Execution

from mpqp.execution import *

Execution is the core of this library. Our goal is to allow you to run a circuit on any hardware without you having to rewrite your circuit in the providers’SDK. We introduce here how execution works in MPQP, both in local simulator and in remote QPUs.

Languages

A circuit is always executed on a user-selected device. Prior to this execution, the circuit is first translated into the SDK selected to support this device. This is done by the to_other_language function present on most objects of MPQP, which takes a language argument. This language corresponds to the appropriate SDK, and you can find the list of available languages in the Language enum.

class Language(value)[source]

Bases: Enum

Enumerate containing all the supported languages.

BRAKET = 3
CIRQ = 4
MY_QLM = 2
QASM2 = 5
QASM3 = 6
QISKIT = 1

Devices

An AvailableDevice is a device on which one can run or submit a circuit. While it is an abstract class, all its concrete implementations are enums with a few methods, required by AvailableDevice.

Each supported provider has its available devices listed as these enums:

Not all combinations of AvailableDevice and JobType are possible. Here is the list of compatible jobs types and devices.

For more information about handling Remote devices, please refer to the Remote devices handling section.

Job/Device Compatibility Matrix

Provider

Device

LOCAL

SAMPLE

STATE_VECTOR

OBSERVABLE

OBSERVABLE ideal

IBM

AER_SIMULATOR

IBM

AER_SIMULATOR_STATEVECTOR

IBM

AER_SIMULATOR_DENSITY_MATRIX

IBM

AER_SIMULATOR_STABILIZER

IBM

AER_SIMULATOR_EXTENDED_STABILIZER

IBM

AER_SIMULATOR_MATRIX_PRODUCT_STATE

IBM

IBM_BRISBANE

IBM

IBM_SHERBROOKE

IBM

IBM_KYIV

IBM

IBM_NAZCA

IBM

IBM_TORINO

IBM

IBM_QUEBEC

IBM

IBM_KAWASAKI

IBM

IBM_CLEVELAND

IBM

IBM_PEEKSKILL

IBM

IBM_RENSSELAER

IBM

IBM_BRUSSELS

IBM

IBM_STRASBOURG

IBM

IBM_FEZ

IBM

IBM_LEAST_BUSY

Atos

MYQLM_PYLINALG

Atos

MYQLM_CLINALG

Atos

QLM_LINALG

Atos

QLM_MPS

Atos

QLM_MPO

Atos

QLM_NOISY_QPROC

AWS

BRAKET_LOCAL_SIMULATOR

AWS

BRAKET_SV1_SIMULATOR

AWS

BRAKET_DM1_SIMULATOR

AWS

BRAKET_TN1_SIMULATOR

AWS

IONQ_ARIA_1

AWS

IONQ_ARIA_2

AWS

IONQ_FORTE_1

AWS

QUERA_AQUILA

AWS

RIGETTI_ANKAA_2

AWS

IQM_GARNET

Google

CIRQ_LOCAL_SIMULATOR

Google

PROCESSOR_RAINBOW

Google

PROCESSOR_WEBER

Google

IONQ_SIMULATOR

Google

IONQ_QPU

Azure

IONQ_SIMULATOR

Azure

IONQ_QPU

Azure

IONQ_QPU_ARIA_1

Azure

IONQ_QPU_ARIA_2

Azure

QUANTINUUM_SIM_H1_1

Azure

QUANTINUUM_SIM_H1_1SC

Azure

QUANTINUUM_SIM_H1_1E

Azure

RIGETTI_SIM_QVM

Azure

RIGETTI_SIM_QPU_ANKAA_2

Azure

MICROSOFT_ESTIMATOR

class ATOSDevice(value)[source]

Bases: AvailableDevice

Enum regrouping all available devices provided by ATOS.

static from_str_remote(name)[source]

Returns the first remote ATOSDevice matching the given name.

Parameters

name (str) – A substring of the desired device’s name.

Raises

ValueError – If no device corresponding to the given name could be found.

Examples

>>> ATOSDevice.from_str_remote('NoisyQProc')
<ATOSDevice.QLM_NOISYQPROC: 6>
>>> ATOSDevice.from_str_remote('linalg')
<ATOSDevice.QLM_LINALG: 3>
>>> ATOSDevice.from_str_remote('Mps')
<ATOSDevice.QLM_MPS: 4>
MYQLM_CLINALG = 2
MYQLM_PYLINALG = 1
QLM_LINALG = 3
QLM_MPO = 5
QLM_MPS = 4
QLM_NOISYQPROC = 6
class AWSDevice(value)[source]

Bases: AvailableDevice

Enum regrouping all available devices provided by AWS.

static from_arn(arn)[source]

Returns the right AWSDevice from the arn given in parameter.

Parameters

arn (str) – The AWS arn identifying the AWSDevice.

Examples

>>> AWSDevice.from_arn('arn:aws:braket:us-east-1::device/qpu/ionq/Aria-1')
<AWSDevice.IONQ_ARIA_1: 'qpu/ionq/Aria-1'>
>>> AWSDevice.from_arn('arn:aws:braket:::device/quantum-simulator/amazon/sv1')
<AWSDevice.BRAKET_SV1_SIMULATOR: 'quantum-simulator/amazon/sv1'>
get_arn()[source]

Retrieve the AWSDevice arn from this AWSDevice element.

Returns

The arn of the device.

Return type

str

Examples

>>> AWSDevice.IONQ_ARIA_1.get_arn()
'arn:aws:braket:us-east-1::device/qpu/ionq/Aria-1'
>>> AWSDevice.BRAKET_SV1_SIMULATOR.get_arn()
'arn:aws:braket:::device/quantum-simulator/amazon/sv1'
>>> AWSDevice.RIGETTI_ANKAA_2.get_arn()
'arn:aws:braket:us-west-1::device/qpu/rigetti/Ankaa-2'
get_region()[source]

Retrieve the AWS region from this AWSDevice element.

Returns

The region of the device.

Return type

str

Examples

>>> AWSDevice.IONQ_ARIA_1.get_region()
'us-east-1'
>>> AWSDevice.BRAKET_SV1_SIMULATOR.get_region() == get_env_variable("AWS_DEFAULT_REGION")
True
>>> AWSDevice.RIGETTI_ANKAA_2.get_region()
'us-west-1'
BRAKET_DM1_SIMULATOR = 'quantum-simulator/amazon/dm1'
BRAKET_LOCAL_SIMULATOR = 'LocalSimulator'
BRAKET_SV1_SIMULATOR = 'quantum-simulator/amazon/sv1'
BRAKET_TN1_SIMULATOR = 'quantum-simulator/amazon/tn1'
IONQ_ARIA_1 = 'qpu/ionq/Aria-1'
IONQ_ARIA_2 = 'qpu/ionq/Aria-2'
IONQ_FORTE_1 = 'qpu/ionq/Forte-1'
IQM_GARNET = 'qpu/iqm/Garnet'
QUERA_AQUILA = 'qpu/quera/Aquila'
RIGETTI_ANKAA_2 = 'qpu/rigetti/Ankaa-2'
class AZUREDevice(value)[source]

Bases: AvailableDevice

Enum regrouping all available devices provided by Azure.

is_ionq()[source]
IONQ_QPU = 'ionq.qpu'
IONQ_QPU_ARIA_1 = 'ionq.qpu.aria-1'
IONQ_QPU_ARIA_2 = 'ionq.qpu.aria-2'
IONQ_SIMULATOR = 'ionq.simulator'
MICROSOFT_ESTIMATOR = 'microsoft.estimator'
QUANTINUUM_SIM_H1_1 = 'quantinuum.qpu.h1-1'
QUANTINUUM_SIM_H1_1E = 'quantinuum.sim.h1-1e'
QUANTINUUM_SIM_H1_1SC = 'quantinuum.sim.h1-1sc'
RIGETTI_SIM_QPU_ANKAA_2 = 'rigetti.qpu.ankaa-2'
RIGETTI_SIM_QVM = 'rigetti.sim.qvm'
class AvailableDevice(value)[source]

Bases: Enum

Class used to define a generic device (quantum computer or simulator).

has_reduced_gate_set()[source]

Indicates whether a simulator does not handle all the native gates.

Returns

True if this device only handles a restricted set of gates.

Return type

bool

abstract is_gate_based()[source]

Indicates whether a device is gate-based or not.

Returns

True if this device is a gate-based simulator/QPU.

Return type

bool

abstract is_noisy_simulator()[source]

Indicates whether a device can simulate noise or not.

Returns

True if this device can simulate noise.

Return type

bool

abstract is_remote()[source]

Indicates whether a device is remote or not.

Returns

True if this device is remote.

Return type

bool

abstract is_simulator()[source]

Indicates whether a device is a simulator or not.

Returns

True if this device is a simulator.

Return type

bool

abstract supports_observable()[source]
Return type

bool

abstract supports_observable_ideal()[source]
Return type

bool

abstract supports_samples()[source]
Return type

bool

abstract supports_state_vector()[source]
Return type

bool

class GOOGLEDevice(value)[source]

Bases: AvailableDevice

Enum regrouping all available devices provided by Google.

is_ionq()[source]

True if the device is from IonQ.

is_processor()[source]

Check if the device is a processor.

Returns

True if the device is a processor, False otherwise.

Return type

bool

CIRQ_LOCAL_SIMULATOR = 'LocalSimulator'
IONQ_QPU = 'qpu'
IONQ_SIMULATOR = 'simulator'
PROCESSOR_RAINBOW = 'rainbow'
PROCESSOR_WEBER = 'weber'
class IBMDevice(value)[source]

Bases: AvailableDevice

Enum regrouping all available devices provided by IBM Quantum.

Warning

Since previous versions, many devices have been disabled by IBM. This may affect your code. We are currently investigating this issue to check if a workaround is possible for some of them (like replacing a simulator by an equivalent one for instance).

AER_SIMULATOR = 'automatic'
AER_SIMULATOR_DENSITY_MATRIX = 'density_matrix'
AER_SIMULATOR_EXTENDED_STABILIZER = 'extended_stabilizer'
AER_SIMULATOR_MATRIX_PRODUCT_STATE = 'matrix_product_state'
AER_SIMULATOR_STABILIZER = 'stabilizer'
AER_SIMULATOR_STATEVECTOR = 'statevector'
IBM_BRISBANE = 'ibm_brisbane'
IBM_BRUSSELS = 'ibm_brussels'
IBM_CLEVELAND = 'ibm_cleveland'
IBM_FEZ = 'ibm_fez'
IBM_KAWASAKI = 'ibm_kawasaki'
IBM_KYIV = 'ibm_kyiv'
IBM_LEAST_BUSY = 'ibm_least_busy'
IBM_NAZCA = 'ibm_nazca'
IBM_PEEKSKILL = 'ibm_peekskill'
IBM_QUEBEC = 'ibm_quebec'
IBM_RENSSELAER = 'ibm_rensselaer'
IBM_SHERBROOKE = 'ibm_sherbrooke'
IBM_STRASBOURG = 'ibm_strasbourg'
IBM_TORINO = 'ibm_torino'

Simulated Devices

To execute a circuit on a noisy simulator that reproduces the noise model of a machine, one can use a SimulatedDevice. Inheriting from AvailableDevice, it is the mother class of all noisy devices reproducing real hardware for several providers.

For the moment, only IBM simulated devices are available (so called \(FakeBackend\)), but the structure is ready to allow other simulated devices (QLM has this feature for instance.

class IBMSimulatedDevice(value)

Bases: StaticIBMSimulatedDevice

Enum regrouping all so called IBM “fake devices” used to simulate noise of real hardware.

The members of this Enum are generated dynamically from qiskit_ibm_runtime.fake_provider.

FakeAlgiers = <class 'qiskit_ibm_runtime.fake_provider.backends.algiers.fake_algiers.FakeAlgiers'>
Return type

None

FakeAlmadenV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.almaden.fake_almaden.FakeAlmadenV2'>
Return type

None

FakeArmonkV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.armonk.fake_armonk.FakeArmonkV2'>
Return type

None

FakeAthensV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.athens.fake_athens.FakeAthensV2'>
Return type

None

FakeAuckland = <class 'qiskit_ibm_runtime.fake_provider.backends.auckland.fake_auckland.FakeAuckland'>
Return type

None

FakeBelemV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.belem.fake_belem.FakeBelemV2'>
Return type

None

FakeBoeblingenV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.boeblingen.fake_boeblingen.FakeBoeblingenV2'>
Return type

None

FakeBogotaV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.bogota.fake_bogota.FakeBogotaV2'>
Return type

None

FakeBrisbane = <class 'qiskit_ibm_runtime.fake_provider.backends.brisbane.fake_brisbane.FakeBrisbane'>
Return type

None

FakeBrooklynV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.brooklyn.fake_brooklyn.FakeBrooklynV2'>
Return type

None

FakeBurlingtonV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.burlington.fake_burlington.FakeBurlingtonV2'>
Return type

None

FakeCambridgeV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.cambridge.fake_cambridge.FakeCambridgeV2'>
Return type

None

FakeCasablancaV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.casablanca.fake_casablanca.FakeCasablancaV2'>
Return type

None

FakeCusco = <class 'qiskit_ibm_runtime.fake_provider.backends.cusco.fake_cusco.FakeCusco'>
Return type

None

FakeEssexV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.essex.fake_essex.FakeEssexV2'>
Return type

None

FakeGeneva = <class 'qiskit_ibm_runtime.fake_provider.backends.geneva.fake_geneva.FakeGeneva'>
Return type

None

FakeGuadalupeV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.guadalupe.fake_guadalupe.FakeGuadalupeV2'>
Return type

None

FakeHanoiV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.hanoi.fake_hanoi.FakeHanoiV2'>
Return type

None

FakeJakartaV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.jakarta.fake_jakarta.FakeJakartaV2'>
Return type

None

FakeJohannesburgV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.johannesburg.fake_johannesburg.FakeJohannesburgV2'>
Return type

None

FakeKawasaki = <class 'qiskit_ibm_runtime.fake_provider.backends.kawasaki.fake_kawasaki.FakeKawasaki'>
Return type

None

FakeKolkataV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.kolkata.fake_kolkata.FakeKolkataV2'>
Return type

None

FakeKyiv = <class 'qiskit_ibm_runtime.fake_provider.backends.kyiv.fake_kyiv.FakeKyiv'>
Return type

None

FakeKyoto = <class 'qiskit_ibm_runtime.fake_provider.backends.kyoto.fake_kyoto.FakeKyoto'>
Return type

None

FakeLagosV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.lagos.fake_lagos.FakeLagosV2'>
Return type

None

FakeLimaV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.lima.fake_lima.FakeLimaV2'>
Return type

None

FakeLondonV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.london.fake_london.FakeLondonV2'>
Return type

None

FakeManhattanV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.manhattan.fake_manhattan.FakeManhattanV2'>
Return type

None

FakeManilaV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.manila.fake_manila.FakeManilaV2'>
Return type

None

FakeMelbourneV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.melbourne.fake_melbourne.FakeMelbourneV2'>
Return type

None

FakeMontrealV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.montreal.fake_montreal.FakeMontrealV2'>
Return type

None

FakeMumbaiV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.mumbai.fake_mumbai.FakeMumbaiV2'>
Return type

None

FakeNairobiV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.nairobi.fake_nairobi.FakeNairobiV2'>
Return type

None

FakeOsaka = <class 'qiskit_ibm_runtime.fake_provider.backends.osaka.fake_osaka.FakeOsaka'>
Return type

None

FakeOslo = <class 'qiskit_ibm_runtime.fake_provider.backends.oslo.fake_oslo.FakeOslo'>
Return type

None

FakeOurenseV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.ourense.fake_ourense.FakeOurenseV2'>
Return type

None

FakeParisV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.paris.fake_paris.FakeParisV2'>
Return type

None

FakePeekskill = <class 'qiskit_ibm_runtime.fake_provider.backends.peekskill.fake_peekskill.FakePeekskill'>
Return type

None

FakePerth = <class 'qiskit_ibm_runtime.fake_provider.backends.perth.fake_perth.FakePerth'>
Return type

None

FakePoughkeepsieV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.poughkeepsie.fake_poughkeepsie.FakePoughkeepsieV2'>
Return type

None

FakePrague = <class 'qiskit_ibm_runtime.fake_provider.backends.prague.fake_prague.FakePrague'>
Return type

None

FakeQuebec = <class 'qiskit_ibm_runtime.fake_provider.backends.quebec.fake_quebec.FakeQuebec'>
Return type

None

FakeQuitoV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.quito.fake_quito.FakeQuitoV2'>
Return type

None

FakeRochesterV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.rochester.fake_rochester.FakeRochesterV2'>
Return type

None

FakeRomeV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.rome.fake_rome.FakeRomeV2'>
Return type

None

FakeSantiagoV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.santiago.fake_santiago.FakeSantiagoV2'>
Return type

None

FakeSherbrooke = <class 'qiskit_ibm_runtime.fake_provider.backends.sherbrooke.fake_sherbrooke.FakeSherbrooke'>
Return type

None

FakeSingaporeV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.singapore.fake_singapore.FakeSingaporeV2'>
Return type

None

FakeSydneyV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.sydney.fake_sydney.FakeSydneyV2'>
Return type

None

FakeTorino = <class 'qiskit_ibm_runtime.fake_provider.backends.torino.fake_torino.FakeTorino'>
Return type

None

FakeTorontoV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.toronto.fake_toronto.FakeTorontoV2'>
Return type

None

FakeValenciaV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.valencia.fake_valencia.FakeValenciaV2'>
Return type

None

FakeVigoV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.vigo.fake_vigo.FakeVigoV2'>
Return type

None

FakeWashingtonV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.washington.fake_washington.FakeWashingtonV2'>
Return type

None

FakeYorktownV2 = <class 'qiskit_ibm_runtime.fake_provider.backends.yorktown.fake_yorktown.FakeYorktownV2'>
Return type

None

class SimulatedDevice(value)[source]

Bases: AvailableDevice

A class used to define simulators reproducing the noise of a real device. It implements the abstract methods of AvailableDevice, and is used as a blueprint for all possible simulated devices (IBM, QLM, …).

class StaticIBMSimulatedDevice(value)[source]

Bases: SimulatedDevice

A class regrouping methods specific to an IBMSimulatedDevice.

static get_ibm_fake_providers()[source]
Return type

list[tuple[str, type[‘FakeBackendV2’]]]

supports_observable()[source]
Return type

bool

supports_observable_ideal()[source]
Return type

bool

supports_samples()[source]
Return type

bool

supports_state_vector()[source]
to_noise_model()[source]

Generates the qiskit NoiseModel corresponding to this IBM fake device.

Return type

Qiskit_NoiseModel

to_noisy_simulator()[source]

Instantiates and returns an AerSimulator (from qiskit_aer) with the noise model corresponding to this IBM fake device.

Return type

AerSimulator

Running a circuit

Once the circuit is defined, you can execute it and retrieve the result using the function run(). You can execute said circuit on one or several devices (local or remote). The function will wait (blocking) until the job is completed and will return a Result if only one device was given or a BatchResult otherwise (see the section Results for more details).

Alternatively, when running jobs on a remote device, you might prefer to retrieve the result asynchronously, without having to wait and block the application until the computation is completed. In that case, you can use the submit() instead. This will submit the job and return the corresponding job id and Job object.

Note

Unlike run(), we can only submit on one device at a time.

adjust_measure(measure, circuit)[source]

We allow the measure to not span the entire circuit, but providers usually do not support this behavior. To make this work, we tweak the measure this function to match the expected behavior.

In order to do this, we add identity measures on the qubits not targeted by the measure. In addition to this, some swaps are automatically added so the the qubits measured are ordered and contiguous (though this is done in generate_job())

Parameters
  • measure (ExpectationMeasure) – The expectation measure, potentially incomplete.

  • circuit (QCircuit) – The circuit to which will be added the potential swaps allowing the user to get the expectation value of the qubits in an arbitrary order (this part is not handled by this function).

Returns

The measure padded with identities before and after.

display_kth_breakpoint(circuit, k, device=ATOSDevice.MYQLM_CLINALG)[source]

Prints to the standard output the state vector corresponding to the state of the system when it encounters the \(k^{th}\) breakpoint.

See the documentation of Breakpoint for examples of breakpoints.

Parameters
  • circuit (QCircuit) – The circuit to be examined.

  • k (int) – The state desired is met at the \(k^{th}\) breakpoint.

  • device (AvailableDevice) – The device to use for the simulation.

generate_job(circuit, device, values={})[source]

Creates the Job of appropriate type and containing the information needed for the execution of the circuit.

If the circuit contains symbolic variables (see section Variational Quantum Algorithms for more information), the values parameter is used to perform the necessary substitutions.

Parameters
  • circuit (QCircuit) – Circuit to be run.

  • device (AvailableDevice) – Device on which the circuit will be run.

  • values (dict[sympy.core.expr.Expr | str, numbers.Complex]) – Set of values to substitute for symbolic variables.

Returns

The Job containing information about the execution of the circuit.

Return type

Job

run(circuit, device, values=None, display_breakpoints=True)[source]

Runs the circuit on the backend, or list of backend, provided in parameter.

If the circuit contains symbolic variables (see section Variational Quantum Algorithms for more information on them), the values parameter is used perform the necessary substitutions.

Parameters
  • circuit (Union[QCircuit, Sequence[QCircuit]]) – Circuit, or list of circuits, to be run.

  • device (Union[AvailableDevice, Sequence[AvailableDevice]]) – Device, or list of devices, on which the circuit will be run.

  • values (Optional[dict[sympy.core.expr.Expr | str, numbers.Complex]]) – Set of values to substitute symbolic variables. Defaults to {}.

  • display_breakpoints (bool) – If False, breakpoints will be disabled. Each breakpoint adds an execution of the circuit(s), so you may use this option for performance if need be.

Returns

The Result containing information about the measurement required.

Return type

mpqp.execution.result.Result | mpqp.execution.result.BatchResult

Examples

>>> c = QCircuit(
...     [X(0), CNOT(0, 1), BasisMeasure([0, 1], shots=1000)],
...     label="X CNOT circuit",
... )
>>> result = run(c, IBMDevice.AER_SIMULATOR)
>>> print(result)
Result: X CNOT circuit, IBMDevice, AER_SIMULATOR
 Counts: [0, 0, 0, 1000]
 Probabilities: [0, 0, 0, 1]
 Samples:
  State: 11, Index: 3, Count: 1000, Probability: 1
 Error: None
>>> batch_result = run(
...     c,
...     [ATOSDevice.MYQLM_PYLINALG, AWSDevice.BRAKET_LOCAL_SIMULATOR]
... )
>>> print(batch_result)
BatchResult: 2 results
Result: X CNOT circuit, ATOSDevice, MYQLM_PYLINALG
 Counts: [0, 0, 0, 1000]
 Probabilities: [0, 0, 0, 1]
 Samples:
  State: 11, Index: 3, Count: 1000, Probability: 1
 Error: 0.0
Result: X CNOT circuit, AWSDevice, BRAKET_LOCAL_SIMULATOR
 Counts: [0, 0, 0, 1000]
 Probabilities: [0, 0, 0, 1]
 Samples:
  State: 11, Index: 3, Count: 1000, Probability: 1
 Error: None
>>> c2 = QCircuit(
...     [X(0), X(1), BasisMeasure([0, 1], shots=1000)],
...     label="X circuit",
... )
>>> result = run([c,c2], IBMDevice.AER_SIMULATOR)
>>> print(result)
BatchResult: 2 results
Result: X CNOT circuit, IBMDevice, AER_SIMULATOR
 Counts: [0, 0, 0, 1000]
 Probabilities: [0, 0, 0, 1]
 Samples:
  State: 11, Index: 3, Count: 1000, Probability: 1
 Error: None
Result: X circuit, IBMDevice, AER_SIMULATOR
 Counts: [0, 0, 0, 1000]
 Probabilities: [0, 0, 0, 1]
 Samples:
  State: 11, Index: 3, Count: 1000, Probability: 1
 Error: None
submit(circuit, device, values=None)[source]

Submit the job related to the circuit on the remote backend provided in parameter. The submission returns a job_id that can be used to retrieve the Result later using the get_remote_result() function.

If the circuit contains symbolic variables (see section Variational Quantum Algorithms for more information), the values parameter is used perform the necessary substitutions.

Note that this function only supports single device submissions.

Parameters
  • circuit (QCircuit) – QCircuit to be run.

  • device (AvailableDevice) – Remote device to which the circuit will be submitted.

  • values (Optional[dict[sympy.core.expr.Expr | str, numbers.Complex]]) – Values to substitute for symbolic variables. Defaults to {}.

Returns

The job id provided by the remote device after submission of the job.

Return type

tuple[str, mpqp.execution.job.Job]

Example

>>> circuit = QCircuit([H(0), CNOT(0,1), BasisMeasure([0,1], shots=10)])
>>> job_id, job = submit(circuit, ATOSDevice.QLM_LINALG) 
Logging as user <qlm_user>...
Submitted a new batch: Job766
>>> print(f"Status of {job_id}: {job.job_status}") 
Status of Job766: JobStatus.RUNNING

Note

Unlike run(), you can only submit on one device at a time.

Helpers for remote jobs

After the jobs are submitted, one can use the functions of this module to retrieve the results from a job_id or the job directly, and list all job attached to the configured accounts.

get_all_job_ids()[source]

Retrieve from the remote providers all the job-ids associated with this account.

Returns

A dictionary of job-ids indexed by the correspond AvailableDevice (ATOSDevice, AWSDevice, IBMDevice, …).

Return type

dict[type[AvailableDevice], list[str]]

get_remote_result(job_data, device=None)[source]

Retrieve and parse a remote the result from a job_id and device. If the job is still running, it will wait until it is done.

Parameters
  • job_data (str | mpqp.execution.job.Job) – Either the Job object or the job id used to identify the job on the remote device.

  • device (Optional[AvailableDevice]) – Remote device on which the job was launched, needed only if job_data is the identifier of the job.

Returns

The Result of the desired remote job.

Return type

Result

Examples

>>> print(get_remote_result('Job141933', ATOSDevice.QLM_LINALG))
Result: ATOSDevice, QLM_LINALG
 Counts: [1017, 0, 0, 0, 983, 0, 0, 0]
 Probabilities: [0.5085 0.     0.     0.     0.4915 0.     0.     0.    ]
  State: 000, Index: 0, Count: 1017, Probability: 0.5085
  State: 100, Index: 4, Count: 983, Probability: 0.4915
 Error: 0.011181519941139355
>>> print(get_remote_result(
...     'cm80pb1054sir2ck9i3g',
...     IBMDevice.IBMQ_QASM_SIMULATOR,
... ))
Result: IBMDevice, IBMQ_QASM_SIMULATOR
 Expectation value: 1.6410799999999999
 Error/Variance: 1.24570724535
>>> aws_task_id = (
...     'arn:aws:braket:us-east-1:752542621531:quantum-task/'
...     '6a46ae9a-d02f-4a23-b46f-eae43471bc22'
... )
>>> print(get_remote_result(
...     aws_task_id,
...     AWSDevice.BRAKET_SV1_SIMULATOR,
... ))
Result: AWSDevice, BRAKET_SV1_SIMULATOR
 Expectation value: 1.6635202030411578
 Error/Variance: None
>>> circ = QCircuit([H(0), CNOT(0,1)])
>>> _, job = submit(circ, ATOSDevice.QLM_LINALG)
>>> print(get_remote_result(job))
Result: ATOSDevice, QLM_LINALG
 State vector: [0.7071068, 0, 0, 0.7071068]
 Probabilities: [0.5, 0, 0, 0.5]
 Number of qubits: 2

Jobs

When you call run() or submit(), a Job is created by generate_job(). This job contains all the needed information to configure the execution, and eventually retrieve remote results.

A Job can be of three types, given by the JobType enum. In addition, it has a status, given by the JobStatus enum.

As described above, a Job is generated on circuit submission so you would in principle never need to instantiate one yourself.

class Job(job_type, circuit, device, measure=None)[source]

Bases: object

Representation of a job, an object regrouping all the information about the submission of a computation/measure of a quantum circuit on a specific hardware.

A job has a type, and a status, and is attached to a specific device. Moreover, the job contains also the quantum circuit and the measure to be performed on the circuit.

Parameters
  • job_type (JobType) – Type of the job (sample, observable, …).

  • circuit (QCircuit) – Circuit to execute. In addition of what the user input, this circuit may contain additional parts such as measure adjustment sections.

  • device (AvailableDevice) – Device (simulator, quantum computer) on which we want to execute the job.

  • measure (Optional[Measure]) – Object representing the measure to perform.

Examples

>>> circuit = QCircuit(3)
>>> job = Job(JobType.STATE_VECTOR, circuit, IBMDevice.AER_SIMULATOR)
>>> circuit.add(BasisMeasure([0, 1], shots=1000))
>>> job2 = Job(
...     JobType.STATE_VECTOR,
...     circuit,
...     IBMDevice.AER_SIMULATOR,
...     circuit.measurements[0],
... )
circuit

See parameter description.

device

See parameter description.

id: Optional[str]

Contains the id of the remote job, used to retrieve the result from the remote provider. None if the job is local. It can take a little while before it is set to the right value (For instance, a job submission can require handshake protocols to conclude before attributing an id to the job).

job_type

See parameter description.

measure

See parameter description.

property status

Update and return the current job status. Mainly relevant for remote jobs.

class JobStatus(value=<no_arg>, names=None, module=None, qualname=None, type=None, start=1, boundary=None)[source]

Bases: MessageEnum

Possible states of a Job.

CANCELLED = 4

The job is cancelled.

DONE = 6

The job is successfully done.

ERROR = 5

An error occurred with the job.

INIT = 1

Initializing the job.

QUEUED = 2

The job is in the queue.

RUNNING = 3

The job is currently running.

class JobType(value=<no_arg>, names=None, module=None, qualname=None, type=None, start=1, boundary=None)[source]

Bases: Enum

Possible types of Job to execute.

Each type of job is restricted to some measures (and to some backends, but this is tackled by the backends themselves).

OBSERVABLE = {ExpectationMeasure}

Computes the expectation value of an observable, using the state_vector or the samples. This type is ideal too: it requires some trickery to retrieve the expectation value in an optimal manner.

SAMPLE = {BasisMeasure}

Measures several times the quantum state in the basis, and retrieve the counts. Contrarily to the STATE_VECTOR job type, this one is realistic.

STATE_VECTOR = {BasisMeasure, <class 'NoneType'>}

Retrieves the vector representing the quantum state, this type is ideal.

get_aws_job_status(job_id)[source]

Retrieves the status of a AWS Braket from the id in parameter, and returns the corresponding JobStatus of this library.

Parameters

job_id (str) – Id of the job for which we want to retrieve the status.

Return type

JobStatus

get_azure_job_status(job_id)[source]

Retrieves the status of a azure from the id in parameter, and returns the corresponding JobStatus of this library.

Parameters

job_id (str) – Id of the job for which we want to retrieve the status.

Return type

JobStatus

get_ibm_job_status(job_id)[source]

Retrieves the status of an IBM job from the id in parameter, and returns the corresponding JobStatus of this library.

Parameters

job_id (str) – Id of the job for which we want to retrieve the status.

Return type

JobStatus

get_qlm_job_status(job_id)[source]

Retrieves the status of a QLM job from the id in parameter, and returns the corresponding JobStatus of this library.

Parameters

job_id (str) – Id of the job for which we want to retrieve the status.

Return type

JobStatus

Results

Once the computation ended, the Result contains all the data from the execution.

The job type affects the data contained in the Result. For a given result, here are how to retrieve the data depending on the job type:

  • for a job type STATE_VECTOR you can retrieve the StateVector from result.state_vector. If you want to directly get the amplitudes of your state vector, you can reach for result.amplitudes;

  • for a job type SAMPLE you can retrieve the list of Sample from result.samples. For a SAMPLE job type, you might be interested in results packed in a different shape than a list of Sample, even though you could rebuild them from said list, we also provide a few shorthands like result.probabilities and result.counts;

  • for a job type OBSERVABLE you can retrieve the expectation value (a float) from result.expectation_value.

When several devices are given to run(), the results are stored in a BatchResult.

class BatchResult(results)[source]

Bases: object

Class used to handle several Result instances.

Parameters

results (list[Result]) – List of results.

Example

>>> result1 = Result(
...     Job(JobType.STATE_VECTOR,QCircuit(0, label="StateVector circuit"),
...     ATOSDevice.MYQLM_PYLINALG),
...     StateVector(np.array([1, 1, 1, -1])/2, 2),
...     0,
...     0
... )
>>> result2 = Result(
...     Job(
...         JobType.SAMPLE,
...         QCircuit([BasisMeasure([0,1],shots=500)], label="Sample circuit"),
...         ATOSDevice.MYQLM_PYLINALG,
...         BasisMeasure([0,1],shots=500)
...     ),
...     [Sample(2, index=0, count=250), Sample(2, index=3, count=250)],
...     0.034,
...     500)
>>> result3 = Result(
...     Job(JobType.OBSERVABLE,QCircuit(0, label="Observable circuit"),
...     ATOSDevice.MYQLM_PYLINALG),
...     -3.09834,
...     0.021,
...     2048
... )
>>> batch_result = BatchResult([result1, result2, result3])
>>> print(batch_result)
BatchResult: 3 results
Result: StateVector circuit, ATOSDevice, MYQLM_PYLINALG
 State vector: [0.5, 0.5, 0.5, -0.5]
 Probabilities: [0.25, 0.25, 0.25, 0.25]
 Number of qubits: 2
Result: Sample circuit, ATOSDevice, MYQLM_PYLINALG
 Counts: [250, 0, 0, 250]
 Probabilities: [0.5, 0, 0, 0.5]
 Samples:
  State: 00, Index: 0, Count: 250, Probability: 0.5
  State: 11, Index: 3, Count: 250, Probability: 0.5
 Error: 0.034
Result: Observable circuit, ATOSDevice, MYQLM_PYLINALG
 Expectation value: -3.09834
 Error/Variance: 0.021
>>> print(batch_result[0])
Result: StateVector circuit, ATOSDevice, MYQLM_PYLINALG
 State vector: [0.5, 0.5, 0.5, -0.5]
 Probabilities: [0.25, 0.25, 0.25, 0.25]
 Number of qubits: 2
plot(show=True)[source]

Display the result(s) using matplotlib.pyplot.

The result(s) must be from a job who’s job_type is SAMPLE. They will be displayed as histograms.

If a BatchResult is given, the contained results will be displayed in a grid using subplots.

Parameters

show (bool) – plt.show() is only executed if show, useful to batch plots.

results

See parameter description.

class Result(job, data, errors=None, shots=0)[source]

Bases: object

Result associated to a submitted job.

The data type in a result depends on the job type, according to the following chart:

Job Type

Data Type

OBSERVABLE

float

SAMPLE

list[Sample]

STATE_VECTOR

StateVector

Parameters
  • job (Job) – Type of the job related to this result.

  • data (float | StateVector | list[Sample]) – Data of the result, can be an expectation value (float), a StateVector, or a list of sample depending on the job_type.

  • errors (Optional[float | dict[PauliString, float] | dict[Any, Any]]) – Information about the error or the variance in the measurement.

  • shots (int) – Number of shots of the experiment (equal to zero if the exact value was required).

Examples

>>> job = Job(JobType.STATE_VECTOR, QCircuit(2), ATOSDevice.MYQLM_CLINALG)
>>> print(Result(job, StateVector(np.array([1, 1, 1, -1], dtype=np.complex64) / 2, 2), 0, 0)) 
Result: ATOSDevice, MYQLM_CLINALG
 State vector: [0.5, 0.5, 0.5, -0.5]
 Probabilities: [0.25, 0.25, 0.25, 0.25]
 Number of qubits: 2
>>> job = Job(
...     JobType.SAMPLE,
...     QCircuit([BasisMeasure([0, 1], shots=1000)]),
...     ATOSDevice.MYQLM_CLINALG,
...     BasisMeasure([0, 1], shots=1000),
... )
>>> print(Result(job, [
...     Sample(2, index=0, count=250),
...     Sample(2, index=3, count=250)
... ], 0.034, 500)) 
Result: ATOSDevice, MYQLM_CLINALG
 Counts: [250, 0, 0, 250]
 Probabilities: [0.5, 0, 0, 0.5]
 Samples:
  State: 00, Index: 0, Count: 250, Probability: 0.5
  State: 11, Index: 3, Count: 250, Probability: 0.5
 Error: 0.034
>>> job = Job(JobType.OBSERVABLE, QCircuit(2), ATOSDevice.MYQLM_CLINALG)
>>> print(Result(job, -3.09834, 0.021, 2048)) 
Result: ATOSDevice, MYQLM_CLINALG
 Expectation value: -3.09834
 Error/Variance: 0.021
plot(show=True)[source]

Extract sampling info from the result and construct the bar diagram plot.

Parameters

show (bool) – plt.show() is only executed if show, useful to batch plots.

property amplitudes: npt.NDArray[np.complex64]

Get the amplitudes of the state of this result

property counts: list[int]

Get the list of counts for each sample of the experiment

property device: AvailableDevice

Device on which the job of this result was run

error

See parameter description.

property expectation_value: float

Get the expectation value stored in this result

job

See parameter description.

property probabilities: npt.NDArray[np.float32]

Get the list of probabilities associated with this result

property samples: list[mpqp.execution.result.Sample]

Get the list of samples of the result

shots

See parameter description.

property state_vector: StateVector

Get the state vector of the state associated with this result

class Sample(nb_qubits, probability=None, index=None, count=None, bin_str=None)[source]

Bases: object

A sample is a partial result of job job with type SAMPLE. It contains the count (and potentially the associated probability) for a given basis state, i.e. the number of times this basis state was measured.

Parameters
  • nb_qubits (int) – Number of qubits of the quantum system of the experiment.

  • probability (Optional[float]) – Probability of measuring the basis state associated to this sample.

  • index (Optional[int]) – Index in decimal notation representing the basis state.

  • count (Optional[int]) – Number of times this basis state was measured during the experiment.

  • bin_str (Optional[str]) – String representing the basis state in binary notation.

Examples

>>> print(Sample(3, index=3, count=250, bin_str="011"))
State: 011, Index: 3, Count: 250, Probability: None
>>> print(Sample(4, index=6, probability=0.5))
State: 0110, Index: 6, Count: None, Probability: 0.5
>>> print(Sample(5, bin_str="01011", count=1234))
State: 01011, Index: 11, Count: 1234, Probability: None
bin_str: str

See parameter description.

count

See parameter description.

index: int

See parameter description.

nb_qubits

See parameter description.

probability

See parameter description.

class StateVector(vector, nb_qubits=None, probabilities=None)[source]

Bases: object

Class representing the state vector of a multi-qubit quantum system.

Parameters
  • vector (list[Complex] | npt.NDArray[np.complex64]) – List of amplitudes defining the state vector.

  • nb_qubits (Optional[int]) – Number of qubits of the state.

  • probabilities (Optional[list[float] | npt.NDArray[np.float32]]) – List of probabilities associated with the state vector.

Example

>>> state_vector = StateVector(np.array([1, 1, 1, -1])/2, 2)
>>> state_vector.probabilities
array([0.25, 0.25, 0.25, 0.25])
>>> print(state_vector)
 State vector: [0.5, 0.5, 0.5, -0.5]
 Probabilities: [0.25, 0.25, 0.25, 0.25]
 Number of qubits: 2
property amplitudes

Return the amplitudes of the state vector

nb_qubits

See parameter description.

probabilities

See parameter description.