Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

L05: The Quantum Software Stack (SDKs, Simulators & Cloud Backends)

Learning Objectives

  • Map the software stack: algorithm \to circuit IR \to transpiler \to pulse/backend.

  • Write, simulate, and run the same circuit in Qiskit, Cirq, and PennyLane.

  • Understand transpilation: basis gates, connectivity, and optimization levels.

  • Choose between statevector, density-matrix, and shot-based simulation.

The Stack, Top to Bottom

  • Algorithm layer: QFT, Grover, VQE (Lectures L08-L12).

  • Circuit layer: gates on abstract qubits (an intermediate representation).

  • Transpiler: rewrite to hardware basis gates + qubit connectivity (SWAP insertion).

  • Pulse/control layer: microwave/laser pulses implementing each gate (L07).

  • Backend: simulator or QPU, returning shots (bitstring counts).

Eureka! A quantum program is a compiled artifact: what runs on hardware is rarely the circuit you drew. Always inspect the transpiled circuit depth.

The Big Five SDKs

  • Qiskit (IBM): largest ecosystem; transpiler, noise models, IBM Quantum cloud.

  • Cirq (Google): explicit device topologies; moment-based scheduling.

  • PennyLane (Xanadu): differentiable programming; best for variational/ML workflows.

  • Braket SDK (AWS): one API across IonQ, Rigetti, IQM hardware.

  • pyQuil (Rigetti): Quil language, quantum-classical hybrid model.

Eureka! Our notebooks are multi-backend by design: set backend in the first cell. Learning the concepts portable across SDKs beats memorizing one API.

Same Bell Pair, Three SDKs


Qiskit                            Cirq
qc = QuantumCircuit(2, 2)         q = cirq.LineQubit.range(2)
qc.h(0); qc.cx(0, 1)              c = cirq.Circuit([cirq.H(q[0]),
qc.measure([0,1], [0,1])              cirq.CNOT(q[0], q[1]),
                                      cirq.measure(*q)])
PennyLane
@qml.qnode(dev)
def bell():
    qml.Hadamard(0); qml.CNOT(wires=[0, 1])
    return qml.counts()

Simulation Modes (and When Each Lies to You)

  • Statevector: exact amplitudes, 2n2^n memory; no shot noise, no decoherence.

  • Shot-based sampler: mimics real readout statistics; use for algorithm testing.

  • Density matrix: 4n4^n memory but supports noise channels (L06 Kraus maps!).

  • Tensor network/stabilizer: scale further for low-entanglement / Clifford circuits.

Eureka! Rule of thumb: debug with statevector, validate with shots + noise model, then burn QPU credits.

Transpilation in One Slide

Hardware exposes a basis gate set (e.g.\ {Rz,X,X,CZ}\{R_z, \sqrt{X}, X, \text{CZ}\}) and a coupling map.

  • Every gate is rewritten into basis gates (Solovay--Kitaev / KAK decompositions, L04).

  • Non-adjacent 2-qubit gates require SWAP chains \Rightarrow depth blow-up.

  • Optimization levels trade compile time for circuit depth; depth \approx error (L06).

Eureka! Circuit depth is the currency of the NISQ era: each layer multiplies in another factor of gate fidelity.

Classical Ecosystem for This Course

  • Python + NumPy/SciPy: state vectors are just arrays; unitaries are matrices.

  • OpenQASM 3: the portable ‘assembly’ of circuits between SDKs.

  • For materials later: openfermion / qiskit-nature / pennylane-qchem map molecules and lattices to qubit Hamiltonians (used in L11-L12).

Hands-on Notebook

New companion notebook: L05_Software_Stack.ipynb (build it from the L01-L04 notebooks: run the same Bell + GHZ circuits across all five backends and compare counts).

Mini-Lab

  • Transpile a 5-qubit GHZ circuit to a linear-connectivity device; count SWAPs and final depth at optimization levels 0-3.

  • Export a circuit to OpenQASM from one SDK and import into another.

  • Compare 1,000-shot histograms: ideal sampler vs. depolarizing noise model.

Takeaways

  • The stack is: algorithm \to IR \to transpiler \to pulses \to shots.

  • SDKs differ in syntax, not physics; concepts are portable.

  • Depth and connectivity, not qubit count, usually decide what is runnable.