squlearn.Executor

class squlearn.Executor(execution: str | Backend | List[Backend] | QiskitRuntimeService | Session | BaseEstimatorV1 | BaseSamplerV1 | BaseEstimatorV2 | BaseSamplerV2 | Device = 'pennylane', backend: Backend | str | None = None, options_estimator: Any | None = None, options_sampler: Any | None = None, log_file: str = '', caching: bool | None = None, cache_dir: str = '_cache', max_session_time: str = '8h', max_jobs_retries: int = 10, wait_restart: int = 1, shots: int | None = None, seed: int | None = None, qpu_parallelization: int | str | None = None, auto_backend_mode: str = 'quality')

A class for executing quantum jobs on IBM Quantum systems or simulators.

The Executor class is the central component of sQUlearn, responsible for running quantum jobs. Both high- and low-level methods utilize the Executor class to execute jobs seamlessly. It for example automatically creates the necessary Qiskit primitives when they are required in the sQUlearn sub-program or takes care of the execution of PennyLane circuits. The Executor takes care about Qiskit Runtime session handling, result caching, and automatic restarts of failed jobs.

The Estimator can be initialized with various objects that specify the execution environment, as for example a Qiskit backend or a PennyLane device.

A detailed introduction to the Executor can be found in the User Guide: The Executor Class

The version of Qiskit Primitives used by the Executor depends on the installed Qiskit version: - For Qiskit versions 1.2 and above, the Executor uses Qiskit Primitives V2. - For versions below 1.2, it defaults to Primitives V1.

Note: The Sampler in Primitives V2 uses shots, even with statevector simulators, whereas Primitives V1 provides exact probabilities.

Important: When using the Executor to run jobs on IBM Quantum systems, sessions are created automatically. If you are working in a Jupyter notebook, ensure you close the session once calculations are complete to avoid unnecessary open sessions (close_session()), to avoide being charged for the opened but unused session.

Parameters:
  • execution (Union[str, Backend, List[Backend], QiskitRuntimeService, Session,BaseEstimatorV1, BaseSamplerV1, BaseEstimatorV2, BaseSamplerV2, PennylaneDevice]) –

    The execution environment, possible inputs are:

    • A string, that specifics the simulator backend. For Qiskit this can be "qiskit",``”statevector_simulator”`` or "qasm_simulator". For PennyLane this can be "pennylane", "default.qubit".

    • A PennyLane device, to run the jobs with PennyLane (e.g. AWS Braket plugin for PennyLane)

    • A Qiskit backend, to run the jobs on IBM Quantum systems or simulators

    • A list of Qiskit backends for automatic backend selection later on

    • A QiskitRuntimeService, to run the jobs on the Qiskit Runtime service. In this case the backend has to be provided separately via backend=

    • A Session, to run the jobs on the Qiskit Runtime service

    • A Estimator primitive (either simulator or Qiskit Runtime primitive - V1 or V2)

    • A Sampler primitive (either simulator or Qiskit Runtime primitive - V1 or V2)

    Default is the initialization with PennyLane’s DefaultQubit simulator.

  • backend (Union[Backend, str, None]) – The backend that is used for the execution. Only mandatory if a service is provided.

  • options_estimator (Union[Any]) – The options for the created estimator primitives.

  • options_sampler (Union[Any]) – The options for the created sampler primitives.

  • log_file (str) – The name of the log file, if empty, no log file is created.

  • caching (Union[bool, None]) – Whether to cache the results of the jobs.

  • cache_dir (str) – The directory where to cache the results of the jobs.

  • max_session_time (str) – The maximum time for a session, similar input as in Qiskit.

  • max_jobs_retries (int) – The maximum number of retries for a job until the execution is aborted.

  • wait_restart (int) – The time to wait before restarting a job in seconds.

  • shots (Union[int, None]) – The number of initial shots that is used for the execution.

  • seed (Union[int, None]) – The seed that is used for finite samples in the execution.

  • qpu_parallelization (Union[int, str, None]) – The number of parallel executions on the QPU. If set to "auto", the number of parallel executions is automatically determined. If set to None, no parallelization is used. Default is None.

  • auto_backend_mode (str) –

    The mode for automatic backend selection. Possible values are:

    • "quality": Automatically selects the best backend for the provided circuit using the mapomatic tool. This is the default value.

    • "quality_hqaa": Same as "quality", but uses the HQAA algorithm.

    • "speed": Automatically selects the backend with the smallest queue using the mapomatic tool.

    • "speed_hqaa": Same as "speed", but uses the HQAA algorithm.

Attributes:

execution

String of the execution environment.

Type:

str

backend

The backend that is used in the Executor.

Type:

Backend

backend_list

The list of backends used for the automatic backend selection.

Type:

List[Backend]

backend_chosen

True, if the backend was chosen automatically.

Type:

Bool

backend_name

The name of the backend that is used in the Executor.

Type:

str

is_statevector

Returns true if the backend is a statevector simulator.

Type:

Bool

qpu_parallelization

Returns true if QPU parallelization is used.

Type:

Bool

session

The session that is used in the Executor.

Type:

Session

service

The service that is used in the Executor.

Type:

QiskitRuntimeService

quantum_framework

The framework used in the Executor ("qiskit" or "pennylane").

Type:

str

IBMQuantum

Whether the backend is an IBM Quantum backend.

Type:

bool

estimator

The Qiskit estimator primitive that is used in the Executor. Different to get_estimator(), which creates a new estimator object with overwritten methods that runs everything through the Executor with estimator_run().

Type:

BaseEstimatorV1, BaseEstimatorV2

sampler

The Qiskit sampler primitive that is used in the Executor. Different to get_sampler(), which creates a new sampler object with overwritten methods that runs everything through the Executor with estimator_run().

Type:

BaseSamplerV1, BaseEstimatorV2

shots

The number of shots that is used in the Executor.

Type:

int

estimator_options

Options of the Runtime Estiamtor V2

sampler_options

Options of the Runtime Sampler V2

Example: Different PennyLane based initializations of the Executor

from squlearn import Executor
import pennylane as qml

# Executor with a PennyLane device (statevector)
executor = Executor(qml.device("default.qubit"))

# Executor with a PennyLane device (shot-based)
executor = Executor(qml.device("default.qubit", shots=1000))

# Executor with a PennyLane lightining device
executor = Executor(qml.device("lightning.qubit"))

# Executor with a AWS Braket device with 4 qubits
# (requires a valid AWS credential to be set)
dev = qml.device(
    "braket.aws.qubit",
    device_arn="arn:aws:braket:::device/quantum-simulator/amazon/sv1",
    wires=4
)
executor = Executor(dev)

Example: Different Qiskit based initializations of the Executor

from squlearn import Executor
from qiskit_ibm_runtime import QiskitRuntimeService

# Executor with a ideal simulator backend
exec = Executor("statevector_simulator")

# Executor with a shot-based simulator backend and 1000 shots
exec = Executor("qasm_simulator")
exec.set_shots(1000)

# Executor with a IBM Quantum backend
service = QiskitRuntimeService(channel="ibm_quantum", token="INSERT_YOUR_TOKEN_HERE")
executor = Executor(service.get_backend('ibm_brisbane'))

# Executor with a IBM Quantum backend and caching and logging
service = QiskitRuntimeService(channel="ibm_quantum", token="INSERT_YOUR_TOKEN_HERE")
executor = Executor(service.get_backend('ibm_brisbane'), caching=True,
                     cache_dir='cache', log_file="log.log")

Example: Get the Executor based Qiskit primitives

from squlearn import Executor

# Initialize the Executor
executor = Executor("statevector_simulator")

# Get the Executor based Estimator with all execusions routed through the Executor
estimator = executor.get_estimator()

# Get the Executor based Sampler with all execusions routed through the Executor
sampler = executor.get_sampler()

# Run a circuit with the Executor based Sampler
from qiskit.circuit.random import random_circuit
circuit = random_circuit(2, 2, seed=1, measure=True).decompose(reps=1)
job = sampler.run([(circuit,)])
result = job.result()

Example: Automatic backend selection

import numpy as np
from squlearn import Executor
from qiskit_ibm_runtime import QiskitRuntimeService
from squlearn.encoding_circuit import ChebyshevRx
from squlearn.kernel import FidelityKernel, QKRR

# Executor is initialized with a service, and considers all available backends
# (except simulators)
service = QiskitRuntimeService(channel="ibm_quantum", token="INSERT_YOUR_TOKEN_HERE")
executor = Executor(service, auto_backend_mode="quality")

# Create a QKRR model with a FidelityKernel and the ChebyshevRx encoding circuit
qkrr = QKRR(FidelityKernel(ChebyshevRx(4,1),executor))

# Backend is automatically selected based on the encoding circuit
# All the following functions will be executed on the selected backend
X_train, y_train = np.array([[0.1],[0.2]]), np.array([0.1,0.2])
qkrr.fit(X_train, y_train)

# Close the session to avoid being charged for the opened but unused session
executor.close_session()

Example: QPU parallelization

from squlearn import Executor

# All circuit executions are copied four times and are executed in parallel
executor = Executor("statevector_simulator", qpu_parallelization=4)

# The level of parallelization is determined automatically to reach a maximum
# parallelization level of number of qubits of the backend divided by the number of qubits
# of the circuit
executor = Executor("statevector_simulator", qpu_parallelization="auto")

Methods:

clear_estimator_cache() None

Function for clearing the cache of the EstimatorV1 primitive to avoid memory overflow.

clear_sampler_cache() None

Function for clearing the cache of the SamplerV1 primitive to avoid memory overflow.

close_session()

Closes the current session, is called automatically.

create_session()

Creates a new session, is called automatically.

estimator_run_v1(circuits, observables, parameter_values=None, **kwargs: Any) JobV1

Function similar to the Qiskit Estimator V1 run function, but this one includes caching, automatic session handling, and restarts of failed jobs.

Parameters:
  • circuits – Quantum circuits to execute.

  • observables – Observable to measure.

  • parameter_values – Values for the parameters in circuits.

  • kwargs (Any) – Additional arguments that are passed to the estimator.

Returns:

A qiskit job containing the results of the run.

estimator_run_v2(pubs: Iterable[EstimatorPub | Tuple[QuantumCircuit, str | Pauli | SparsePauliOp | Mapping[str | Pauli, float] | Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | bytes | _NestedSequence[bool | int | float | complex | str | bytes]] | Tuple[QuantumCircuit, str | Pauli | SparsePauliOp | Mapping[str | Pauli, float] | Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | bytes | _NestedSequence[bool | int | float | complex | str | bytes], Mapping[Parameter | str | Tuple[Parameter | str, ...], Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]]] | Tuple[QuantumCircuit, str | Pauli | SparsePauliOp | Mapping[str | Pauli, float] | Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | bytes | _NestedSequence[bool | int | float | complex | str | bytes], Mapping[Parameter | str | Tuple[Parameter | str, ...], Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]], Real]], precision: float | None = None)

Function similar to the Qiskit Estimator V2 run function, but this one includes caching, automatic session handling, and restarts of failed jobs.

Parameters:
  • pubs (Iterable[EstimatorPubLike]) – An iterable of pub-like objects, such as tuples (circuit, observables) or (circuit, observables, parameter_values).

  • precision (Union[float, None]) – The target precision for expectation value estimates of each run Estimator Pub that does not specify its own precision. If None the the precision is set by the executor number of shots.

Returns:

A qiskit job containing the results of the run.

get_estimator()

Returns a Estimator primitive that overwrites the Qiskit Estimator primitive.

This Estimator runs all executions through the Executor and includes result caching, automatic session handling, and restarts of failed jobs.

For Qiskit >= 1.2 the Estimator V2 is used, for Qiskit < 1.2 the Estimator V1 is returned.

get_sampler()

Returns a Sampler primitive that overwrites the Qiskit Sampler primitive.

This Sampler runs all executions through the Executor and includes result caching, automatic session handling, and restarts of failed jobs.

For Qiskit >= 1.2 the Sampler V2 is used, for Qiskit < 1.2 the Sampler V1 is returned.

get_shots() int

Getter for the number of shots.

Returns:

Returns the number of shots that are used for the current evaluation.

pennylane_execute(pennylane_circuit: callable, *args, **kwargs)

Function for executing of PennyLane circuits with the Executor with caching and restarts

Parameters:
  • pennylane_circuit (callable) – The PennyLane circuit function

  • args – Arguments for the circuit

  • kwargs – Keyword arguments for the circuit

Returns:

The result of the circuit

pennylane_execute_batched(pennylane_circuit: callable, arg_tuples: list | tuple, **kwargs) array | list

Function for batched execution of PennyLane circuits.

Parameters:
  • pennylane_circuit (callable) – The PennyLane circuit function

  • arg_tuples (Union[list,tuple]) – List of tuples with arguments for the circuit

Returns

Union[np.array,list]: List of results of the circuits

qiskit_execute(run_input, **options)

Routine that runs the given circuits on the backend.

Parameters:
  • run_input – An object to run on the backend (typically a circuit).

  • options – Additional arguments that are passed to the backend.

Returns:

The Qiskit job object from the run.

reset_shots() None

Resets the shots to the initial values when the executor was created.

sampler_run_v1(circuits, parameter_values=None, **kwargs: Any) JobV1

Function similar to the Qiskit Sampler V1 run function, but this one includes caching, automatic session handling, and restarts of failed jobs.

Parameters:
  • circuits – Quantum circuits to execute.

  • parameter_values – Values for the parameters in circuits.

  • kwargs (Any) – Additional arguments that are passed to the estimator.

Returns:

A qiskit job containing the results of the run.

sampler_run_v2(pubs: Iterable[QuantumCircuit | Tuple[QuantumCircuit] | Tuple[QuantumCircuit, Mapping[Parameter | str | Tuple[Parameter | str, ...], Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]]] | Tuple[QuantumCircuit, Mapping[Parameter | str | Tuple[Parameter | str, ...], Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]], Integral | None]], *, shots: int | None = None)

Function similar to the Qiskit Sampler V2 run function, but this one includes caching, automatic session handling, and restarts of failed jobs.

Parameters:
  • pubs (Iterable[EstimatorPubLike]) – An iterable of pub-like objects, such as tuples (circuit,) or (circuit, parameter_values).

  • shots (Union[int, None]) – The number of shots used for the sampling. If None the Executors numer of shot will be used.

Returns:

A qiskit job containing the results of the run.

select_backend(circuit, **options)

Selects the best backend for a given circuit and options.

Parameters:
  • circuit – Either a QuantumCircuit or an EncodingCircuitBase

  • **options

    Additional options for backend selection. Possible options:

    • min_num_qubits: Minimum number of qubits in the circuit (default: None)

    • max_num_qubits: Maximum number of qubits in the circuit (default: None)

    • cost_function: Cost function to use (default: None)

    • optimization_level: Optimization level (default: 3)

    • n_trials_transpile: Number of trials to transpile (default: 1)

    • call_limit: Call limit (default: int(3e7))

    • verbose: Whether to print information (default: False)

    • mode: Mode for the backend selection. Overwrites the option provided to the constructor.

    • use_hqaa: Whether to use HQAA. Overwrites the option provided to the constructor.

Returns:

A tuple containing the best backend and the transpiled circuit

set_backend(backend: Backend)

Sets the backend that is used for the execution.

Parameters:

backend (Backend) – Backend that is used for the execution.

set_options_estimator(**fields)

Set options values for the estimator (V1 and V2).

Parameters:

**fields – The fields to update the options

set_options_sampler(**fields)

Set options values for the sampler (V1 and V2).

Parameters:

**fields – The fields to update the options

set_primitive_options(**fields)

Set options values for the estimator and sampler primitive.

Parameters:

**fields – The fields to update the options

set_seed_for_primitive(seed: int = 0)

Set options values for the estimator run.

Parameters:

**fields – The fields to update the options

set_shots(num_shots: int | None) None

Sets the number shots for the next evaluations.

Parameters:

num_shots (int or None) – Number of shots that are set

unset_backend()

Unsets the backend that is used for the execution.