RemoteDevice¶
- class pennylane_qiskit.RemoteDevice(wires, backend, shots=1024, **kwargs)[source]¶
Bases:
QiskitDevice
A PennyLane device for any Qiskit backend.
- Parameters:
wires (int or Iterable[Number, str]]) – Number of subsystems represented by the device, or iterable that contains unique labels for the subsystems as numbers (i.e.,
[-1, 0, 2]
) or strings (['aux_wire', 'q1', 'q2']
).backend (Backend) – the initialized Qiskit backend
- Keyword Arguments:
shots (Union[int, None]) – number of circuit evaluations/random samples used to estimate expectation values and variances of observables.
session (Session) – a Qiskit Session to use for device execution. If none is provided, a session will be created at each device execution.
compile_backend (Union[Backend, None]) – the backend to be used for compiling the circuit that will be sent to the backend device, to be set if the backend desired for compliation differs from the backend used for execution. Defaults to
None
, which means the primary backend will be used.**kwargs – transpilation and runtime keyword arguments to be used for measurements with Primitives. If an options dictionary is defined amongst the kwargs, and there are settings that overlap with those in kwargs, the settings in options will take precedence over kwargs. Keyword arguments accepted by both the transpiler and at runtime (e.g.
optimization_level
) will be passed to the transpiler rather than to the Primitive.
Example:
import pennylane as qml from qiskit_ibm_runtime import QiskitRuntimeService service = QiskitRuntimeService(channel="ibm_quantum") backend = service.least_busy(n_qubits=127, simulator=False, operational=True) dev = qml.device("qiskit.remote", wires=127, backend=backend) @qml.qnode(dev) def circuit(x): qml.RX(x, wires=[0]) qml.CNOT(wires=[0, 1]) return qml.expval(qml.PauliZ(1))
>>> circuit(np.pi/3, shots=1024) 0.529296875
This device also supports the use of local simulators such as
AerSimulator
or fake backends such asFakeManila
.import pennylane as qml from qiskit_aer import AerSimulator backend = AerSimulator() dev = qml.device("qiskit.remote", wires=5, backend=backend) @qml.qnode(dev) def circuit(x): qml.RX(x, wires=[0]) qml.CNOT(wires=[0, 1]) return qml.expval(qml.PauliZ(1))
>>> circuit(np.pi/3, shots=1024) 0.49755859375
We can also change the number of shots, either when initializing the device or when we execute the circuit. Note that the shots number specified on circuit execution will override whatever was set on device initialization.
dev = qml.device("qiskit.remote", wires=5, backend=backend, shots=2) @qml.qnode(dev) def circuit(x): qml.RX(x, wires=[0]) qml.CNOT(wires=[0, 1]) return qml.sample(qml.PauliZ(1))
>>> circuit(np.pi/3) # this will run with 2 shots array([-1., 1.])
>>> circuit(np.pi/3, shots=5) # this will run with 5 shots array([-1., -1., 1., 1., 1.])
>>> circuit(np.pi/3) # this will run with 2 shots array([-1., 1.])
Internally, the device uses the EstimatorV2 and the SamplerV2 runtime primitives to execute the measurements. To set options for transpilation or runtime, simply pass the keyword arguments into the device. If you wish to change options other than
shots
, PennyLane requires you to re-initialize the device to do so.import pennylane as qml from qiskit_ibm_runtime.fake_provider import FakeManilaV2 backend = FakeManilaV2() dev = qml.device( "qiskit.remote", wires=5, backend=backend, resilience_level=1, optimization_level=1, seed_transpiler=42, ) # to change options, re-initialize the device dev = qml.device( "qiskit.remote", wires=5, backend=backend, resilience_level=1, optimization_level=2, seed_transpiler=24, )
Attributes
The Qiskit backend object.
A
DeviceCapabilities
object describing the capabilities of the backend device.The
compile_backend
is a Qiskit backend object to be used for transpilation.A device can use a toml file to specify the capabilities of the backend device.
The name of the device or set of devices.
Get the number of wires.
The QiskitRuntimeService service.
The QiskitRuntimeService session.
Default shots for execution workflows containing this device.
A
Tracker
that can store information about device executions, shots, batches, intermediate results, or any additional device dependent information.The device wires.
- backend¶
The Qiskit backend object.
- Returns:
Qiskit backend object.
- Return type:
qiskit.providers.Backend
- capabilities: DeviceCapabilities | None = None¶
A
DeviceCapabilities
object describing the capabilities of the backend device.
- compile_backend¶
The
compile_backend
is a Qiskit backend object to be used for transpilation. :returns: Qiskit backend object. :rtype: qiskit.providers.backend
- config_filepath: str | None = None¶
A device can use a toml file to specify the capabilities of the backend device. If this is provided, the file will be loaded into a
DeviceCapabilities
object assigned to thecapabilities
attribute.
- name¶
The name of the device or set of devices.
This property can either be the name of the class, or an alias to be used in the
device()
constructor, such as"default.qubit"
or"lightning.qubit"
.
- num_wires¶
Get the number of wires.
- Returns:
The number of wires.
- Return type:
int
- observables = {'Hadamard', 'Hermitian', 'Identity', 'LinearCombination', 'PauliX', 'PauliY', 'PauliZ', 'Prod', 'Projector', 'SProd', 'Sum'}¶
- operations = {'Adjoint(GlobalPhase)', 'Adjoint(S)', 'Adjoint(SX)', 'Adjoint(T)', 'Barrier', 'CCZ', 'CH', 'CNOT', 'CPhase', 'CRX', 'CRY', 'CRZ', 'CSWAP', 'CY', 'CZ', 'ECR', 'Hadamard', 'ISWAP', 'Identity', 'IsingXX', 'IsingYY', 'IsingZZ', 'PauliX', 'PauliY', 'PauliZ', 'PhaseShift', 'QubitUnitary', 'RX', 'RY', 'RZ', 'S', 'SWAP', 'SX', 'StatePrep', 'T', 'Toffoli', 'U1', 'U2', 'U3'}¶
- service¶
The QiskitRuntimeService service.
- Returns:
qiskit.qiskit_ibm_runtime.QiskitRuntimeService
- session¶
The QiskitRuntimeService session.
- Returns:
qiskit.qiskit_ibm_runtime.Session
- short_name = 'qiskit.remote'¶
- shots¶
Default shots for execution workflows containing this device.
Note that the device itself should always pull shots from the provided
QuantumTape
and itsshots
, not from this property. This property is used to provide a default at the start of a workflow.
- tracker: Tracker = <pennylane.devices.tracker.Tracker object>¶
A
Tracker
that can store information about device executions, shots, batches, intermediate results, or any additional device dependent information.A plugin developer can store information in the tracker by:
# querying if the tracker is active if self.tracker.active: # store any keyword: value pairs of information self.tracker.update(executions=1, shots=self._shots, results=results) # Calling a user-provided callback function self.tracker.record()
- wires¶
The device wires.
Note that wires are optional, and the default value of None means any wires can be used. If a device has wires defined, they will only be used for certain features. This includes:
Validation of tapes being executed on the device
Defining the wires used when evaluating a
state()
measurement
Methods
compile_circuits
(circuits)Compiles multiple circuits one after the other.
compute_derivatives
(circuits[, ...])Calculate the jacobian of either a single or a batch of circuits on the device.
compute_jvp
(circuits, tangents[, ...])The jacobian vector product used in forward mode calculation of derivatives.
compute_vjp
(circuits, cotangents[, ...])The vector jacobian product used in reverse-mode differentiation.
eval_jaxpr
(jaxpr, consts, *args[, ...])An experimental method for natively evaluating PLXPR.
execute
(circuits[, execution_config])Execute a circuit or a batch of circuits and turn it into results.
execute_and_compute_derivatives
(circuits[, ...])Compute the results and jacobians of circuits at the same time.
execute_and_compute_jvp
(circuits, tangents)Execute a batch of circuits and compute their jacobian vector products.
execute_and_compute_vjp
(circuits, cotangents)Calculate both the results and the vector jacobian product used in reverse-mode differentiation.
generate_samples
([circuit])Returns the computational basis samples generated for all wires.
get_transpile_args
(kwargs)The transpile argument setter.
jaxpr_jvp
(jaxpr, args, tangents[, ...])An experimental method for computing the results and jvp for PLXPR.
Specifies whether or not an observable is accepted by QiskitDevice2.
preprocess
([execution_config])This function defines the device transform program to be applied and an updated device configuration.
preprocess_transforms
([execution_config])Returns the transform program to preprocess a circuit for execution.
reset
()Reset the current job to None.
setup_execution_config
([config, circuit])Sets up an
ExecutionConfig
that configures the execution behaviour.Specifies whether or not an Operator is accepted by QiskitDevice2.
supports_derivatives
([execution_config, circuit])Determine whether or not a device provided derivative is potentially available.
supports_jvp
([execution_config, circuit])Whether or not a given device defines a custom jacobian vector product.
supports_vjp
([execution_config, circuit])Whether or not a given device defines a custom vector jacobian product.
update_session
(session)Update the session attribute.
- compile_circuits(circuits)¶
Compiles multiple circuits one after the other.
- Parameters:
circuits (list[QuantumCircuit]) – the circuits to be compiled
- Returns:
the list of compiled circuits
- Return type:
list[QuantumCircuit]
- compute_derivatives(circuits: ~pennylane.tape.qscript.QuantumScript | ~collections.abc.Sequence[~pennylane.tape.qscript.QuantumScript], execution_config: ~pennylane.devices.execution_config.ExecutionConfig = ExecutionConfig(grad_on_execution=None, use_device_gradient=None, use_device_jacobian_product=None, gradient_method=None, gradient_keyword_arguments={}, device_options={}, interface=<Interface.NUMPY: 'numpy'>, derivative_order=1, mcm_config=MCMConfig(mcm_method=None, postselect_mode=None), convert_to_numpy=True, executor_backend=<class 'pennylane.concurrency.executors.native.multiproc.MPPoolExec'>))¶
Calculate the jacobian of either a single or a batch of circuits on the device.
- Parameters:
circuits (Union[QuantumTape, Sequence[QuantumTape]]) – the circuits to calculate derivatives for
execution_config (ExecutionConfig) – a datastructure with all additional information required for execution
- Returns:
The jacobian for each trainable parameter
- Return type:
Tuple
See also
supports_derivatives()
andexecute_and_compute_derivatives()
.Execution Config:
The execution config has
gradient_method
andorder
property that describes the order of differentiation requested. If the requested method or order of gradient is not provided, the device should raise aNotImplementedError
. Thesupports_derivatives()
method can pre-validate supported orders and gradient methods.Return Shape:
If a batch of quantum scripts is provided, this method should return a tuple with each entry being the gradient of each individual quantum script. If the batch is of length 1, then the return tuple should still be of length 1, not squeezed.
- compute_jvp(circuits: ~pennylane.tape.qscript.QuantumScript | ~collections.abc.Sequence[~pennylane.tape.qscript.QuantumScript], tangents: tuple[~numbers.Number, ...], execution_config: ~pennylane.devices.execution_config.ExecutionConfig = ExecutionConfig(grad_on_execution=None, use_device_gradient=None, use_device_jacobian_product=None, gradient_method=None, gradient_keyword_arguments={}, device_options={}, interface=<Interface.NUMPY: 'numpy'>, derivative_order=1, mcm_config=MCMConfig(mcm_method=None, postselect_mode=None), convert_to_numpy=True, executor_backend=<class 'pennylane.concurrency.executors.native.multiproc.MPPoolExec'>))¶
The jacobian vector product used in forward mode calculation of derivatives.
- Parameters:
circuits (Union[QuantumTape, Sequence[QuantumTape]]) – the circuit or batch of circuits
tangents (tensor-like) – Gradient vector for input parameters.
execution_config (ExecutionConfig) – a datastructure with all additional information required for execution
- Returns:
A numeric result of computing the jacobian vector product
- Return type:
Tuple
Definition of jvp:
If we have a function with jacobian:
\[\vec{y} = f(\vec{x}) \qquad J_{i,j} = \frac{\partial y_i}{\partial x_j}\]The Jacobian vector product is the inner product with the derivatives of \(x\), yielding only the derivatives of the output \(y\):
\[\text{d}y_i = \Sigma_{j} J_{i,j} \text{d}x_j\]Shape of tangents:
The
tangents
tuple should be the same length ascircuit.get_parameters()
and have a single number per parameter. If a number is zero, then the gradient with respect to that parameter does not need to be computed.
- compute_vjp(circuits: ~pennylane.tape.qscript.QuantumScript | ~collections.abc.Sequence[~pennylane.tape.qscript.QuantumScript], cotangents: tuple[~numbers.Number, ...], execution_config: ~pennylane.devices.execution_config.ExecutionConfig = ExecutionConfig(grad_on_execution=None, use_device_gradient=None, use_device_jacobian_product=None, gradient_method=None, gradient_keyword_arguments={}, device_options={}, interface=<Interface.NUMPY: 'numpy'>, derivative_order=1, mcm_config=MCMConfig(mcm_method=None, postselect_mode=None), convert_to_numpy=True, executor_backend=<class 'pennylane.concurrency.executors.native.multiproc.MPPoolExec'>))¶
The vector jacobian product used in reverse-mode differentiation.
- Parameters:
circuits (Union[QuantumTape, Sequence[QuantumTape]]) – the circuit or batch of circuits
cotangents (Tuple[Number, Tuple[Number]]) – Gradient-output vector. Must have shape matching the output shape of the corresponding circuit. If the circuit has a single output, cotangents may be a single number, not an iterable of numbers.
execution_config (ExecutionConfig) – a datastructure with all additional information required for execution
- Returns:
A numeric result of computing the vector jacobian product
- Return type:
tensor-like
Definition of vjp:
If we have a function with jacobian:
\[\vec{y} = f(\vec{x}) \qquad J_{i,j} = \frac{\partial y_i}{\partial x_j}\]The vector jacobian product is the inner product of the derivatives of the output
y
with the Jacobian matrix. The derivatives of the output vector are sometimes called the cotangents.\[\text{d}x_i = \Sigma_{i} \text{d}y_i J_{i,j}\]Shape of cotangents:
The value provided to
cotangents
should match the output ofexecute()
.
- eval_jaxpr(jaxpr: jax.extend.core.Jaxpr, consts: list[TensorLike], *args, execution_config: ExecutionConfig | None = None) list[TensorLike] ¶
An experimental method for natively evaluating PLXPR. See the
capture
module for more details.- Parameters:
jaxpr (jax.extend.core.Jaxpr) – Pennylane variant jaxpr containing quantum operations and measurements
consts (list[TensorLike]) – the closure variables
consts
corresponding to the jaxpr*args (TensorLike) – the variables to use with the jaxpr.
- Keyword Arguments:
execution_config (Optional[ExecutionConfig]) – a data structure with additional information required for execution
- Returns:
the result of evaluating the jaxpr with the given parameters.
- Return type:
list[TensorLike]
- execute(circuits: QuantumTape | Sequence[QuantumTape], execution_config: ExecutionConfig | None = None) Result | Sequence[Result] ¶
Execute a circuit or a batch of circuits and turn it into results.
- execute_and_compute_derivatives(circuits: ~pennylane.tape.qscript.QuantumScript | ~collections.abc.Sequence[~pennylane.tape.qscript.QuantumScript], execution_config: ~pennylane.devices.execution_config.ExecutionConfig = ExecutionConfig(grad_on_execution=None, use_device_gradient=None, use_device_jacobian_product=None, gradient_method=None, gradient_keyword_arguments={}, device_options={}, interface=<Interface.NUMPY: 'numpy'>, derivative_order=1, mcm_config=MCMConfig(mcm_method=None, postselect_mode=None), convert_to_numpy=True, executor_backend=<class 'pennylane.concurrency.executors.native.multiproc.MPPoolExec'>))¶
Compute the results and jacobians of circuits at the same time.
- Parameters:
circuits (Union[QuantumTape, Sequence[QuantumTape]]) – the circuits or batch of circuits
execution_config (ExecutionConfig) – a datastructure with all additional information required for execution
- Returns:
A numeric result of the computation and the gradient.
- Return type:
tuple
See
execute()
andcompute_derivatives()
for more information about return shapes and behaviour. Ifcompute_derivatives()
is defined, this method should be as well.This method can be used when the result and execution need to be computed at the same time, such as during a forward mode calculation of gradients. For certain gradient methods, such as adjoint diff gradients, calculating the result and gradient at the same can save computational work.
- execute_and_compute_jvp(circuits: ~pennylane.tape.qscript.QuantumScript | ~collections.abc.Sequence[~pennylane.tape.qscript.QuantumScript], tangents: tuple[~numbers.Number, ...], execution_config: ~pennylane.devices.execution_config.ExecutionConfig = ExecutionConfig(grad_on_execution=None, use_device_gradient=None, use_device_jacobian_product=None, gradient_method=None, gradient_keyword_arguments={}, device_options={}, interface=<Interface.NUMPY: 'numpy'>, derivative_order=1, mcm_config=MCMConfig(mcm_method=None, postselect_mode=None), convert_to_numpy=True, executor_backend=<class 'pennylane.concurrency.executors.native.multiproc.MPPoolExec'>))¶
Execute a batch of circuits and compute their jacobian vector products.
- Parameters:
circuits (Union[QuantumTape, Sequence[QuantumTape]]) – circuit or batch of circuits
tangents (tensor-like) – Gradient vector for input parameters.
execution_config (ExecutionConfig) – a datastructure with all additional information required for execution
- Returns:
A numeric result of execution and of computing the jacobian vector product
- Return type:
Tuple, Tuple
See also
execute()
andcompute_jvp()
- execute_and_compute_vjp(circuits: ~pennylane.tape.qscript.QuantumScript | ~collections.abc.Sequence[~pennylane.tape.qscript.QuantumScript], cotangents: tuple[~numbers.Number, ...], execution_config: ~pennylane.devices.execution_config.ExecutionConfig = ExecutionConfig(grad_on_execution=None, use_device_gradient=None, use_device_jacobian_product=None, gradient_method=None, gradient_keyword_arguments={}, device_options={}, interface=<Interface.NUMPY: 'numpy'>, derivative_order=1, mcm_config=MCMConfig(mcm_method=None, postselect_mode=None), convert_to_numpy=True, executor_backend=<class 'pennylane.concurrency.executors.native.multiproc.MPPoolExec'>))¶
Calculate both the results and the vector jacobian product used in reverse-mode differentiation.
- Parameters:
circuits (Union[QuantumTape, Sequence[QuantumTape]]) – the circuit or batch of circuits to be executed
cotangents (Tuple[Number, Tuple[Number]]) – Gradient-output vector. Must have shape matching the output shape of the corresponding circuit. If the circuit has a single output, cotangents may be a single number, not an iterable of numbers.
execution_config (ExecutionConfig) – a datastructure with all additional information required for execution
- Returns:
the result of executing the scripts and the numeric result of computing the vector jacobian product
- Return type:
Tuple, Tuple
See also
execute()
andcompute_vjp()
- generate_samples(circuit=None)¶
Returns the computational basis samples generated for all wires.
Note that PennyLane uses the convention \(|q_0,q_1,\dots,q_{N-1}\rangle\) where \(q_0\) is the most significant bit.
- Parameters:
circuit (int) – position of the circuit in the batch.
- Returns:
array of samples in the shape
(dev.shots, dev.num_wires)
- Return type:
array[complex]
- static get_transpile_args(kwargs)¶
The transpile argument setter. This separates keyword arguments related to transpilation from the rest of the keyword arguments and removes those keyword arguments from kwargs.
- Keyword Arguments:
kwargs (dict) – combined keyword arguments to be parsed for the Qiskit transpiler. For more details, see the Qiskit transpiler documentation
- Returns:
keyword arguments for the runtime options and keyword arguments for the transpiler
- Return type:
kwargs (dict), transpile_args (dict)
- jaxpr_jvp(jaxpr: jax.extend.core.Jaxpr, args, tangents, execution_config: ExecutionConfig | None = None)¶
An experimental method for computing the results and jvp for PLXPR. See the
capture
module for more details.- Parameters:
jaxpr (jax.extend.core.Jaxpr) – Pennylane variant jaxpr containing quantum operations and measurements
args (Sequence[TensorLike]) – the
consts
followed by the normal argumentstangents (Sequence[TensorLike]) – the tangents corresponding to
args
. May containjax.interpreters.ad.Zero
.
- Keyword Arguments:
execution_config (Optional[ExecutionConfig]) – a data structure with additional information required for execution
- Returns:
the results and jacobian vector products
- Return type:
Sequence[TensorLike], Sequence[TensorLike]
>>> qml.capture.enable() >>> import jax >>> closure_var = jax.numpy.array(0.5) >>> def f(x): ... qml.RX(closure_var, 0) ... qml.RX(x, 1) ... return qml.expval(qml.Z(0)), qml.expval(qml.Z(1)) >>> jaxpr = jax.make_jaxpr(f)(1.2) >>> args = (closure_var, 1.2) >>> zero = jax.interpreters.ad.Zero(jax.core.ShapedArray((), float)) >>> tangents = (zero, 1.0) >>> config = qml.devices.ExecutionConfig(gradient_method="adjoint") >>> dev = qml.device('default.qubit', wires=2) >>> res, jvps = dev.jaxpr_jvp(jaxpr.jaxpr, args, tangents, execution_config=config) >>> res [Array(0.87758255, dtype=float32), Array(0.36235774, dtype=float32)] >>> jvps [Array(0., dtype=float32), Array(-0.932039, dtype=float32)]
- observable_stopping_condition(obs: Operator) bool ¶
Specifies whether or not an observable is accepted by QiskitDevice2.
- preprocess(execution_config: ExecutionConfig | None = None) Tuple[TransformProgram, ExecutionConfig] ¶
This function defines the device transform program to be applied and an updated device configuration.
- Parameters:
execution_config (Union[ExecutionConfig, Sequence[ExecutionConfig]]) – A data structure describing the parameters needed to fully describe the execution.
- Returns:
A transform program that when called returns QuantumTapes that the device can natively execute as well as a postprocessing function to be called after execution, and a configuration with unset specifications filled in.
- Return type:
TransformProgram, ExecutionConfig
This device:
Supports any operations with explicit PennyLane to Qiskit gate conversions defined in the plugin
Does not intrinsically support parameter broadcasting
- preprocess_transforms(execution_config: ExecutionConfig | None = None) TransformProgram ¶
Returns the transform program to preprocess a circuit for execution.
- Parameters:
execution_config (ExecutionConfig) – The execution configuration object
- Returns:
A transform program that is called before execution
- Return type:
TransformProgram
The transform program is composed of a list of individual transforms, which may include:
Decomposition of operations and measurements to what is supported by the device.
Splitting a circuit with measurements of non-commuting observables or Hamiltonians into multiple executions.
Splitting a circuit with batched parameters into multiple executions.
Validation of wires, measurements, and observables.
Gradient specific preprocessing, such as making sure trainable operators have generators.
Example
All transforms that are part of the preprocessing transform program need to respect the transform contract defined in
pennylane.transform()
.from pennylane.tape import QuantumScriptBatch from pennylane.typing import PostprocessingFn @qml.transform def my_preprocessing_transform(tape: qml.tape.QuantumScript) -> tuple[QuantumScriptBatch, PostprocessingFn]: # e.g. valid the measurements, expand the tape for the hardware execution, ... def blank_processing_fn(results): return results[0] return [tape], processing_fn
A transform program can hold an arbitrary number of individual transforms:
def preprocess(self, config): program = TransformProgram() program.add_transform(my_preprocessing_transform) return program
See also
transform()
andTransformProgram
Post processing function and derivatives
Derivatives and Jacobian products will be bound to the machine learning library before the postprocessing function is called on the results. Therefore, the machine learning library will be responsible for combining and post-processing derivatives returned from the device.
from pennylane.interfaces.jax import execute as jax_boundary def f(x): circuit = qml.tape.QuantumScript([qml.Rot(*x, wires=0)], [qml.expval(qml.Z(0))]) config = ExecutionConfig(gradient_method="adjoint") config = dev.setup_execution_config(config) program = dev.preprocess_transforms(config) circuit_batch, postprocessing = program((circuit, )) def execute_fn(tapes): return dev.execute_and_compute_derivatives(tapes, config) results = jax_boundary(circuit_batch, dev, execute_fn, None, {}) return postprocessing(results) x = jax.numpy.array([1.0, 2.0, 3.0]) jax.grad(f)(x)
In the above code, the quantum derivatives are registered with jax in the
jax_boundary
function. Only then is the classical postprocessing called on the result object.
- reset()¶
Reset the current job to None.
- setup_execution_config(config: ExecutionConfig | None = None, circuit: QuantumScript | None = None) ExecutionConfig ¶
Sets up an
ExecutionConfig
that configures the execution behaviour.The execution config stores information on how the device should perform the execution, as well as how PennyLane should interact with the device. See
ExecutionConfig
for all available options and what they mean.An
ExecutionConfig
is constructed from arguments passed to theQNode
, and this method allows the device to update the config object based on device-specific requirements or preferences. See Execution Config for more details.- Parameters:
config (ExecutionConfig) – The initial ExecutionConfig object that describes the parameters needed to configure the execution behaviour.
circuit (QuantumScript) – The quantum circuit to customize the execution config for.
- Returns:
The updated ExecutionConfig object
- Return type:
ExecutionConfig
- stopping_condition(op: Operator) bool ¶
Specifies whether or not an Operator is accepted by QiskitDevice2.
- supports_derivatives(execution_config: ExecutionConfig | None = None, circuit: QuantumScript | None = None) bool ¶
Determine whether or not a device provided derivative is potentially available.
Default behaviour assumes first order device derivatives for all circuits exist if
compute_derivatives()
is overriden.- Parameters:
execution_config (ExecutionConfig) – A description of the hyperparameters for the desired computation.
circuit (None, QuantumTape) – A specific circuit to check differentation for.
- Returns:
Bool
The device can support multiple different types of “device derivatives”, chosen via
execution_config.gradient_method
. For example, a device can natively calculate"parameter-shift"
derivatives, in which casecompute_derivatives()
will be called for the derivative instead ofexecute()
with a batch of circuits.>>> config = ExecutionConfig(gradient_method="parameter-shift") >>> custom_device.supports_derivatives(config) True
In this case,
compute_derivatives()
orexecute_and_compute_derivatives()
will be called instead ofexecute()
with a batch of circuits.If
circuit
is not provided, then the method should return whether or not device derivatives exist for any circuit.Example:
For example, the Python device will support device differentiation via the adjoint differentiation algorithm if the order is
1
and the execution occurs with no shots (shots=None
).>>> config = ExecutionConfig(derivative_order=1, gradient_method="adjoint") >>> dev.supports_derivatives(config) True >>> circuit_analytic = qml.tape.QuantumScript([qml.RX(0.1, wires=0)], [qml.expval(qml.Z(0))], shots=None) >>> dev.supports_derivatives(config, circuit=circuit_analytic) True >>> circuit_finite_shots = qml.tape.QuantumScript([qml.RX(0.1, wires=0)], [qml.expval(qml.Z(0))], shots=10) >>> dev.supports_derivatives(config, circuit = circuit_fintite_shots) False
>>> config = ExecutionConfig(derivative_order=2, gradient_method="adjoint") >>> dev.supports_derivatives(config) False
Adjoint differentiation will only be supported for circuits with expectation value measurements. If a circuit is provided and it cannot be converted to a form supported by differentiation method by
preprocess()
, thensupports_derivatives
should return False.>>> config = ExecutionConfig(derivative_order=1, shots=None, gradient_method="adjoint") >>> circuit = qml.tape.QuantumScript([qml.RX(2.0, wires=0)], [qml.probs(wires=(0,1))]) >>> dev.supports_derivatives(config, circuit=circuit) False
If the circuit is not natively supported by the differentiation method but can be converted into a form that is supported, it should still return
True
. For example,Rot
gates are not natively supported by adjoint differentation, as they do not have a generator, but they can be compiled into operations supported by adjoint differentiation. Therefore this method may reproduce compilation and validation steps performed bypreprocess()
.>>> config = ExecutionConfig(derivative_order=1, shots=None, gradient_method="adjoint") >>> circuit = qml.tape.QuantumScript([qml.Rot(1.2, 2.3, 3.4, wires=0)], [qml.expval(qml.Z(0))]) >>> dev.supports_derivatives(config, circuit=circuit) True
Backpropagation:
This method is also used be to validate support for backpropagation derivatives. Backpropagation is only supported if the device is transparent to the machine learning framework from start to finish.
>>> config = ExecutionConfig(gradient_method="backprop") >>> python_device.supports_derivatives(config) True >>> cpp_device.supports_derivatives(config) False
- supports_jvp(execution_config: ExecutionConfig | None = None, circuit: QuantumScript | None = None) bool ¶
Whether or not a given device defines a custom jacobian vector product.
- Parameters:
execution_config (ExecutionConfig) – A description of the hyperparameters for the desired computation.
circuit (None, QuantumTape) – A specific circuit to check differentation for.
Default behaviour assumes this to be
True
ifcompute_jvp()
is overridden.
- supports_vjp(execution_config: ExecutionConfig | None = None, circuit: QuantumScript | None = None) bool ¶
Whether or not a given device defines a custom vector jacobian product.
- Parameters:
execution_config (ExecutionConfig) – A description of the hyperparameters for the desired computation.
circuit (None, QuantumTape) – A specific circuit to check differentation for.
Default behaviour assumes this to be
True
ifcompute_vjp()
is overridden.
- update_session(session)¶
Update the session attribute.
- Parameters:
session – The new session to be set.