silicon_mind / models.py
parzivalprime
Initial commit of SiliconMind OpenEnv environment
b3f3ef9
Raw History Blame Contribute Delete
18.9 kB
"""SiliconMind β€” Pydantic Models for the OpenEnv Memory Subsystem Intelligence Gym.
All models inherit from openenv.core.env_server base classes to ensure
full OpenEnv spec compliance. Every field is typed and documented so the
LLM agent (and human reviewers) can reason about the observation space.
Architecture note:
Action β†’ what the agent sends
Observation β†’ what the agent receives (includes reward)
State β†’ internal episode state (for /state endpoint)
"""
from __future__ import annotations
from enum import Enum
from typing import Any, Dict, List, Optional
from pydantic import BaseModel, Field
# ---------------------------------------------------------------------------
# OpenEnv base classes β€” same import path used by CasualOps (proven pattern)
# ---------------------------------------------------------------------------
from openenv.core.env_server import (
Action as OEAction,
Observation as OEObservation,
State as OEState,
)
# ╔══════════════════════════════════════════════════════════════════════════╗
# β•‘ ENUMS β•‘
# β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
class ActionType(str, Enum):
"""The five control levers available to the agent.
Easy tasks expose only PREFETCH / NO_PREFETCH.
Medium adds SET_AGGRESSIVENESS.
Hard/Extreme unlock THROTTLE_BANDWIDTH and PARTITION_CACHE.
"""
PREFETCH = "prefetch"
NO_PREFETCH = "no_prefetch"
SET_AGGRESSIVENESS = "set_aggressiveness"
THROTTLE_BANDWIDTH = "throttle_bandwidth"
PARTITION_CACHE = "partition_cache"
class PrefetchOutcome(str, Enum):
"""Pythia-inspired 9-level classification for every prefetch decision.
Reference: Pythia (MICRO '21) β€” Bera et al.
Extensions: POLLUTION and CORRECT_RESTRAINT are SiliconMind originals.
"""
# Positive outcomes
ACCURATE_TIMELY = "RAT" # Prefetch was used AND arrived before demand
ACCURATE_LATE = "RAL" # Prefetch was used BUT arrived after demand started
CORRECT_RESTRAINT = "RESTRAINT" # Agent correctly chose NO_PREFETCH on unpredictable
# Neutral / mild negative
REDUNDANT = "REDUNDANT" # Prefetched a line already in cache
NO_PREFETCH_LOW_BW = "RNP_L" # Did not prefetch, bandwidth was available (missed opportunity)
NO_PREFETCH_HIGH_BW = "RNP_H" # Did not prefetch, bandwidth was congested (acceptable)
# Negative outcomes
INACCURATE_LOW_BW = "RIN_L" # Wrong prefetch, bandwidth was available
INACCURATE_HIGH_BW = "RIN_H" # Wrong prefetch, bandwidth was congested (worse)
POLLUTION = "POLLUTION" # Prefetch evicted a useful line from cache
class CacheLevel(str, Enum):
"""Where a demand access resolved in the cache hierarchy."""
L1_HIT = "L1_HIT"
L2_HIT = "L2_HIT"
LLC_HIT = "LLC_HIT"
MISS = "MISS"
class BandwidthPressure(str, Enum):
"""Qualitative bandwidth state for LLM-friendly observation."""
LOW = "low" # utilization < 50%
MODERATE = "moderate" # 50% - 70%
HIGH = "high" # 70% - 90%
CRITICAL = "critical" # > 90%
class MSHRRisk(str, Enum):
"""MSHR stall risk level."""
NONE = "none" # < 50% utilization
APPROACHING = "approaching" # 50% - 80%
STALLING = "stalling" # > 80% or actual stall
class SLAStatus(str, Enum):
"""Per-workload SLA compliance status."""
MET = "met"
AT_RISK = "at_risk"
VIOLATED = "violated"
# ╔══════════════════════════════════════════════════════════════════════════╗
# β•‘ REWARD MODELS β•‘
# β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
# Pythia-inspired reward values (raw, before normalization)
REWARD_VALUES: Dict[PrefetchOutcome, float] = {
PrefetchOutcome.ACCURATE_TIMELY: +20.0,
PrefetchOutcome.ACCURATE_LATE: +12.0,
PrefetchOutcome.CORRECT_RESTRAINT: +8.0,
PrefetchOutcome.REDUNDANT: -2.0,
PrefetchOutcome.NO_PREFETCH_LOW_BW: -4.0,
PrefetchOutcome.NO_PREFETCH_HIGH_BW: -2.0,
PrefetchOutcome.INACCURATE_LOW_BW: -8.0,
PrefetchOutcome.INACCURATE_HIGH_BW: -14.0,
PrefetchOutcome.POLLUTION: -18.0,
}
# For normalization to [0, 1]
_REWARD_MIN = min(REWARD_VALUES.values()) # -18
_REWARD_MAX = max(REWARD_VALUES.values()) # +20
def normalize_reward(raw: float) -> float:
"""Map raw Pythia-scale reward to [0.001, 0.999] for OpenEnv compliance."""
if _REWARD_MAX == _REWARD_MIN:
return 0.5
normalized = (raw - _REWARD_MIN) / (_REWARD_MAX - _REWARD_MIN)
return round(max(0.001, min(0.999, normalized)), 3)
class RewardComponents(BaseModel):
"""Decomposed per-step reward with 6 named components.
All components are in [0.0, 0.25] so they sum to at most 1.0.
The component weights change per-task (defined in task config).
"""
accuracy: float = Field(default=0.0, ge=0.0, le=0.25,
description="Prefetch prediction accuracy")
coverage: float = Field(default=0.0, ge=0.0, le=0.20,
description="Miss elimination rate")
pollution: float = Field(default=0.0, ge=0.0, le=0.20,
description="Cache pollution control")
bandwidth: float = Field(default=0.0, ge=0.0, le=0.15,
description="Memory bus efficiency")
timeliness: float = Field(default=0.0, ge=0.0, le=0.10,
description="Prefetch arrived before demand")
restraint: float = Field(default=0.0, ge=0.0, le=0.10,
description="Correct NO_PREFETCH decisions")
@property
def total(self) -> float:
"""Sum of all components, clamped to [0, 1]."""
return min(1.0, (
self.accuracy + self.coverage + self.pollution
+ self.bandwidth + self.timeliness + self.restraint
))
class Reward(BaseModel):
"""Per-step reward returned to the agent.
Contains the total normalized scalar, the component breakdown,
the Pythia classification, and a human-readable explanation.
"""
total: float = Field(default=0.0, ge=0.0, le=1.0,
description="Normalized scalar reward [0, 1]")
components: RewardComponents = Field(default_factory=RewardComponents)
outcome: str = Field(default="",
description="Pythia classification (RAT/RAL/RIN_L/...)")
explanation: str = Field(default="",
description="Human-readable reward explanation")
# ╔══════════════════════════════════════════════════════════════════════════╗
# β•‘ OBSERVATION SUB-MODELS β•‘
# β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
class PatternAnalysis(BaseModel):
"""Environment-computed pattern detection shared with the agent.
This is the key LLM-friendly feature: instead of making the LLM
figure out patterns from raw hex, we tell it what we detected.
"""
detected_pattern: str = Field(
default="unknown",
description="Identified pattern: 'stride-1', 'stride-4', 'random', 'unknown'")
confidence: float = Field(
default=0.0, ge=0.0, le=1.0,
description="How confident the detector is (drops on phase change)")
pattern_age: int = Field(
default=0, ge=0,
description="Steps since this pattern was first detected")
previous_pattern: str = Field(
default="",
description="What pattern was active before current one")
previous_confidence: float = Field(
default=0.0, ge=0.0, le=1.0,
description="Confidence of the previous pattern")
class CacheStats(BaseModel):
"""Aggregate cache performance counters exposed to the agent."""
hit_rate: float = Field(default=0.0, ge=0.0, le=1.0)
l1_hit_rate: float = Field(default=0.0, ge=0.0, le=1.0)
l2_hit_rate: float = Field(default=0.0, ge=0.0, le=1.0)
llc_hit_rate: float = Field(default=0.0, ge=0.0, le=1.0)
total_hits: int = Field(default=0, ge=0)
total_misses: int = Field(default=0, ge=0)
total_prefetches_issued: int = Field(default=0, ge=0)
total_prefetches_useful: int = Field(default=0, ge=0)
total_prefetches_wasted: int = Field(default=0, ge=0)
total_pollution_evictions: int = Field(default=0, ge=0)
class BandwidthState(BaseModel):
"""Memory bus state for bandwidth-aware decision making."""
utilization: float = Field(default=0.0, ge=0.0, le=1.0,
description="Current bandwidth utilization [0, 1]")
pressure: BandwidthPressure = Field(
default=BandwidthPressure.LOW,
description="Qualitative pressure level")
outstanding_requests: int = Field(default=0, ge=0)
dropped_requests: int = Field(default=0, ge=0,
description="Prefetches dropped due to congestion")
class MSHRState(BaseModel):
"""Miss Status Holding Register state."""
utilization: float = Field(default=0.0, ge=0.0, le=1.0)
stall_risk: MSHRRisk = Field(default=MSHRRisk.NONE)
total_stalls: int = Field(default=0, ge=0,
description="Pipeline stalls caused by full MSHR")
demand_blocked: int = Field(default=0, ge=0,
description="Demand requests blocked by prefetch MSHR usage")
# ╔══════════════════════════════════════════════════════════════════════════╗
# β•‘ ACTION MODEL β•‘
# β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
class SiliconMindAction(OEAction):
"""Agent β†’ Environment: the prefetch decision.
Target format varies by action type:
PREFETCH β†’ "1,2,4" (comma-sep cache-line offsets)
NO_PREFETCH β†’ "skip"
SET_AGGRESSIVENESS β†’ "1" | "2" | "3" | "4"
THROTTLE_BANDWIDTH β†’ "0.6" (max utilization target)
PARTITION_CACHE β†’ "web:6,db:6,video:4" (LLC way allocation)
"""
type: ActionType = Field(
...,
description="Which control lever to use")
target: str = Field(
...,
description="Action parameter (format depends on type)")
detail: str = Field(
default="",
description="Agent's reasoning (optional, for interpretability)")
# ╔══════════════════════════════════════════════════════════════════════════╗
# β•‘ OBSERVATION MODEL β•‘
# β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
class SiliconMindObservation(OEObservation):
"""Environment β†’ Agent: everything the LLM sees each step.
The `narrative` field is the #1 innovation: a 2-3 sentence natural
language summary designed for LLM reasoning. All other fields provide
structured data for precision.
"""
# ── LLM-OPTIMIZED NARRATIVE ──────────────────────────────────────────
narrative: str = Field(
default="",
description="2-3 sentence natural language summary of current state")
# ── CURRENT MEMORY ACCESS ────────────────────────────────────────────
step_number: int = Field(default=0, ge=0)
steps_remaining: int = Field(default=0, ge=0)
current_pc: str = Field(
default="0x0",
description="Program counter (hex string)")
current_address: str = Field(
default="0x0",
description="Memory address being accessed (hex string)")
current_cache_result: CacheLevel = Field(
default=CacheLevel.MISS,
description="Where this access resolved")
is_write: bool = Field(default=False)
current_workload: str = Field(
default="default",
description="Which workload generated this access")
current_phase: str = Field(
default="unknown",
description="Current phase within the workload (e.g., 'forward_pass')")
# ── PATTERN CONTEXT ──────────────────────────────────────────────────
recent_deltas: List[int] = Field(
default_factory=list,
description="Last 8 address deltas in cache-line units")
recent_pcs: List[str] = Field(
default_factory=list,
description="Last 8 program counters (hex)")
recent_cache_results: List[str] = Field(
default_factory=list,
description="Last 8 cache results")
pattern_analysis: PatternAnalysis = Field(
default_factory=PatternAnalysis)
# ── PERFORMANCE FEEDBACK ─────────────────────────────────────────────
last_action_outcome: str = Field(
default="",
description="Pythia classification of last action (RAT/WASTED/...)")
last_action_explanation: str = Field(
default="",
description="Why the last action got its outcome")
prefetch_accuracy_recent: float = Field(
default=0.0, ge=0.0, le=1.0,
description="Accuracy over last 10 prefetches")
prefetch_accuracy_total: float = Field(
default=0.0, ge=0.0, le=1.0,
description="Accuracy over entire episode")
# ── SYSTEM STATE ─────────────────────────────────────────────────────
cache_stats: CacheStats = Field(default_factory=CacheStats)
bandwidth: BandwidthState = Field(default_factory=BandwidthState)
mshr: MSHRState = Field(default_factory=MSHRState)
pollution_rate: float = Field(
default=0.0, ge=0.0, le=1.0,
description="pollution_evictions / total_prefetches")
# ── MULTI-TENANT (Tasks 3-4) ─────────────────────────────────────────
active_workloads: List[str] = Field(default_factory=list)
workload_sla_status: Dict[str, str] = Field(
default_factory=dict,
description="workload_id β†’ 'met'|'at_risk'|'violated'")
llc_partition: Dict[str, int] = Field(
default_factory=dict,
description="Current LLC way allocation per workload")
# ── AVAILABLE ACTIONS ────────────────────────────────────────────────
available_actions: List[str] = Field(
default_factory=list,
description="Which ActionTypes are available in this task")
action_hint: str = Field(
default="",
description="Environment hint (e.g., 'Consider reducing aggressiveness')")
# ── EPISODE METADATA ─────────────────────────────────────────────────
task_id: str = Field(default="")
task_description: str = Field(default="")
done: bool = Field(default=False)
reward: float = Field(default=0.0,
description="Normalized scalar reward [0, 1]")
reward_detail: Reward = Field(default_factory=Reward,
description="Rich reward breakdown (outcome, components, explanation)")
info: Dict[str, Any] = Field(
default_factory=dict,
description="Extra data: forensics, baseline comparison, etc.")
# ╔══════════════════════════════════════════════════════════════════════════╗
# β•‘ STATE MODEL β•‘
# β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
class SiliconMindState(OEState):
"""Internal episode state returned by the /state endpoint.
This is NOT exposed to the agent during normal play β€” it is used
by the OpenEnv framework and for debugging.
"""
task_id: str = Field(default="")
step_number: int = Field(default=0, ge=0)
max_steps: int = Field(default=0, ge=0)
done: bool = Field(default=False)
total_reward: float = Field(default=0.0)
seed: int = Field(default=0)
# Aggregate counters
cache_stats: CacheStats = Field(default_factory=CacheStats)
bandwidth: BandwidthState = Field(default_factory=BandwidthState)
mshr: MSHRState = Field(default_factory=MSHRState)
# Agent config state
prefetch_aggressiveness: int = Field(default=2, ge=1, le=4)
bandwidth_throttle: float = Field(default=1.0, ge=0.0, le=1.0)
llc_partition: Dict[str, int] = Field(default_factory=dict)
# Workload tracking
current_workload: str = Field(default="")
current_phase: str = Field(default="")