Quick start on cloud
Device: Dirac-3
Qatalyst overview
Qatalyst is a software package from Quantum Computing Inc. It provides a REST API, which can be programmed in any programming language.
The remainder of this document will walk the user through the steps necessary to obtain an access token (API token), test that the token works, and run a small problem. We will use the qci-client
written in Python.
Obtaining an Access Token
To run jobs using the qci-client
you will need an active account and an API token from QCI. To request a QCI user account and a token, submit this form and wait for a response:
Setting up and testing your token
Once you have an API token you can perform the following steps to confirm that you have connectivity.
Installing the client
First, we'll install qci-client package which requires Python 3.8 or higher. Once you have a suitable virtual environment with Python 3.8+ set up, from within that environment run:
pip install "qci-client>=4.0"
Testing Your Setup
With qci-client
installed you should be able to authenticate to the API with your token. To test, let's confirm that we can authenticate. First, import the qci-client
package and set a couple of variables:
import qci_client as qcapi_token = '<your token here>'api_url = 'https://api.qci-prod.com'
Now you can instantiate the client and check that it successfully retrieves a proper bearer token, which should look something like this:
client = qc.QciClient(api_token=api_token, url=api_url)print(client._auth_client.get_access_tokens_health())# {'message': 'OK'}
Alternative Bash Token and URL Setup
Using the API token obtained above, you can also store it in an environment variable named QCI_TOKEN, along with the QCI_API_URL environment variable as shown below. These steps can be run in a terminal (BASH shell) window:
export QCI_TOKEN=<your token here>export QCI_API_URL=https://api.qci-prod.com
Alternatively, you can place these lines in your .bashrc
file. Don't forget to run source ~/.bashrc.
In this case, you can instantiate the QciClient
without arguments, like this:
client = qc.QciClient()print(client._auth_client.get_access_tokens_health())# {'message': 'OK'}
Running a Small Job
Let's run a small job to get familiar with the job pipeline. We'll walk through the steps for an optimization problem using a small 2x2 QUBO matrix.
Main stages of a job
There are three main steps involved with running a job, which we will explicitly detail below:
Data conversion to JSON. This can be handled by a utility function in `qci-client`.
Upload the data to the API. A
file_id
will be returned. Once uploaded, the same data can be referenced multiple times. This is useful when running a parameter sweep, for instance.Submit a job with the
job_type
your are running and thefile_id
obtained in step 1.
Details
First import
qci_client
, then initialize theQciClient
class.Next, load a sample Hamiltonian file as an N by N+1 array for the linear term coefficients in the first column and the quadratic terms in the second column. Each
job_type
requires the user to upload a file in a specific format (see Definitions).After calling
upload_file
, we have thefile_id
of the uploaded file.To trigger the chosen sampler to run, it needs at least one
file_id
in a formattedjob_body
plus thejob_type
.The
job_body
andjob_type
are provided toprocess_job
, which triggers the Qatalyst backend to solve the problem on the desired sampler (this example usesdirac-3
).
import qci_client as qcimport numpy as np# Initialize the client (supply the variables as shown before if# they aren't configured in environment variables# client = qc.qci_client.QciClient()# 1. Here we load some example data which represent a very small polynomial problem (-x_1^2+2*x_1*x_2-x_2^2)hamiltonian = np.array([[0, -1, 1], [0, 1, -1]])poly_coefficients = [-1, 1, -1]poly_indices = [[1, 1], [1, 2], [2, 2]]data = []for i in range(len(poly_coefficients)):data.append({"idx": poly_indices[i],"val": poly_coefficients[i]})hamiltonian_file = {"file_name": "hello-world", "file_config": {"polynomial": {"data": data,"min_degree": 2,"max_degree": 2,"num_variables": 2}}}# 2. A convenience function converts List/Numpy/Scipy matrices to the required JSON for the API under the hood. A file_id is returned with each uploaded file.file_response = client.upload_file(file=hamiltonian_file)# 3. We show a job_body explicitly, but build_job_body is a convenience function available for this step.job_body = client.build_job_body(polynomial_file_id=file_response['file_id'],job_type='sample-hamiltonian',job_name='test_hamiltonian_job', # user-definedjob_tags=['foo', 'bar'], # user-defined list of search tagsjob_params={'device_type': 'dirac-3', 'relaxation_schedule': 3, 'sum_constraint': 1})# Now we can trigger the job to run and wait for a response from the API. The client polls the API every second to check the job status.response = client.process_job(job_body=job_body)
print("Completed Job on Dirac-3. Job Status:", response["status"])assert response["status"] == "COMPLETED"print(response["results"]["solutions"][0])print("Results " + ("Optimal" if response["results"]["energies"][0] == -1 else "Suboptimal"))#2024-04-15 15:47:11 - Dirac allocation balance = 0 s (unmetered)#2024-04-15 15:47:11 - Job submitted: job_id='661da05fbdefceebf853c16c'#2024-04-15 15:47:11 - QUEUED#2024-04-15 15:47:14 - RUNNING#2024-04-15 15:47:32 - COMPLETED#2024-04-15 15:47:34 - Dirac allocation balance = 0 s (unmetered)#Completed Job on Dirac-3. Job Status: COMPLETED#[1, 0]#Results Optimal
This simple example is enough to get you started on running jobs on Dirac systems with QciClient. If you are ready to continue the journey through using Dirac systems, try out these tutorials.