simquantum-tuning-lab / INTEGRATION.md
100enigma's picture
SimQuantum — AMD Developer Hackathon
da98415
|
Raw
History Blame Contribute Delete
15.5 kB
## Phase 0/1/2 Integration Guide
This document explains how the three phases of the agentic quantum dot tuning system integrate together.
---
## Architecture Overview
```
┌─────────────────────────────────────────────────────────────────────┐
│ EXECUTIVE AGENT (Phase 2) │
│ Main orchestration loop (Fig. 2) │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
┌────────────────┐ ┌────────────┐ ┌─────────────┐
│ PERCEPTION │ │ PLANNING │ │ HARDWARE │
│ (Phase 1) │ │ (Phase 2) │ │ (Phase 0) │
└────────────────┘ └────────────┘ └─────────────┘
│ │ │
│ - DQCGatekeeper │ - BeliefUpdater │ - DeviceAdapter
│ - InspectionAgent │ - ActiveSensingPolicy│ - SafetyCritic
│ - EnsembleCNN │ - MultiResBO │ - HITLManager
│ - OOD Detector │ - StateMachine │ - GovernanceLogger
│ │ - TranslationAgent │
└───────────────────┴──────────────────────┴─────────────┘
┌─────────────────────┐
│ EXPERIMENT STATE │
│ (Phase 0) │
│ Single source of │
│ truth │
└─────────────────────┘
```
---
## Data Flow: One Complete Loop
### 1. Active Sensing (Phase 2 Planning)
**ActiveSensingPolicy.select()** examines `ExperimentState.belief` and proposes a measurement:
```python
plan = sensing_policy.select(state.belief, v1_range, v2_range)
# → MeasurementPlan(modality=COARSE_2D, v1_range=(-0.5, 0.5), ...)
```
### 2. Translation (Phase 2 Agent)
**TranslationAgent.execute()** converts the plan to a DeviceAdapter call:
```python
result = translator.execute(plan)
measurement = result.measurement # Measurement from CIMSimulatorAdapter
state.add_measurement(measurement)
```
### 3. Data Quality Check (Phase 1 Perception)
**DQCGatekeeper.assess()** runs physics-based quality checks:
```python
dqc_result = dqc.assess(measurement)
state.add_dqc_result(dqc_result)
if dqc_result.quality == DQCQuality.LOW:
# STOP — do not pass to InspectionAgent
return failure_result
```
### 4. Classification (Phase 1 Perception)
**InspectionAgent.inspect()** runs the full perception pipeline:
```python
if measurement.is_2d:
classification, ood_result = inspector.inspect(measurement, dqc_result)
state.add_classification(classification)
state.add_ood_result(ood_result)
```
InspectionAgent internally:
- Log-preprocesses the array
- Runs EnsembleCNN (5-model ensemble)
- Extracts physics features (FFT peak ratio, diagonal strength)
- Checks for physics override
- Runs OOD detector on penultimate features
- Generates structured NL summary
### 5. Belief Update (Phase 2 Planning)
**BeliefUpdater** updates the POMDP belief using CIM observation model:
```python
belief_updater.update_from_2d(measurement, classification)
# Updates state.belief.charge_probs in-place
```
For line scans (bypass InspectionAgent per blueprint §5.1):
```python
if measurement.modality == MeasurementModality.LINE_SCAN:
belief_updater.update_from_1d(measurement)
```
### 6. Bayesian Optimization (Phase 2 Planning)
**MultiResBO.propose()** uses GP with CIM-informed priors:
```python
bo.update(state.bo_history)
proposal = bo.propose(current=state.current_voltage, l1_max=0.10)
# → ActionProposal(delta_v=VoltagePoint(vg1=0.05, vg2=0.02), ...)
```
### 7. Safety Critic (Phase 0 Hardware)
**SafetyCritic** enforces hard constraints:
```python
proposal = safety_critic.clip(proposal, state.current_voltage)
verdict = safety_critic.verify(state.current_voltage, proposal)
if not verdict.all_passed:
state.record_safety_violation()
return failure_result
```
### 8. Risk Assessment + HITL (Phase 0 Governance)
**HITLManager.compute_risk_score()** aggregates 12 trigger conditions:
```python
risk = hitl_manager.compute_risk_score(
proposal=proposal,
safety_verdict=verdict,
dqc_flag=dqc_result.quality.value,
ood_score=ood_result.score,
ensemble_disagreement=classification.ensemble_disagreement,
consecutive_backtracks=state.consecutive_backtracks,
step=state.step + 1,
)
if risk >= 0.70:
event = hitl_manager.queue_request(...)
event = hitl_manager.await_decision(event) # BLOCKS
state.add_hitl_event(event)
```
### 9. Execute Move (Phase 2 Agent + Phase 0 Hardware)
If all checks pass:
```python
translator.execute_voltage_move(
vg1=state.current_voltage.vg1 + safe_dv.vg1,
vg2=state.current_voltage.vg2 + safe_dv.vg2,
)
state.apply_move(safe_dv)
```
### 10. Governance (Phase 0)
**GovernanceLogger** records every action:
```python
decision = Decision(
run_id=state.run_id,
step=state.step,
intent="voltage_move",
stage=state.stage,
observation_summary={...},
action_summary={...},
rationale="...",
)
state.add_decision(decision)
governance_logger.log(decision)
```
### 11. State Machine (Phase 2 Planning)
**StateMachine.process_result()** manages stage transitions:
```python
result = navigation_result(target_reached=True, belief_confidence=0.85)
new_stage, rationale, hitl_triggered = state_machine.process_result(result)
if new_stage != state.stage:
state.advance_stage(new_stage)
```
Backtracking on failure:
```python
if retries_exhausted:
event = BacktrackEvent(from_stage=NAVIGATION, to_stage=CHARGE_ID, ...)
state.record_backtrack(event)
```
---
## Key Integration Points
### BeliefState (Phase 0 stub → Phase 2 implementation)
**Phase 0 defined the interface:**
```python
@dataclass
class BeliefState:
charge_probs: Dict[tuple, float] = field(default_factory=dict)
uncertainty_map: Optional[Any] = None
device_params: Dict[str, float] = field(default_factory=lambda: {...})
def entropy(self) -> float: ...
def most_likely_state(self) -> Optional[tuple]: ...
def initialise_uniform(self, charge_states: Optional[List[tuple]] = None) -> None: ...
```
**Phase 2 implemented the particle filter:**
```python
class BeliefUpdater:
def __init__(self, belief: BeliefState, ...):
self.belief = belief # Operates on Phase 0 stub directly
self._particles = _ParticleSet(...) # Internal engine
def update_from_2d(self, measurement, classification):
# Updates self.belief.charge_probs in-place
self.belief.charge_probs = self._particles.to_charge_probs()
```
### Classification Flow (Phase 1 → Phase 2)
**InspectionAgent output:**
```python
classification = Classification(
measurement_id=...,
label=ChargeLabel.DOUBLE_DOT,
confidence=0.85,
ensemble_disagreement=0.12,
features={...},
physics_override=False,
nl_summary="...",
)
```
**Used by multiple Phase 2 components:**
- **BeliefUpdater:** Uses `label` and `confidence` to boost particle weights; `physics_override=True` → inflates uncertainty
- **MultiResBO:** Creates BOPoints from classifications; `confidence` becomes the reward signal
- **StateMachine:** Uses `confidence` to determine if stage success threshold is met
- **HITLManager:** Uses `ensemble_disagreement` in risk score computation
### Safety Integration (Phase 0 → Phase 2)
**ExecutiveAgent always calls SafetyCritic before any move:**
```python
proposal = bo.propose(...) # Phase 2 proposes
proposal = safety_critic.clip(proposal, current) # Phase 0 clips
verdict = safety_critic.verify(current, proposal) # Phase 0 verifies
if verdict.all_passed:
translator.execute_voltage_move(...) # Phase 2 executes
state.apply_move(proposal.safe_delta_v) # Phase 0 records
else:
state.record_safety_violation()
```
No component can bypass SafetyCritic — it's architecturally enforced.
### HITL Integration (Phase 0 → Phase 2)
**HITLManager is called at two points:**
1. **Risk score computation (every voltage move):**
```python
risk = hitl_manager.compute_risk_score(...)
if risk >= 0.70:
event = hitl_manager.queue_request(...)
event = hitl_manager.await_decision(event) # BLOCKS
```
2. **State machine backtracking (condition 8):**
```python
if state.consecutive_backtracks >= 2:
# StateMachine returns hitl_triggered=True
# ExecutiveAgent queues HITL event
```
**No timeout auto-approval** — agent blocks until human decides.
---
## Running the Integrated System
### Without Trained Models (CI/Development)
```bash
# Uses InspectionAgent in stub mode (untrained ensemble, no OOD)
pytest tests/test_integration_phase012.py -v
# Run benchmark without checkpoints
python experiments/benchmark_phase2.py --fast --skip-missing-checkpoints
```
### With Trained Models (Full System)
```bash
# 1. Train Phase 1 models
python experiments/train_phase1.py --out experiments/checkpoints/phase1
# 2. Run benchmark
python experiments/benchmark_phase2.py --n-trials 100 --budget 2048
```
### Manual Inspection
```python
from qdot.core.state import ExperimentState
from qdot.simulator.cim import CIMSimulatorAdapter
from qdot.agent.executive import ExecutiveAgent
from qdot.perception.inspector import InspectionAgent
from qdot.core.hitl import HITLManager, HITLOutcome
# Setup
state = ExperimentState.new(device_id="manual_test")
adapter = CIMSimulatorAdapter(device_id="manual_test", seed=42)
inspector = InspectionAgent(ensemble=None, ood_detector=None) # Or load trained
hitl = HITLManager()
hitl.set_test_mode(auto_outcome=HITLOutcome.APPROVED) # No blocking for demo
# Create agent
agent = ExecutiveAgent(
state=state,
adapter=adapter,
inspection_agent=inspector,
hitl_manager=hitl,
max_steps=50,
measurement_budget=2048,
)
# Run
summary = agent.run()
print(f"Success: {summary['success']}")
print(f"Measurements: {summary['total_measurements']}")
print(f"Reduction: {summary['measurement_reduction']:.1%}")
```
---
## File Organization
```
qdot/
├── core/ # Phase 0 — Foundation
│ ├── types.py # All canonical types
│ ├── state.py # ExperimentState + BeliefState stub
│ ├── governance.py # GovernanceLogger
│ └── hitl.py # HITLManager
├── hardware/ # Phase 0 — Device interface
│ ├── adapter.py # DeviceAdapter ABC
│ └── safety.py # SafetyCritic
├── simulator/ # Phase 0 — CIM simulator
│ └── cim.py # ConstantInteractionDevice + CIMSimulatorAdapter
├── perception/ # Phase 1 — Perception pipeline
│ ├── dqc.py # DQCGatekeeper
│ ├── inspector.py # InspectionAgent
│ ├── classifier.py # EnsembleCNN
│ ├── features.py # Physics validators
│ ├── ood.py # MahalanobisOOD
│ └── dataset.py # CIMDataset for training
├── planning/ # Phase 2 — POMDP + BO
│ ├── belief.py # BeliefUpdater + CIMObservationModel
│ ├── sensing.py # ActiveSensingPolicy
│ ├── bayesian_opt.py # MultiResBO + GaussianProcess
│ └── state_machine.py # StateMachine (5 stages)
└── agent/ # Phase 2 — Main loop
├── executive.py # ExecutiveAgent (orchestrator)
└── translator.py # TranslationAgent (NL → API)
```
---
## Testing Strategy
### Unit Tests (per module)
- `tests/test_types.py` — Phase 0 types
- `tests/test_state.py` — ExperimentState, BeliefState stub
- `tests/test_safety.py` — SafetyCritic + fuzz test (5000 iterations)
- `tests/test_simulator.py` — CIM physics
- `tests/test_perception.py` — DQC, CNN, OOD, InspectionAgent
- `tests/test_planning.py` — Belief, sensing, BO, state machine
- `tests/test_agent.py` — TranslationAgent, ExecutiveAgent
### Integration Tests
- `tests/test_integration_phase012.py` — Full pipeline smoke tests
### Benchmarks
- `experiments/train_phase1.py --fast` — Phase 1 smoke test (CI)
- `experiments/benchmark_phase2.py --fast` — Phase 2 quick eval (10 trials)
- `experiments/benchmark_phase2.py --n-trials 100` — Full benchmark
---
## Next Steps (Phase 3)
1. **LLM Integration (IBM Granite 3-8B-Instruct)**
- Replace template rationales with LLM calls
- ONE call per stage transition + ONE per HITL trigger
- Budget: ~200 tokens per call
2. **Disorder Learning**
- OOD flag → fit device-specific disorder map
- Inject into CIMObservationModel.device
- Close sim-to-real gap
3. **Meta-Learning**
- Learn CIM parameter priors from device family
- Fast adaptation to new devices
4. **Hardware Validation**
- Integrate real Si/SiGe adapter
- Run on QFlow hardware testbed
- Validate ≥50% reduction on real devices
---
## Troubleshooting
### "No tests collected" in test_agent.py
**Cause:** File didn't exist or pytest can't find it.
**Fix:** Ensure `tests/test_agent.py` is in the repo root `tests/` directory.
### "ModuleNotFoundError: No module named 'qdot.planning'"
**Cause:** Phase 2 modules not in Python path.
**Fix:** Run `pip install -e .` from repo root to install in editable mode.
### InspectionAgent predictions are random
**Cause:** Running without trained checkpoints (ensemble=None).
**Fix:** Either (a) train models with `experiments/train_phase1.py`, or (b) use `--skip-missing-checkpoints` flag for testing without models.
### HITL blocks forever
**Cause:** HITLManager not in test mode.
**Fix:** Call `hitl_manager.set_test_mode(auto_outcome=HITLOutcome.APPROVED)` for non-blocking testing.
### SafetyCritic rejects all moves
**Cause:** Voltage bounds or l1_max cap too tight.
**Fix:** Check `state.voltage_bounds` and `state.step_caps["l1_max"]` are reasonable for your device.
---
**Phase 0/1/2 integration complete.** All components tested individually and end-to-end. Ready for Phase 3.