The dominant programming abstraction for gate-model quantum computing is the circuit: an ordered set of operations that prepare, transform, entangle, and measure qubits, potentially with classical control. An abstract circuit need not assign physical start times. Scheduling maps its dependencies to hardware timing constraints.
SDKs make this look familiar. That familiarity is useful, but also dangerous. The code a developer writes is only the start of the operational object that eventually runs on hardware.
3.1 Circuit source versus executable circuit
A developer may write a compact circuit. The machine may run a much larger, deeper circuit after decomposition, routing, and basis translation.
View diagram source
flowchart LR
Source[User circuit source] --> IR[Intermediate representation]
IR --> Decompose[Gate decomposition]
Decompose --> Layout[Qubit layout selection]
Layout --> Routing[Routing / SWAP insertion]
Routing --> Optimize[Optimization passes]
Optimize --> Native[Native hardware circuit]
Native --> Pulse[Pulse or control instructions]The output of compilation is the object that must be analyzed for feasibility. The source circuit may be elegant and still operationally poor.
3.2 Circuit depth and execution time
Circuit depth counts sequential operation layers under a chosen counting convention. It is a rough proxy for execution time, not a duration. Gates, delays, reset, measurement, and feed-forward have different timing costs; two circuits with equal depth can take different amounts of time.
Optimize the scheduled circuit using device-specific durations and error estimates. Adding well-designed suppression operations can sometimes improve fidelity despite increasing gate count. Use hardware timing estimates to assess duration.
For many near-term workloads, reducing two-qubit gate count is more valuable than reducing single-qubit gates, because two-qubit gates are often harder to implement with high fidelity.
3.3 SDKs and platform interfaces
Current quantum software stacks commonly expose circuit-building and execution interfaces. IBM’s Qiskit documentation describes primitives as computational building blocks for larger applications, and the broader IBM Quantum documentation includes circuit building, transpilation, error mitigation, execution, and post-processing capabilities. See R9 and R10.
Google’s Cirq documentation describes Cirq as a Python framework for writing, manipulating, optimizing, and running quantum circuits, with abstractions for noisy intermediate-scale hardware. See R11 and R12.
Cloud access platforms such as Amazon Braket and Azure Quantum provide managed ways to build, test, simulate, and run quantum workloads across hardware and simulators. See R13, R14, and R15.
3.4 The hybrid loop
Many useful near-term workflows are hybrid. A classical optimizer proposes parameters, a quantum device estimates a value, the classical optimizer updates parameters, and the loop repeats.
View diagram source
sequenceDiagram
participant O as Classical optimizer
participant C as Circuit generator
participant Q as Quantum backend
participant P as Post-processor
O->>C: propose parameters θ
C->>Q: submit parameterized circuit
Q->>P: return measurement counts
P->>P: estimate cost function
P->>O: return objective value and uncertainty
O->>O: update θThis loop is sensitive to latency, queueing, shot noise, optimizer choice, and barren plateaus. A quantum backend may be fast at individual execution but slow in end-to-end iteration if queueing and compilation are repeated unnecessarily.
3.5 Programming with uncertainty
The classical software habit is to treat functions as deterministic unless marked otherwise. Quantum programs should be treated as stochastic unless proven otherwise.
A good quantum API should make uncertainty explicit:
estimate = run_expectation_value(
circuit=my_circuit,
observable=hamiltonian,
shots=20_000,
backend="selected_backend",
mitigation="measurement_error_mitigation"
)
print(estimate.value)
print(estimate.standard_error)
print(estimate.backend_metadata)The value alone is not enough. The uncertainty and provenance are part of the return type.
3.6 Compilation as an optimization problem
Compilation has several objectives that may conflict:
| Objective | Why it matters | Potential conflict |
|---|---|---|
| Minimize depth | May shorten execution; verify the physical schedule | May increase gate count or use slower gates |
| Minimize two-qubit gates | Reduces dominant error source | May increase depth |
| Use high-fidelity qubits | Improves execution quality | May require more routing |
| Respect topology | Makes circuit executable | May require SWAPs |
| Preserve structure | Helps algorithms and mitigation | May reduce low-level optimization |
The compiler is therefore a policy engine. It encodes assumptions about what matters most for a workload.
View diagram source
flowchart TD
A[Compilation policy] --> B{Optimization priority}
B -->|Depth| C[Compress schedule]
B -->|Two-qubit count| D[Reduce entangling gates]
B -->|Calibration| E[Prefer high-fidelity regions]
B -->|Topology| F[Minimize routing cost]
C --> G[Candidate circuit]
D --> G
E --> G
F --> G
G --> H[Estimate success probability]3.7 Practical metadata schema
A platform should represent a quantum workload as more than source code. A minimal workload schema might look like this:
workload:
name: h2_vqe_trial_017
objective: estimate_ground_state_energy
algorithm_family: VQE
circuit_source: circuits/vqe_ansatz.py
observable_source: hamiltonians/h2.yaml
backend_constraints:
min_qubits: 8
preferred_connectivity: linear_or_better
max_two_qubit_error: 0.01
execution:
shots: 20000
max_queue_delay_minutes: 30
mitigation:
measurement_error: true
zero_noise_extrapolation: false
provenance_required:
save_raw_counts: true
save_calibration_snapshot: true
save_compiled_circuit: trueThe schema makes implicit assumptions visible. That is the first step toward repeatability.
3.8 Failure modes
Failure: confusing source-level simplicity with hardware-level simplicity
A simple-looking high-level circuit may compile into a deep hardware circuit. Always inspect the compiled circuit.
Failure: reusing a compiler policy across workloads
A policy that works for shallow sampling may be poor for expectation estimation or iterative optimization.
Failure: hiding uncertainty from users
APIs that return point estimates without confidence intervals encourage bad decisions.
Failure: ignoring classical overhead
Hybrid algorithms can spend more time in classical orchestration, optimization, and queueing than in quantum execution.
3.9 Operator checklist
Before accepting a quantum program for hardware execution:
- Inspect the post-compilation circuit.
- Record depth, two-qubit count, measurement count, and idle time.
- Confirm backend topology fit.
- Confirm calibration recency.
- Estimate shot requirements.
- Decide which uncertainty metric will be reported.
- Save source, compiled artifact, backend metadata, and raw counts.
3.10 Chapter summary
Quantum programming is circuit construction plus compilation plus statistical interpretation. The executable object is not the source circuit. It is the hardware-native circuit produced under a particular compiler policy and calibration context. A serious platform treats uncertainty and provenance as first-class API outputs.