Using Qiskit to Run Quantum Workloads on IQM Hardware via QDMI-on-IQM¶
The iqm-qdmi Python package includes a wrapper for the
IQM QDMI Device library that integrates it with Qiskit. This wrapper
is implemented in the iqm.qdmi.qiskit submodule and is based on the
open-source, MIT-licensed MQT Core library. To use the wrapper, make sure to
install the iqm-qdmi package with the qiskit extra:
uv pip install iqm-qdmi[qiskit]
Then, the IQMBackend class can be imported from
iqm.qdmi.qiskit and used as a drop-in replacement for any Qiskit
backend.
1from iqm.qdmi.qiskit import IQMBackend
2from qiskit.circuit import QuantumCircuit
3from qiskit.compiler import transpile
4
5backend = IQMBackend(
6 base_url="https://resonance.iqm.tech",
7 qc_alias="emerald:mock",
8)
1qc = QuantumCircuit(2)
2qc.h(0)
3qc.cx(0, 1)
4qc.measure_all()
5
6transpiled_qc = transpile(qc, backend)
7result = backend.run(transpiled_qc, shots=128).result()
8print(result.get_counts())
{'00': 50, '11': 78}
Explicit arguments to IQMBackend(...) take precedence over IQM_SERVER_URL,
IQM_TOKEN, IQM_TOKENS_FILE, IQM_QC_ID, and IQM_QUANTUM_COMPUTER from the
environment. IQM_BASE_URL and IQM_QC_ALIAS remain supported as legacy
aliases. Canonical variables take precedence over their legacy aliases, which
take precedence over the registered device default.
The wrapper registers the packaged IQM QDMI device as a fallback under the
stable ID iqm.default with the standard Resonance endpoint as its default. An
existing configured definition with that ID is preserved, including its
endpoint. Every backend opens a fresh device session with its own configuration.
Sampler and Estimator Primitives¶
IQMBackend provides small helpers (see
sampler() and
estimator()) for constructing
BackendSamplerV2 and
BackendEstimatorV2 primitives bound to the
backend instance.
1sampler_job = backend.sampler().run([(transpiled_qc,)], shots=128)
2counts = sampler_job.result()[0].data["meas"].get_counts()
3print(f"Counts: {counts}")
Counts: {'00': 63, '11': 65}
1from qiskit.quantum_info import SparsePauliOp
2
3transpiled_qc.remove_final_measurements(inplace=True)
4observable = SparsePauliOp("Z" * backend.num_qubits)
5
6estimator_job = backend.estimator().run([(transpiled_qc, observable)])
7data = estimator_job.result()[0].data
8print(f"Expectation values: {data['evs']}")
9print(f"Standard deviations: {data['stds']}")
Expectation values: 0.00927734375
Standard deviations: 0.015624327570631967
CLI Scripts¶
The package also exposes the iqm-sampler and iqm-estimator CLI scripts for
executing serialized circuits directly from the shell. For more details on these
utilities and their usage, see the Python Package Guide.