The compiler is not a translator bolted onto the side of a quantum computer. It is one of the control surfaces of the machine. A hardware-aware compiler can save fidelity, reduce depth, avoid bad couplers, exploit native gates, and shape workloads to calibration reality. A hardware-ignorant compiler can destroy an otherwise good experiment.
Compiler-hardware co-design is the process of making the hardware, calibration system, compiler, scheduler, and user API improve together.
22.1 The compiler as an operating control loop
View diagram source
flowchart TB
UserCircuit[User circuit / program] --> Frontend[Frontend normalization]
Frontend --> Logical[Logical optimization]
Logical --> Target[Target-aware lowering]
Target --> Layout[Layout and routing]
Layout --> Timing[Timing and scheduling]
Timing --> Native[Native executable]
Native --> Execute[QPU execution]
Execute --> Telemetry[Result and telemetry]
Telemetry --> Learn[Compiler learning]
Learn --> Target
Learn --> LogicalThe compiler should not be static. It should learn from calibration, benchmark, and workload telemetry, but changes must be gated because compiler changes can invalidate reproducibility.
22.2 Target contracts
A target contract is the machine-readable description of what a backend can execute and how expensive or risky each choice is.
target_contract:
backend: qpu-alpha
contract_version: 2026.04.18
instruction_set:
- gate: rz
qubits: any
duration_ns: 0
virtual: true
- gate: ecr
qubits: [[0,1], [1,2]]
duration_ns: 533
error_estimate: by_pair
topology:
directed_edges: true
timing_constraints:
alignment: 16_dt
measurement_latency_ns: 850
forbidden_patterns:
- simultaneous_readout_group_conflict
quality_annotations:
- qubit_error
- coupler_error
- readout_errorView diagram source
flowchart LR
Hardware[Hardware constraints] --> Contract[Target contract]
Calibration[Calibration data] --> Contract
Contract --> Compiler[Compiler]
Contract --> Scheduler[Scheduler]
Contract --> Validator[Static validator]
Contract --> Trust[Trust report]Qiskit’s Target abstraction is one concrete example of this concept: it informs the compiler about backend constraints such as supported instructions, properties, and timing information [R45]. A production platform should extend the idea to all execution paths, not only a single SDK.
22.3 Native gates are economic units
A logical circuit is written in convenient gates. A QPU executes native operations. Every decomposition has cost.
View diagram source
flowchart LR
LogicalGate[Logical gate] --> Decompose[Decomposition]
Decompose --> NativeOps[Native operations]
NativeOps --> Error[Accumulated error]
NativeOps --> Duration[Duration]
NativeOps --> Crosstalk[Crosstalk exposure]
Error --> Utility[Useful result probability]
Duration --> Utility
Crosstalk --> UtilityA compiler should optimize for useful result probability, not just gate count.
| Objective | Naive proxy | Better proxy |
|---|---|---|
| small circuit | operation count | expected success probability |
| fast execution | depth | duration under timing constraints |
| low error | average gate error | mapped, time-local, crosstalk-aware error |
| portability | same source circuit | same validated workload intent |
22.4 Layout and routing under drift
Routing decisions are usually treated as graph problems. On real devices they are graph problems with time-varying edge quality.
View diagram source
flowchart TB
Circuit[Logical circuit] --> Candidates[Candidate layouts]
Candidates --> Quality[Apply calibration quality]
Quality --> Crosstalk[Apply crosstalk risk]
Crosstalk --> Duration[Estimate duration]
Duration --> Score[Score layouts]
Score --> Select[Select layout]
Select --> Execute[Execute]
Execute --> Feedback[Observed quality feedback]
Feedback --> QualityThe compiler should answer:
- which qubits are good enough today,
- which couplers should be avoided,
- which parallel operations are unsafe,
- which route minimizes expected failure rather than graph distance,
- when to reject the workload instead of pretending compilation solved it.
22.5 Calibration-aware compilation
Calibration-aware compilation is not “use the latest calibration file.” It is a release discipline.
View diagram source
sequenceDiagram
participant Cal as Calibration service
participant Model as Device model registry
participant Comp as Compiler service
participant Bench as Benchmark gate
participant Sched as Scheduler
Cal->>Model: publish candidate model
Model->>Comp: compile benchmark suite
Comp->>Bench: submit compiled benchmarks
Bench->>Model: pass/fail and quality deltas
alt pass
Model->>Sched: promote model version
else fail
Model->>Cal: reject model and request investigation
endThe compiler should know whether a calibration model is candidate, active, deprecated, or quarantined.
22.6 Dynamic circuits and feedback-aware lowering
Dynamic circuits introduce measurement-conditioned behavior. OpenQASM 3 explicitly supports measurement-based circuits and classical feed-forward, including low-level embedded classical control and higher-level external functions [R26, R27]. That matters operationally because a dynamic circuit is partly a real-time control program.
View diagram source
flowchart LR
Measure[Mid-circuit measurement] --> Latency[Classical decision latency]
Latency --> Conditional[Conditional operation]
Conditional --> Coherence[Remaining coherence budget]
Coherence --> Feasible{Feasible?}
Feasible -- yes --> Lower[Lower to target]
Feasible -- no --> Reject[Reject or transform]Compiler checks for dynamic workloads:
| Check | Why it matters |
|---|---|
| conditional support | not every target supports all dynamic constructs |
| decision latency | feedback must fit within coherence and control timing budgets |
| branch structure | branch explosion can break runtime predictability |
| measurement reuse | classical register semantics must be exact |
| result provenance | branch frequencies become part of the result evidence |
22.7 Compiler releases
A compiler release can change scientific results. Treat it like a production release.
View diagram source
flowchart TB
Change[Compiler change] --> Unit[Unit tests]
Unit --> Golden[Golden circuit compile tests]
Golden --> Sim[Simulator equivalence tests]
Sim --> Hardware[Hardware canary tests]
Hardware --> Compare[Compare against previous release]
Compare --> Decision{Promote?}
Decision -- yes --> Release[Promote compiler]
Decision -- no --> Hold[Hold and investigate]Release artifacts:
compiler_release:
version: 2026.04.18
source_commit: string
supported_targets:
- qpu-alpha@target-2026.04.18
optimization_passes:
- name: layout_quality_v3
- name: crosstalk_guard_v1
validation:
golden_circuits: passed
hardware_canaries: passed
regression_thresholds: passed
reproducibility:
deterministic_seed_policy: string22.8 Compiler observability
Compilation failures are user education events. Compilation successes are not necessarily safe.
View diagram source
flowchart LR
Compile[Compile request] --> Metrics[Compiler metrics]
Metrics --> Depth[Depth / duration]
Metrics --> Routing[Routing overhead]
Metrics --> Quality[Expected quality]
Metrics --> Rejects[Reject reasons]
Metrics --> Drift[Drift sensitivity]Track:
| Metric | Diagnostic use |
|---|---|
| routing overhead | reveals topology mismatch |
| two-qubit operation inflation | reveals poor decomposition or layout |
| expected success probability | supports admission control |
| rejected workload class | guides user education and SDK improvements |
| compiler runtime | affects interactive workflows |
| target-model age | detects stale calibration dependencies |
22.9 Chapter rule
The compiler is a reliability system. Its job is not to make every user program executable. Its job is to produce executable workloads whose evidence can be trusted, and to reject the rest with a repair path.