dr.David
Rhodus
The bookREFERENCE COLLECTION Contents
Chapter 35 / 232

Programming Model

Operating Quantum Computers · 4 min read

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.

DIAGRAM
Diagram loads as you read
3.1 Circuit source versus executable circuit · Figure 1
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.

DIAGRAM
Diagram loads as you read
3.4 The hybrid loop · Figure 2
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:

Illustrative listing · text
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.

DIAGRAM
Diagram loads as you read
3.6 Compilation as an optimization problem · Figure 3
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:

Illustrative listing · yaml
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: true

The 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.