Accessing info with cirq-superstaq
This tutorial will cover the information you can access on your account and related jobs and targets using cirq-superstaq
.
Imports and API Token
As usual, we’ll begin with importing requirements and setting up access to Superstaq. This tutorial uses cirq-superstaq
, our Superstaq client for Cirq. You can install it and relevant dependencies by running pip install cirq-superstaq
.
[1]:
# Requirements to use cirq-superstaq
try:
import cirq
import cirq_superstaq as css
except ImportError:
print("Installing cirq-superstaq...")
%pip install --quiet 'cirq-superstaq[examples]'
print("Installed cirq-superstaq.")
print("You may need to restart the kernel to import newly installed packages.")
import cirq
import cirq_superstaq as css
Now, we instantiate a service provider in cirq-superstaq
with Service()
. Supply the Superstaq API token by providing the token as an argument of css.Service()
or setting it as an environment variable (see this guide).
[2]:
service = css.Service()
Account Information
The service
class gives you a means to retrieve information regarding your Superstaq account. Currently, you can use service
to retrieve your Superstaq balance.
[3]:
service.get_balance()
[3]:
'20 credits'
If are interested in increasing your balance or have more information on your user role, please reach out to us at superstaq@infleqtion.com or join our Slack workspace.
Backend Information
In addition to account information, the Service
object also gives you a list of all the devices and simulators to which you have access, as well as additional information about those targets.
get_targets()
: Retrieves a list of available targets. This method also accepts the following boolean keyword arguments to filter the targets returned:simulator
,supports_submit
,supports_submit_qubo
,supports_compile
,available
,retired
, andaccessible
.get_my_targets()
: Retrieves a filtered list of targets that are accessible to the user based on their user role permissions. This method is equivalent toget_targets(accessible=True)
.target_info("<target_name>")
: Retrieve information on your selected backend, such as number of qubits, native gate set, where<target_name>
is the name of the desired backend
[4]:
service.get_targets()
[4]:
[Target(target='aqt_keysight_qpu', supports_submit=False, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='aqt_zurich_qpu', supports_submit=False, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='aws_dm1_simulator', supports_submit=True, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='aws_sv1_simulator', supports_submit=True, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='aws_tn1_simulator', supports_submit=True, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='cq_sqale_qpu', supports_submit=True, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='cq_sqale_simulator', supports_submit=True, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='eeroq_wonderlake_qpu', supports_submit=False, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='ibmq_brisbane_qpu', supports_submit=True, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='ibmq_fez_qpu', supports_submit=True, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='ibmq_kyiv_qpu', supports_submit=True, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='ibmq_marrakesh_qpu', supports_submit=True, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='ibmq_sherbrooke_qpu', supports_submit=True, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='ibmq_torino_qpu', supports_submit=True, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='ionq_aria-1_qpu', supports_submit=True, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='ionq_aria-2_qpu', supports_submit=False, supports_submit_qubo=False, supports_compile=True, available=False, retired=False),
Target(target='ionq_forte-1_qpu', supports_submit=False, supports_submit_qubo=False, supports_compile=True, available=False, retired=False),
Target(target='ionq_ion_simulator', supports_submit=True, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='iqm_garnet_qpu', supports_submit=False, supports_submit_qubo=False, supports_compile=True, available=False, retired=False),
Target(target='qscout_peregrine_qpu', supports_submit=False, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='qtm_h1-1_qpu', supports_submit=True, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='qtm_h1-1e_simulator', supports_submit=True, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='qtm_h2-1_qpu', supports_submit=True, supports_submit_qubo=False, supports_compile=True, available=True, retired=False),
Target(target='rigetti_ankaa-2_qpu', supports_submit=False, supports_submit_qubo=False, supports_compile=True, available=False, retired=False),
Target(target='ss_unconstrained_simulator', supports_submit=True, supports_submit_qubo=True, supports_compile=True, available=True, retired=False)]
[ ]:
service.target_info("ibmq_brisbane_qpu") # retrieving information about IBM's Brisbane device
{'num_qubits': 127,
'target': 'ibmq_brisbane_qpu',
'coupling_map': [[0, 1],
[0, 14],
[1, 0],
[1, 2],
[2, 1],
[2, 3],
[3, 2],
[3, 4],
[4, 3],
[4, 5],
[4, 15],
[5, 4],
[5, 6],
[6, 5],
[6, 7],
[7, 6],
[7, 8],
[8, 7],
[8, 9],
[8, 16],
[9, 8],
[9, 10],
[10, 9],
[10, 11],
[11, 10],
[11, 12],
[12, 11],
[12, 13],
[12, 17],
[13, 12],
[14, 0],
[14, 18],
[15, 4],
[15, 22],
[16, 8],
[16, 26],
[17, 12],
[17, 30],
[18, 14],
[18, 19],
[19, 18],
[19, 20],
[20, 19],
[20, 21],
[20, 33],
[21, 20],
[21, 22],
[22, 15],
[22, 21],
[22, 23],
[23, 22],
[23, 24],
[24, 23],
[24, 25],
[24, 34],
[25, 24],
[25, 26],
[26, 16],
[26, 25],
[26, 27],
[27, 26],
[27, 28],
[28, 27],
[28, 29],
[28, 35],
[29, 28],
[29, 30],
[30, 17],
[30, 29],
[30, 31],
[31, 30],
[31, 32],
[32, 31],
[32, 36],
[33, 20],
[33, 39],
[34, 24],
[34, 43],
[35, 28],
[35, 47],
[36, 32],
[36, 51],
[37, 38],
[37, 52],
[38, 37],
[38, 39],
[39, 33],
[39, 38],
[39, 40],
[40, 39],
[40, 41],
[41, 40],
[41, 42],
[41, 53],
[42, 41],
[42, 43],
[43, 34],
[43, 42],
[43, 44],
[44, 43],
[44, 45],
[45, 44],
[45, 46],
[45, 54],
[46, 45],
[46, 47],
[47, 35],
[47, 46],
[47, 48],
[48, 47],
[48, 49],
[49, 48],
[49, 50],
[49, 55],
[50, 49],
[50, 51],
[51, 36],
[51, 50],
[52, 37],
[52, 56],
[53, 41],
[53, 60],
[54, 45],
[54, 64],
[55, 49],
[55, 68],
[56, 52],
[56, 57],
[57, 56],
[57, 58],
[58, 57],
[58, 59],
[58, 71],
[59, 58],
[59, 60],
[60, 53],
[60, 59],
[60, 61],
[61, 60],
[61, 62],
[62, 61],
[62, 63],
[62, 72],
[63, 62],
[63, 64],
[64, 54],
[64, 63],
[64, 65],
[65, 64],
[65, 66],
[66, 65],
[66, 67],
[66, 73],
[67, 66],
[67, 68],
[68, 55],
[68, 67],
[68, 69],
[69, 68],
[69, 70],
[70, 69],
[70, 74],
[71, 58],
[71, 77],
[72, 62],
[72, 81],
[73, 66],
[73, 85],
[74, 70],
[74, 89],
[75, 76],
[75, 90],
[76, 75],
[76, 77],
[77, 71],
[77, 76],
[77, 78],
[78, 77],
[78, 79],
[79, 78],
[79, 80],
[79, 91],
[80, 79],
[80, 81],
[81, 72],
[81, 80],
[81, 82],
[82, 81],
[82, 83],
[83, 82],
[83, 84],
[83, 92],
[84, 83],
[84, 85],
[85, 73],
[85, 84],
[85, 86],
[86, 85],
[86, 87],
[87, 86],
[87, 88],
[87, 93],
[88, 87],
[88, 89],
[89, 74],
[89, 88],
[90, 75],
[90, 94],
[91, 79],
[91, 98],
[92, 83],
[92, 102],
[93, 87],
[93, 106],
[94, 90],
[94, 95],
[95, 94],
[95, 96],
[96, 95],
[96, 97],
[96, 109],
[97, 96],
[97, 98],
[98, 91],
[98, 97],
[98, 99],
[99, 98],
[99, 100],
[100, 99],
[100, 101],
[100, 110],
[101, 100],
[101, 102],
[102, 92],
[102, 101],
[102, 103],
[103, 102],
[103, 104],
[104, 103],
[104, 105],
[104, 111],
[105, 104],
[105, 106],
[106, 93],
[106, 105],
[106, 107],
[107, 106],
[107, 108],
[108, 107],
[108, 112],
[109, 96],
[109, 114],
[110, 100],
[110, 118],
[111, 104],
[111, 122],
[112, 108],
[112, 126],
[113, 114],
[114, 109],
[114, 113],
[114, 115],
[115, 114],
[115, 116],
[116, 115],
[116, 117],
[117, 116],
[117, 118],
[118, 110],
[118, 117],
[118, 119],
[119, 118],
[119, 120],
[120, 119],
[120, 121],
[121, 120],
[121, 122],
[122, 111],
[122, 121],
[122, 123],
[123, 122],
[123, 124],
[124, 123],
[124, 125],
[125, 124],
[125, 126],
[126, 112],
[126, 125]],
'supports_midcircuit_measurement': True,
'native_gate_set': ['ecr', 'id', 'rz', 'sx', 'x'],
'max_experiments': 300,
'max_shots': 100000,
'processor_type': {'family': 'Eagle', 'revision': 3},
'open_pulse': True,
'supports_dynamic_circuits': True}
Job Information
Jobs submitted through Superstaq contain the following information:
job_id()
: Unique identifier for the job.status()
: Overall status of the job (Submitted, Queued, Running, Failed, Canceled, or Done). Note that anindex
argument can be passed optionally to retreive the status of a specific job indexed byindex
in a batch job.target()
: Device the job was run on.counts()
: Counts from the result of the job run. Note this can return a list, so you must specify anindex
if you want to retrieve a specific counts dictionary (corresponding to the circuit with the sameindex
).num_qubits()
: Number of qubits for the job. Note this can return a list, so you must specify anindex
if you want to retrieve the corresponding number of qubits to a particular circuit.repetitions()
: Number of repetitions for the job.input_circuits()
: Retrieves original (i.e., not compiled) circuit(s) for job. Note this returns a list and you must specify anindex
if you want to retrieve a single/specific circuit.compiled_circuits()
: Retrieves compiled circuit(s) from submitted job. Note this returns a list and you must specify anindex
if you want to retrieve a single/specific circuit.
Note that jobs live in our database for a limited amount of time. Typically, they have a lifespan of 1 year.
[6]:
# Creating a circuit using Cirq
qubits = cirq.LineQubit.range(2)
circuit = cirq.Circuit(
cirq.H(qubits[0]),
cirq.CNOT(qubits[0], qubits[1]),
cirq.measure(qubits[0]),
cirq.measure(qubits[1]),
)
# Submitting the circuit to IBM's Brisbane QPU
job = service.create_job(
circuit, repetitions=100, method="dry-run", target="ibmq_brisbane_qpu"
) # Specify "dry-run" as the method to submit & run a Superstaq simulation
[7]:
job.job_id()
[7]:
'933729a9-db61-4c94-b994-26e2941a7fd1'
[8]:
job.status()
[8]:
'Done'
[9]:
job.target()
[9]:
'ibmq_brisbane_qpu'
[10]:
job.counts(index=0)
[10]:
{'11': 63, '00': 37}
[11]:
job.num_qubits(index=0)
[11]:
2
[12]:
job.repetitions()
[12]:
100
[13]:
job.input_circuits(index=0)
[13]:
0: ───H───@───M─── │ 1: ───────X───M───
[14]:
job.compiled_circuits(index=0)
[14]:
41: ───Rz(1.5π)───X^0.5───AceCR+-(Z side)───│───M('q(0)')─── │ │ 53: ───X^0.5──────────────AceCR+-(X side)───│───M('q(1)')───
Additionally, you may cancel the current job (or, optionally, a sub-job by passing an index
argument) if it is not in a terminal state like so:
[15]:
job.cancel()
SuperstaqWarning: Job '933729a9-db61-4c94-b994-26e2941a7fd1' cannot be cancelled: it already has status Done
self._client.cancel_jobs(ids_to_cancel, **kwargs)
Lastly, you may also retrieve the information described above on a previously submitted cirq-superstaq
job with service.get_job('<job_id>')
:
[16]:
job_id = job.job_id() # Here we use the job ID from above, but this can be any old job ID
job_old = service.get_job(job_id)
job_old.input_circuits(index=0)
[16]:
0: ───H───@───M─── │ 1: ───────X───M───