How to run circuits on Fire Opal
Learning the basics of running circuits with Fire Opal
If you want to run a circuit or a list of circuits, Fire Opal's execute
function is designed for straightforward job submission to quantum hardware. As your workload scales, and you need to run several hundred circuits at once or multiple consecutive circuits, you can use the iterate
function, which is optimized for handling several jobs or executing multiple consecutive circuits, such as variational or batch workflows. The iterate
function minimizes preprocessing and queuing delays when jobs are submitted in immediate succession.
In this user guide, you will learn how to run circuits using both the execute
and iterate
functions.
1. Imports and initialization
To run these examples, you'll first need to set up your account information for Fire Opal and your hardware provider.
1.1 Fire Opal import and initialization
import fireopal as fo
# Replace "YOUR_QCTRL_API_KEY" with your API key, which you can find at https://accounts.q-ctrl.com/security
api_key = "YOUR_QCTRL_API_KEY"
fo.authenticate_qctrl_account(api_key=api_key)
1.2 IBM Quantum import and initialization
If you are using an IBM Quantum device, first you will need to setup your IBM account, then import the required libraries for this user guide.
from qiskit import QuantumCircuit, qasm3
from qiskit.circuit import Parameter
You can access devices on IBM Quantum via Fire Opal by signing up for an IBM Quantum account and using your token and credentials to authenticate.
# Insert your token and instance information
ibm_token = "YOUR_IBMQ_TOKEN"
hub = "ibm-q"
group = "open"
project = "main"
# Create your credentials dictionary hardware platform authentication
credentials = fo.credentials.make_credentials_for_ibmq(
token=ibm_token, hub=hub, group=group, project=project
)
1.3 IonQ through Amazon Braket import and initialization
If you are using an IonQ device, first you will need to setup your AWS Braket environment, then import the required libraries for this user guide.
from braket.circuits.serialization import IRType
from braket.circuits import Circuit
from braket.aws import AwsDevice
On Amazon Braket, you can use the function make_credentials_for_braket
to generate the credentials dictionary needed to execute jobs.
arn = "your_role_arn"
credentials = fo.credentials.make_credentials_for_braket(arn=arn)
2. Running a single job in Fire Opal
The following entanglement circuit demonstrates a basic example of how to code and run a job using the execute
function, this function is limited to 300 circuits per batch.
2.1 Submitting a circuit with execute
on IBM Quantum
# Create a basic circuit with a Hadamard and a CNOT gate
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
qc.measure_all()
qc.draw("mpl")
Be sure to choose a backend and replace "desired_backend"
with the target name.
# Define shots and desired backend (replace "desired_backend" with your backend)
shot_count = 1024
backend_name = "desired_backend"
# Run the circuit with the execute function
fire_opal_job = fo.execute(
circuits=[qasm3.dumps(qc)],
shot_count=shot_count,
credentials=credentials,
backend_name=backend_name,
)
fire_opal_job.result()
2.2 Submitting a circuit with execute
on IonQ
# Create a basic circuit with a Hadamard and a CNOT gate
qc = """
OPENQASM 3.0;
include "stdgates.inc";
bit[2] b;
qubit[2] q;
h q[0];
cx q[0], q[1];
b[0] = measure q[0];
b[1] = measure q[1];
"""
circuit = Circuit.from_ir(qc)
print(circuit)
Use the function show_supported_devices
to list the devices that are supported by Fire Opal and accessible to you, and choose a backend device.
supported_devices = fo.show_supported_devices(credentials=credentials)[
"supported_devices"
]
for name in supported_devices:
print(name)
# Enter your desired IonQ backend here or select one with a small queue
shot_count = 1024
backend_name = "desired_backend"
print(f"Will run on backend: {backend_name}")
fire_opal_job = fo.execute(
circuits=[qc],
shot_count=shot_count,
credentials=credentials,
backend_name=backend_name,
)
fire_opal_result = fire_opal_job.result()
3. Running multiple jobs in Fire Opal
The following code demonstrates a basic example of using iterate to submit multiple jobs on IBM Quantum. You can also refer to more in-depth guides on using iterate
to run batch workloads and variational algorithms.
# Creating a parameterized circuit
from qiskit.circuit import Parameter
angle = Parameter("alpha")
param_qc = QuantumCircuit(1)
param_qc.rx(angle, 0)
param_qc.measure_all()
param_qc.draw("mpl")
# Generate sets of random values for the parameters
random_values = np.random.rand(500, 2)
parameter_dicts = [
{param.name: val for param, val in zip(param_qc.parameters, values)}
for values in random_values
]
# Split the dictionary of parameters to account for the max job size.
max_size = 300
result_arrays = np.array_split(
parameter_dicts, np.ceil(len(parameter_dicts) / max_size)
)
# Define the backend (replace "desired_backend" with your backend)
backend_name = "desired_backend"
# Submit jobs for each list of parameters
jobs = []
for param_array in result_arrays:
fire_opal_job = fo.iterate(
circuits=[qasm3.dumps(param_qc)],
shot_count=1024,
credentials=credentials,
backend_name=backend_name,
parameters=param_array.tolist(),
)
jobs.append(fire_opal_job)
results = []
for job in jobs:
results.append(job.result())
You can use the iterate
function to bypass the limit of 300 circuits from the execute
function, however, this will initiate a session on IBM Quantum, which may incur in additional costs. If your workflow does not involve dependent iterations, an alternative is to split your circuits into batches of 300.