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 qc
api_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:

  1. Data conversion to JSON. This can be handled by a utility function in `qci-client`.

  2. 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.

  3. Submit a job with the job_type your are running and the file_id obtained in step 1.

Details

  • First import qci_client , then initialize the QciClient 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 the file_id of the uploaded file.

  • To trigger the chosen sampler to run, it needs at least one file_id in a formatted job_body plus the job_type .

  • The job_body and job_type are provided to process_job , which triggers the Qatalyst backend to solve the problem on the desired sampler (this example uses dirac-3 ).

import qci_client as qc
import 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-defined
job_tags=['foo', 'bar'], # user-defined list of search tags
job_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.