Compiling and Submitting Circuits onto Sqorpius via Qiskit
Import Requirements
This tutorial will showcase how to compile and submit a circuit onto Infleqtion’s hardware, Sqorpius, using the qiskit-superstaq client.
[1]:
# Required imports
try:
import qiskit
import qiskit_superstaq as qss
except ImportError:
print("Installing qiskit-superstaq...")
%pip install --quiet 'qiskit-superstaq[examples]'
print("Installed qiskit-superstaq.")
print("You may need to restart the kernel to import newly installed packages.")
import qiskit
import qiskit_superstaq as qss
# Optional imports
import os # Used if setting a token as an environment variable
To interface Superstaq via Qiskit, we must first instantiate a service provider in qiskit-superstaq. We then supply a Superstaq API key (which you can get from https://superstaq.infleqtion.com) by either providing the API key as an argument, i.e., qss.superstaq_provider.SuperstaqProvider(api_key="token"), or by setting it as an environment variable (see more details
here).
[2]:
provider = qss.superstaq_provider.SuperstaqProvider()
Create a Circuit
First, we will create an example Qiskit circuit that we can then compile and submit onto Sqorpius
[3]:
circuit1 = qiskit.QuantumCircuit(1, 1)
circuit1.h(0)
circuit1.measure(0, 0)
circuit1.draw(fold=-1)
[3]:
┌───┐┌─┐
q: ┤ H ├┤M├
└───┘└╥┘
c: 1/══════╩═
0 Single Circuit Compilation
We will now compile the above circuit onto Sqorpius’s native gateset and visualize the differences by drawing the compiled circuit
[4]:
compiler_output = provider.cq_compile(circuit1)
[5]:
print(compiler_output.circuit)
┌───────────────────┐┌─┐
q_0: ┤0 ├┤M├
│ │└╥┘
q_1: ┤1 ├─╫─
│ │ ║
q_2: ┤2 ├─╫─
│ │ ║
q_3: ┤3 ├─╫─
│ │ ║
q_4: ┤4 ├─╫─
│ │ ║
q_5: ┤5 ├─╫─
│ │ ║
q_6: ┤6 ├─╫─
│ │ ║
q_7: ┤7 ├─╫─
│ │ ║
q_8: ┤8 ├─╫─
│ │ ║
q_9: ┤9 ├─╫─
│ │ ║
q_10: ┤10 ├─╫─
│ │ ║
q_11: ┤11 ├─╫─
│ GR(1.57, -1.57) │ ║
q_12: ┤12 ├─╫─
│ │ ║
q_13: ┤13 ├─╫─
│ │ ║
q_14: ┤14 ├─╫─
│ │ ║
q_15: ┤15 ├─╫─
│ │ ║
q_16: ┤16 ├─╫─
│ │ ║
q_17: ┤17 ├─╫─
│ │ ║
q_18: ┤18 ├─╫─
│ │ ║
q_19: ┤19 ├─╫─
│ │ ║
q_20: ┤20 ├─╫─
│ │ ║
q_21: ┤21 ├─╫─
│ │ ║
q_22: ┤22 ├─╫─
│ │ ║
q_23: ┤23 ├─╫─
└───────────────────┘ ║
c: 1/══════════════════════╩═
0
If you would like to compile (or submit) on a different number of qubits, this can be done via the grid_shape option. This simply sets the shape of the rectangular qubit grid. However, specifying a grid that is incompatible with Sqorpius’s current capabilities will result in an error when submitting.
[6]:
example_circuit = qiskit.QuantumCircuit(4, 1)
example_circuit.cx(0, 1)
example_circuit.cx(2, 3)
new_compiler_output = provider.cq_compile(example_circuit, grid_shape=(2, 2))
new_compiler_output.circuit.draw(fold=-1)
[6]:
┌──────────────────┐ ┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
q_0: ┤0 ├─────┤0 ├─■─┤0 ├─────┤0 ├
│ │┌───┐│ │ │ │ │┌───┐│ │
q_1: ┤1 ├┤ Z ├┤1 ├─■─┤1 ├┤ Z ├┤1 ├
│ GR(-0.79, 1.57) │└───┘│ GR(0.79, 1.57) │ │ GR(-0.79, 1.57) │└───┘│ GR(0.79, 1.57) │
q_2: ┤2 ├─────┤2 ├─■─┤2 ├─────┤2 ├
│ │┌───┐│ │ │ │ │┌───┐│ │
q_3: ┤3 ├┤ Z ├┤3 ├─■─┤3 ├┤ Z ├┤3 ├
└──────────────────┘└───┘└─────────────────┘ └──────────────────┘└───┘└─────────────────┘Single Circuit Submission
The code below will submitt he circuit to the noiseless Sqorpius simulator. If you would like to run on Sqorpius, change the target argument in backend from cq_sqorpius_simulator to cq_sqorpius_qpu. It is recommended to first submit to the simulator for testing to ensure your code runs before submitting to Sqorpius.
[7]:
backend = provider.get_backend("cq_sqorpius_simulator")
job = backend.run(circuit1, shots=100)
print(f"Counts from qiskit-superstaq submission: {job.result().get_counts()}")
Counts from qiskit-superstaq submission: {'1': 48, '0': 52}
If you would like to submit these circuits to a noisy simulator, you can specify via method = noise-sim in job.
[8]:
backend = provider.get_backend("cq_sqorpius_simulator")
job = backend.run(circuit1, shots=100, method="noise-sim")
print(f"Counts from noisy qiskit-superstaq submission: {job.result().get_counts()}")
Counts from noisy qiskit-superstaq submission: {'0': 58, '1': 42}
Multiple circuit compilation
All the functionalities we have seen so far can also be used on a multiple-circuit input as well. To illustrate this, let us create a different example two-qubit circuit, and compile both circuits we have created at the same time.
[9]:
circuit2 = qiskit.QuantumCircuit(2)
circuit2.cx(0, 1)
circuit2.h(1)
circuit2.draw(fold=-1)
[9]:
q_0: ──■───────
┌─┴─┐┌───┐
q_1: ┤ X ├┤ H ├
└───┘└───┘[10]:
compiler_output = provider.cq_compile([circuit1, circuit2])
[11]:
print(compiler_output.circuits[0])
┌───────────────────┐┌─┐
q_0: ┤0 ├┤M├
│ │└╥┘
q_1: ┤1 ├─╫─
│ │ ║
q_2: ┤2 ├─╫─
│ │ ║
q_3: ┤3 ├─╫─
│ │ ║
q_4: ┤4 ├─╫─
│ │ ║
q_5: ┤5 ├─╫─
│ │ ║
q_6: ┤6 ├─╫─
│ │ ║
q_7: ┤7 ├─╫─
│ │ ║
q_8: ┤8 ├─╫─
│ │ ║
q_9: ┤9 ├─╫─
│ │ ║
q_10: ┤10 ├─╫─
│ │ ║
q_11: ┤11 ├─╫─
│ GR(1.57, -1.57) │ ║
q_12: ┤12 ├─╫─
│ │ ║
q_13: ┤13 ├─╫─
│ │ ║
q_14: ┤14 ├─╫─
│ │ ║
q_15: ┤15 ├─╫─
│ │ ║
q_16: ┤16 ├─╫─
│ │ ║
q_17: ┤17 ├─╫─
│ │ ║
q_18: ┤18 ├─╫─
│ │ ║
q_19: ┤19 ├─╫─
│ │ ║
q_20: ┤20 ├─╫─
│ │ ║
q_21: ┤21 ├─╫─
│ │ ║
q_22: ┤22 ├─╫─
│ │ ║
q_23: ┤23 ├─╫─
└───────────────────┘ ║
c: 1/══════════════════════╩═
0
[12]:
print(compiler_output.circuits[1])
┌───────────────────┐ ┌──────────────────┐
q_0: ┤0 ├─────┤0 ├─■─
│ │┌───┐│ │ │
q_1: ┤1 ├┤ Z ├┤1 ├─■─
│ │└───┘│ │
q_2: ┤2 ├─────┤2 ├───
│ │ │ │
q_3: ┤3 ├─────┤3 ├───
│ │ │ │
q_4: ┤4 ├─────┤4 ├───
│ │ │ │
q_5: ┤5 ├─────┤5 ├───
│ │ │ │
q_6: ┤6 ├─────┤6 ├───
│ │ │ │
q_7: ┤7 ├─────┤7 ├───
│ │ │ │
q_8: ┤8 ├─────┤8 ├───
│ │ │ │
q_9: ┤9 ├─────┤9 ├───
│ │ │ │
q_10: ┤10 ├─────┤10 ├───
│ │ │ │
q_11: ┤11 ├─────┤11 ├───
│ GR(-0.79, 1.57) │ │ GR(0.79, 1.57) │
q_12: ┤12 ├─────┤12 ├───
│ │ │ │
q_13: ┤13 ├─────┤13 ├───
│ │ │ │
q_14: ┤14 ├─────┤14 ├───
│ │ │ │
q_15: ┤15 ├─────┤15 ├───
│ │ │ │
q_16: ┤16 ├─────┤16 ├───
│ │ │ │
q_17: ┤17 ├─────┤17 ├───
│ │ │ │
q_18: ┤18 ├─────┤18 ├───
│ │ │ │
q_19: ┤19 ├─────┤19 ├───
│ │ │ │
q_20: ┤20 ├─────┤20 ├───
│ │ │ │
q_21: ┤21 ├─────┤21 ├───
│ │ │ │
q_22: ┤22 ├─────┤22 ├───
│ │ │ │
q_23: ┤23 ├─────┤23 ├───
└───────────────────┘ └──────────────────┘