This page was generated from the notebook examples/notebooks/2_Execution_Bell_circuit.ipynb.

Execution of the Bell circuit

The “Hello World!” of Quantum Computing is the generation of the 2-qubit Bell state.

Creating the EPR/Bell state

Let us start with the circuit:

[1]:
from mpqp import QCircuit
from mpqp.gates import H, CNOT
[2]:
circuit = QCircuit([H(0), CNOT(0,1)], label="Bell state")
print(circuit)
     ┌───┐
q_0: ┤ H ├──■──
     └───┘┌─┴─┐
q_1: ─────┤ X ├
          └───┘

Run the circuit on a local device

We can execute a circuit on a local simulator by calling the function run and precising the device.

[3]:
from mpqp.execution import run, ATOSDevice

When no measure is added to the circuit, running the circuit will consist in extracting the state-vector at the output of the circuit.

⚠ This feature is not supported on all backends

[4]:
result = run(circuit, ATOSDevice.MYQLM_PYLINALG)
print(result)
print(result.amplitudes)
print(result.probabilities)
Result: ATOSDevice, MYQLM_PYLINALG
 State vector: [0.7071068, 0, 0, 0.7071068]
 Probabilities: [0.5, 0, 0, 0.5]
 Number of qubits: 2

[0.70710677+0.j 0.        +0.j 0.        +0.j 0.70710677+0.j]
[0.5 0.  0.  0.5]

We can also add to the circuit a BasisMeasure, consisting in sample the state in a given basis. By default, the basis is the computational one.

[5]:
from mpqp.measures import BasisMeasure

We precise which qubits we can to measure by inputting a list of indices, and precising the number of shots. When shots=0, we end up in the same case as before, a statevector simulation.

[6]:
circuit.add(BasisMeasure([0,1], shots=0))
result = run(circuit, ATOSDevice.MYQLM_PYLINALG)
print(result)
Result: ATOSDevice, MYQLM_PYLINALG
 State vector: [0.7071068, 0, 0, 0.7071068]
 Probabilities: [0.5, 0, 0, 0.5]
 Number of qubits: 2

When we precise a number of shots, the circuit will be sampled and the core of the Result will be a list of Sample. A precising the counts for each state of the basis.

[7]:
circuit = circuit.without_measurements()
circuit.add(BasisMeasure([0,1], shots=1024))
[8]:
result = run(circuit, ATOSDevice.MYQLM_PYLINALG)
print(result)
print(result.samples)
print(result.counts)
print(result.probabilities)
Result: ATOSDevice, MYQLM_PYLINALG
 Counts: [505, 0, 0, 519]
 Probabilities: [0.4931641, 0, 0, 0.5068359]
 Samples:
  State: 00, Index: 0, Count: 505, Probability: 0.4931640625
  State: 11, Index: 3, Count: 519, Probability: 0.5068359375
 Error: 0.015631173891374292

[Sample(2, index=0, count=505, probability=0.4931640625), Sample(2, index=3, count=519, probability=0.5068359375)]
[505, 0, 0, 519]
[0.49316406 0.         0.         0.50683594]

Run the circuit on multiple devices

By using the same function run we can execute the circuit on several simulators at the time. One just has to give a list of devices instead of a single device.

[9]:
from mpqp.execution import IBMDevice, AWSDevice, GOOGLEDevice
[10]:
results = run(circuit, [ATOSDevice.MYQLM_PYLINALG, IBMDevice.AER_SIMULATOR, AWSDevice.BRAKET_LOCAL_SIMULATOR, GOOGLEDevice.CIRQ_LOCAL_SIMULATOR])
print(results)
print('---------')
print(results[0])
c:\Users\JulienCalisto\Documents\MPQP_main_repo\mpqp\.venv\lib\site-packages\mpqp\qasm\qasm_to_braket.py:80: UnsupportedBraketFeaturesWarning:
This program uses OpenQASM language features that may not be supported on QPUs or on-demand simulators.
  warnings.warn(

BatchResult: 4 results
Result: ATOSDevice, MYQLM_PYLINALG
 Counts: [480, 0, 0, 544]
 Probabilities: [0.46875, 0, 0, 0.53125]
 Samples:
  State: 00, Index: 0, Count: 480, Probability: 0.46875
  State: 11, Index: 3, Count: 544, Probability: 0.53125
 Error: 0.0156020726215454
Result: GOOGLEDevice, CIRQ_LOCAL_SIMULATOR
 Counts: [506, 0, 0, 518]
 Probabilities: [0.4941406, 0, 0, 0.5058594]
 Samples:
  State: 00, Index: 0, Count: 506, Probability: 0.494140625
  State: 11, Index: 3, Count: 518, Probability: 0.505859375
 Error: None
Result: AWSDevice, BRAKET_LOCAL_SIMULATOR
 Counts: [513, 0, 0, 511]
 Probabilities: [0.5009766, 0, 0, 0.4990234]
 Samples:
  State: 00, Index: 0, Count: 513, Probability: 0.5009765625
  State: 11, Index: 3, Count: 511, Probability: 0.4990234375
 Error: None
Result: IBMDevice, AER_SIMULATOR
 Counts: [530, 0, 0, 494]
 Probabilities: [0.5175781, 0, 0, 0.4824219]
 Samples:
  State: 00, Index: 0, Count: 530, Probability: 0.517578125
  State: 11, Index: 3, Count: 494, Probability: 0.482421875
 Error: None

---------
Result: ATOSDevice, MYQLM_PYLINALG
 Counts: [480, 0, 0, 544]
 Probabilities: [0.46875, 0, 0, 0.53125]
 Samples:
  State: 00, Index: 0, Count: 480, Probability: 0.46875
  State: 11, Index: 3, Count: 544, Probability: 0.53125
 Error: 0.0156020726215454

Run or submit the circuit on a remote device

To execute the circuit on remote device, one can use the exact same process as with local devices. A call of the function run on a remote device will launch the job and wait until it finished before returning the result. One or several devices can still be given in parameter.

[11]:
result = run(circuit, IBMDevice.AER_SIMULATOR)
print(result)
UserWarning: Cloud simulators have been deprecated and will be removed on 15 May 2024. Use the new local testing mode in qiskit-ibm-runtime version 0.22.0 or later to meet your debugging needs.
Result: IBMDevice, AER_SIMULATOR
 Counts: [500, 0, 0, 524]
 Probabilities: [0.48828125 0.         0.         0.51171875]
 Samples:
  State: 00, Index: 0, Count: 500, Probability: 0.48828125
  State: 11, Index: 3, Count: 524, Probability: 0.51171875
 Error: None

However, it is also possible to asynchronously submit the job way using the submit function.

[12]:
from mpqp.execution import submit

By submitting the circuit to a remote device, we retrieve the id of the job attributed by the provider, as well as the corresponding MPQP job.

The MPQP job object contains additional information, such as the status of the job.

[13]:
job_id, job = submit(circuit, IBMDevice.IBM_LEAST_BUSY)
print(job_id)
coogal6phvvei9s9j13g

Once the computation is done, we use the function get_remote_result for retrieving the result.

If the job is not completed, the function will wait (blocking) until it is done.

[14]:
from mpqp.execution import get_remote_result
[15]:
result = get_remote_result(job_id, IBMDevice.IBM_LEAST_BUSY)
print(result)
Result: IBMDevice, IBM_LEAST_BUSY
 Counts: [531, 0, 0, 493]
 Probabilities: [0.51855469 0.         0.         0.48144531]
 Samples:
  State: 00, Index: 0, Count: 531, Probability: 0.5185546875
  State: 11, Index: 3, Count: 493, Probability: 0.4814453125
 Error: None