PennyLane integration¶
From a source checkout, install the optional adapter with
uv pip install '.[pennylane]'. The IBMDevice
class reuses MQT Core’s PennyLane preprocessing, job orchestration, and sample
decoding. It exports ibm.default, ibm.berlin, and ibm.aachen as PennyLane
device names.
Configure a device¶
Set IBM_QUANTUM_API_KEY and IBM_QUANTUM_INSTANCE_CRN as described in
backend configuration. The generic ibm.default
device also requires IBM_QUANTUM_BACKEND or an explicit backend_name.
Concrete catalogue IDs keep their backend selection unless backend_name is
supplied.
import pennylane as qml
# Device construction queries IBM metadata. Calling the QNode submits paid jobs.
device = qml.device("ibm.berlin", wires=2)
@qml.qnode(device, shots=128)
def circuit():
qml.X(0)
return qml.counts(wires=[0, 1])
Supply api_key, instance_crn, and backend_name explicitly to override the
environment. IBMDevice(device=opened_device, wires=2) adapts an existing QDMI
session and rejects connection overrides. Importing the adapter and inspecting
entry points do not open a session or submit work.
The wrapper uses environment credentials as explicit session parameters when
api_key or instance_crn is omitted. An environment API key therefore takes
precedence over a registered authentication file. To retain a native session’s
file selection, open it through the QDMI driver and pass it as device; see
Usage guide for native credential precedence.
Wire labels map in their declared order to physical qubits starting at zero. For
example, wires=["control", "target"] maps those labels to physical qubits 0
and 1. Integer labels are labels, not a physical layout override. The emitted
OpenQASM always declares the full backend width, and measures only the exposed
wires using indexed assignments. Sample columns follow the requested measurement
order. The adapter validates each gate’s parameters and physical placement
against backend metadata. It does not route circuits or reverse directed
couplings.
Measurements and differentiation¶
Set finite shots on the QNode with shots=128, or use qml.set_shots. Analytic
execution and device-level shots are unsupported. Samples, counts,
probabilities, expectation values, and variances are computed from returned
samples. Shot vectors and parameter broadcasting may create several native jobs.
Parameter-shift and finite-difference differentiation use ordinary sampled jobs;
the device does not provide analytic gradients.
PennyLane decomposes operations into the advertised native basis. The IBM adapter expresses single-qubit rotations using SX and RZ while preserving parameters for differentiation; this includes Hadamard, RX, and RY gates. Native ECR and RZZ remain native when the backend advertises their signatures and placements. CNOT decomposes into CZ or ECR when CX is unavailable. Bound RZZ angles, including parameter-shift circuits, are folded into IBM’s calibrated range with equivalent single-qubit corrections. Incompatible operations or placements fail before any job in a prepared batch is submitted. A submission or result failure attempts cancellation of earlier jobs; remote cancellation can race with completion, and submissions are never retried.
The adapter forwards compatible custom job settings through job_parameters;
the native parameter contracts are documented in Usage guide. MQT Core 4’s Python
custom-parameter interface cannot encode the uint64_t execution-time cap.
PennyLane therefore retains the native default of 60 seconds; use the native C
interface to change that cap.
For local development without IBM access, use MQT Core’s
qml.device("mqt.ddsim.default", wires=2) with the same finite-shot QNode API.
This simulator checks circuit logic without validating IBM connectivity or
hardware behavior.