IQMBackend#
Module: iqm.qrisp_iqm.backends
- class iqm.qrisp_iqm.backends.IQMBackend(server_url: str | None = None, *, device_instance: str | None = None, transpiler: Callable[[QuantumCircuit], QuantumCircuit] | None = None, calibration_set_id: UUID | str | None = None, use_metrics: bool = False, pass_manager: PassManager | None = None, use_timeslot: bool = False, compilation_options: CircuitCompilationOptions | None = None, compiler: Compiler | None = None, **user_auth_args)#
Bases:
BackendQrisp backend for executing circuits on IQM quantum hardware.
After transpilation,
run_async()automatically detects whether any of the circuits containsIQMPulseOperationinstructions, and routes the job to the appropriate submission path:No pulse ops → submitted as a gate-level
IQMCircuitJob.Has pulse ops → compiled locally down to pulse level, and submitted as a
IQMPulseJob.
The
server_urlanddevice_instanceparameters can alternatively be provided as the environment variablesIQM_SERVER_URLandIQM_QUANTUM_COMPUTER. If the server requires user authentication, you can provide it either using environment variables or as keyword arguments. The user authentication kwargs are passed through toIQMClientas is, and are documented there.- Parameters:
server_url (str | None) – URL for connecting to a quantum computer. If None, use environment variable
IQM_SERVER_URL.device_instance (str | None) – IQM quantum computer identifier (e.g.,
"garnet"). If None, use environment variableIQM_QUANTUM_COMPUTER. If it is not defined, use the default quantum computer on the server.user_auth_args – User authentication information, e.g. an API token.
transpiler (Callable[[QuantumCircuit], QuantumCircuit] | None) –
Deprecated since version Use:
pass_managerinstead.Transforms quantum circuits for hardware compatibility. If provided, a
DeprecationWarningis raised and the callable is wrapped in aCircuitPassand installed as the sole pass in thePassManager. Must not be used together withpass_manager.calibration_set_id (UUID | str | None) – ID of the calibration set to use.
Nonemeans the server’s current default calibration set is used.use_metrics (bool) – Iff
True, the backend will query the server for calibration data and related quality metrics, and pass these to the default pass manager. Currently a no-op — the flag is stored and will be wired into both submission paths in a future release.pass_manager (PassManager | None) –
PassManager for circuit transpilation. Accepted values:
None: Builds a pre-configured PassManager that performs routing, layout and other optimization to bring good performance without configuration overhead.A
PassManagerinstance: Used directly for transpilation, bypassing the default pipeline entirely.
use_timeslot (bool) – If True, submits the job to the timeslot queue. If False, the job is submitted to the normal on-demand queue.
compilation_options (CircuitCompilationOptions | None) – Options for compiling circuits to pulse schedules. On the pulse-level execution path, the
CircuitCompilationOptions.max_circuit_duration_over_t2attribute has no effect.Nonemeans use the default options.compiler (Compiler | None) – IQM circuit-to-pulse compiler to use for pulse-level submissions.
Noneuses the standard compiler.
Examples: Automatic transpilation (default PassManager):
>>> from iqm.qrisp_iqm import IQMBackend >>> backend = IQMBackend( ... token="YOUR_API_TOKEN", ... device_instance="garnet" ... ) >>> from qrisp import QuantumCircuit >>> qc = QuantumCircuit(2) >>> qc.h(0) >>> qc.cx(0, 1) >>> qc.measure(qc.qubits) >>> result = backend.run(qc, shots=1000)
Custom pass pipeline via :attr:`pm`:
>>> from qrisp import PassManager, convert_to_cz, convert_to_prx >>> from iqm.qrisp_iqm import vf2pp_layout >>> backend = IQMBackend( ... token="YOUR_API_TOKEN", ... device_instance="garnet", ... pass_manager=PassManager() # start with an empty manager ... ) >>> coupling_map = [(0, 1), (1, 2), (2, 3)] >>> backend.pm += vf2pp_layout(coupling_map) >>> backend.pm += convert_to_cz() >>> backend.pm += convert_to_prx >>> result = backend.run(my_circuit, shots=1000)
The
pass_manager=PassManager()constructor argument gives you full control. You can also start fromNoneand extend the pipeline (or even insert passes at arbitrary positions viainsert_before()).Pulse-level execution (automatic routing):
>>> from iqm.qrisp_iqm import IQMBackend >>> from iqm.qrisp_iqm.pulse_operation import IQMPulseOperation >>> backend = IQMBackend( ... token="YOUR_API_TOKEN", ... device_instance="garnet" ... ) >>> # Circuit with IQMPulseOperation is compiled locally to a pulse-level job. >>> job = backend.run_async(my_pulse_circuit, shots=1000) >>> result = job.result()
Attributes
Currently executable qubit connectivity for this IQM backend.
Methods
Retrieve a previously submitted job.
Transpile and submit circuits for execution, return measurement result(s).
Transpile and submit circuits for execution on the IQM device, return immediately.
- run(circuits: QuantumCircuit | Sequence[QuantumCircuit], shots: int | None = None, *, use_timeslot: bool | None = None, compilation_options: CircuitCompilationOptions | None = None) MeasurementResult | list[MeasurementResult]#
Transpile and submit circuits for execution, return measurement result(s).
Blocks until the execution is finished, which may take awhile if there are other jobs in the queue. Consider using
run_async()instead.Takes the same args as
run_async().- Returns:
A pre-populated
MeasurementResultwhen one circuit is submitted, or a list of them for multiple circuits.- Parameters:
circuits (QuantumCircuit | Sequence[QuantumCircuit])
shots (int | None)
use_timeslot (bool | None)
compilation_options (CircuitCompilationOptions | None)
- Return type:
MeasurementResult | list[MeasurementResult]
- run_async(circuits: QuantumCircuit | Sequence[QuantumCircuit], shots: int | None = None, *, use_timeslot: bool | None = None, compilation_options: CircuitCompilationOptions | None = None) IQMJob#
Transpile and submit circuits for execution on the IQM device, return immediately.
Automatically detects whether any of
circuitscontainIQMPulseOperationinstances:No pulse ops → submitted as a gate-level
IQMCircuitJob.Has pulse ops → compiled locally down to pulse level, and submitted as a
IQMPulseJob.
- Parameters:
circuits (QuantumCircuit | Sequence[QuantumCircuit]) – The circuit(s) to execute.
shots (int | None) – Number of shots per circuit. If
None, use the backend default.use_timeslot (bool | None) – If True, submits the job to the timeslot queue. If False, the job is submitted to the normal on-demand queue.
Nonemeans use the default set in__init__().compilation_options (CircuitCompilationOptions | None) – Options for compiling circuits to pulse schedules. On the pulse-level execution path, the
CircuitCompilationOptions.max_circuit_duration_over_t2attribute has no effect.Nonemeans use the default set in__init__().
- Returns:
A job handle for the submitted execution.
- Return type:
IQMJob
- property connectivity: list[tuple[int, int]]#
Currently executable qubit connectivity for this IQM backend.
Cached once at construction time from the DynamicQuantumArchitecture.
- Returns:
The two-qubit gate coupling map as a list of qubit-index pairs.
- retrieve_job(job_id: str, *, pulse: Literal[False]) IQMCircuitJob#
- retrieve_job(job_id: str, *, pulse: Literal[True]) IQMPulseJob
Retrieve a previously submitted job.
- Parameters:
job_id – The IQM job ID (UUID as string) of the job to retrieve.
pulse – Whether the job was submitted at the pulse level.
- Returns:
Handle for the previously submitted job.
Inheritance
