Using the API to run the emulation

We use a strongly defined HTTP API protocol to communicate with a C12 backend (get and receive the data). This tutorial will briefly present basic API calls that can be used for communication with the C12 backend. Our APIs are the low-level access to our emulator, and could be made compatible with other quantum computer frameworks and interfaces.

To run each API, we need to pass the unique bearer token that will be used to verify the user’s right to access C12’s system.

For communication with C12’s system, it is possible to use the API library that encapsulates the HTTP communication with the C12 system using the Python request module.

To start using it, we need to create an instance of the Request class, as shown in the following code snippet.

[2]:
# Installing the c12simulator-clients package (for more details see jupyter 1)
import os
from c12_callisto_clients.api.client import Request

TOKEN = os.getenv("C12_TOKEN")

# Create the request instance
# Constructor of the Request class also accepts the verbose parameter, which can be use for more detailed output of the methods.

request = Request(auth_token=TOKEN, verbose=False)

Run the simulation

The method start_job() is used to start the simulation. It has the following arguments: - qasm_str: QASM string with quantum circuit - shots: Number of trials for the simulation - result: what is desired output (statevector, counts, density_matrix) - backend_name: the name of the backend to run on

[3]:
from qiskit import QuantumCircuit
from qiskit.qasm2 import dumps

circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)


qasm_str = dumps(circuit)
res = request.start_job(
    qasm_str=qasm_str, shots=100, result="density_matrix", backend_name="c12sim-iswap"
)

# The function returns the UUID and QasmStr of started job or HTTP error in case of problems
print(res)
job_uuid = res[0]

('9815850c-26d1-41f7-bdf9-3a7a6ec4fc92', 'OPENQASM 2.0;\ninclude "qelib1.inc";\ngate iswap q0,q1 { s q0; s q1; h q0; cx q0,q1; cx q1,q0; h q1; }\nqreg q[2];\nry(-pi/2) q[1];\niswap q[0],q[1];\nrx(pi) q[0];\nry(-pi/2) q[1];\niswap q[0],q[1];\nry(-pi/2) q[0];\nrz(-pi/2) q[0];\nrz(pi/2) q[1];\nry(-pi/2) q[1];\n')

Get the results of a simulation

To get the emulation results, we can use the get_job_result() method that accepts one mandatory argument (job UUID string) and two optional ones. - timeout, which represents the number of seconds that the function will wait for job completion - wait, number of seconds between each check if the job is finished

If we do not specify a timeout argument the function will run until the result is obtained

[4]:
job_result = request.get_job_result(job_uuid, timeout=120, wait=5)
print(job_result)
{'status': 'FINISHED', 'results': {'density_matrix': [['(0.5003440602236676+0j)', '(-4.0683126779214476e-05+0.00019098408162360553j)', '(-4.0659775278663985e-05+0.00015270732715235404j)', '(0.49999981190306614-8.134297823249877e-05j)'], ['(-4.0683126779214476e-05-0.00019098408162360553j)', '(7.620763244616229e-08+0j)', '(6.15952858760575e-08+3.103381079950268e-09j)', '(-4.068618490670183e-05-0.0001908460661227806j)'], ['(-4.0659775278663985e-05-0.00015270732715235404j)', '(6.15952858760575e-08-3.103381079950268e-09j)', '(4.9911145303821645e-08+0j)', '(-4.0656626664155645e-05-0.00015259565074291268j)'], ['(0.49999981190306614+8.134297823249877e-05j)', '(-4.068618490670183e-05+0.0001908460661227806j)', '(-4.0656626664155645e-05+0.00015259565074291268j)', '(0.4996558136575547+0j)']]}, 'errors': ''}

Get the status of the job

[5]:
status = request.get_job_status(job_uuid=job_uuid)
print(status)
finished

Get all jobs

Method get_user_jobs() can be used for obtaining information about all the jobs that have been run on the system for the user whose token is passed to the Request instance.

The method has two arguments: - limit: an integer that represents the number of results to obtain - offset: an integer that represents the offset from the first result

Using these two values, one can obtain the pagination, where the offset represents a page and limits the number of results per page. Method returns an array with results.

[ ]:
number_of_results = 5  # Limit parameter, number of records to retrieve
offset = 0
count = 1
while True:
    jobs = request.get_user_jobs(limit=number_of_results, offset=offset)

    for job in jobs:
        print(f"{count:}")
        print(job)
        count += 1

    if len(jobs) < number_of_results:
        break

    offset += number_of_results

Get information about a specific job

Using the method get_job() it is possible to retrieve the information about the specific job with a given UUID.

[7]:
job_data = request.get_job(job_uuid)
print(job_data)
{'uuid': '9815850c-26d1-41f7-bdf9-3a7a6ec4fc92', 'time': '2024-10-08T14:49:13.520938', 'status': 'finished', 'options': {'shots': 100, 'result': 'density_matrix', 'basis': 'iswap'}, 'task': 'OPENQASM 2.0;\ninclude "qelib1.inc";\ngate iswap q0,q1 { s q0; s q1; h q0; cx q0,q1; cx q1,q0; h q1; }\nqreg q[2];\nry(-pi/2) q[1];\niswap q[0],q[1];\nrx(pi) q[0];\nry(-pi/2) q[1];\niswap q[0],q[1];\nry(-pi/2) q[0];\nrz(-pi/2) q[0];\nrz(pi/2) q[1];\nry(-pi/2) q[1];\n', 'task_orig': 'OPENQASM 2.0;\ninclude "qelib1.inc";\nqreg q[2];\nh q[0];\ncx q[0],q[1];', 'errors': '', 'result': {'statevector': ['(-0.707350024308301+5.774697558332201e-05j)', '(5.7536886630460415e-05+0.0002699947020277173j)', '(5.749945628447106e-05+0.0002158818144976827j)', '(-0.7068633604703698-5.728953929746232e-05j)'], 'density_matrix': [['(0.5003440602236676+0j)', '(-4.0683126779214476e-05+0.00019098408162360553j)', '(-4.0659775278663985e-05+0.00015270732715235404j)', '(0.49999981190306614-8.134297823249877e-05j)'], ['(-4.0683126779214476e-05-0.00019098408162360553j)', '(7.620763244616229e-08+0j)', '(6.15952858760575e-08+3.103381079950268e-09j)', '(-4.068618490670183e-05-0.0001908460661227806j)'], ['(-4.0659775278663985e-05-0.00015270732715235404j)', '(6.15952858760575e-08-3.103381079950268e-09j)', '(4.9911145303821645e-08+0j)', '(-4.0656626664155645e-05-0.00015259565074291268j)'], ['(0.49999981190306614+8.134297823249877e-05j)', '(-4.068618490670183e-05+0.0001908460661227806j)', '(-4.0656626664155645e-05+0.00015259565074291268j)', '(0.4996558136575547+0j)']], 'counts': {'00': 57, '11': 43}, 'states': {'density_matrix': {}, 'statevector': {}}}}
[ ]: