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 below 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 execute this command:
- pip install --upgrade "qci-client<5"
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 package:
In [ ]:
- import qci_client as qc
Next, set a couple of variables:
In [ ]:
- api_url = "https://api.qci-prod.com"
- api_token = "<your_secret_token>"
Now you can instantiate the client and check that it knows your API token:
In [ ]:
- client = qc.QciClient(api_token=api_token, url=api_url)
- print(client.api_token)
- # <your_secret_token>
Finally, check that you can authenticate successfully to API by checking your Dirac devices allocation. For metered accounts, this must be a positive number of seconds in order to run jobs:
In [ ]:
- print(client.get_allocations()["allocations"]["dirac"])
- # {'metered': True, 'seconds': 600}
Running a small job
To get familiar with the job pipeline, let's run a job on the Dirac-3 machine to solve a small optimization problem.
We'll walk through the steps to minimize the energy of a so-called Hamiltonian function defined by a polynomial in 2 variables.
The optimization problem
We solve the following problem:
Main stages of a job
-
Encode the problem data into a file that is recognized by the API.
-
Upload the file to the API. A unique
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. -
Prepare a
job_body
using thefile_id
and other problem and device configuration metadata. -
Submit the
job_body
as a job to the API. The job is given a uniquejob_id
. In this example, we wait synchronously for the results as the job moves through the pipeline.
In [ ]:
- # Insert your API token below, and this script should run as a standalone Python script.
- import qci_client as qc
- client = qc.QciClient(
- url="https://api.qci-prod.com",
- api_token="<your_secret_token>",
- )
- # Stage 1:
- # Here we load some example data which represents a very small problem to minimize the
- # polynomial H = -x_1^2 + 2*x_1*x_2 - x_2^2, subject to x_1 + x_2 = 1, x_1>=0, x_2>=0.
- poly_indices = [[1, 1], [1, 2], [2, 2]]
- poly_coefficients = [-1, 2, -1]
- data = [{"idx": idx, "val": val} for idx, val in zip(poly_indices, poly_coefficients)]
- file = {
- "file_name": "hello-world",
- "file_config": {
- "polynomial": {
- "num_variables": 2,
- "min_degree": 2,
- "max_degree": 2,
- "data": data,
- }
- }
- }
- # Stage 2:
- # Upload the file. A file_id is returned in the file_response.
- file_response = client.upload_file(file=file)
- # Stage 3:
- # Build the job body to be submitted to the API.
- # This is where the job type and the Dirac-3 device and its configuration are specified.
- job_body = client.build_job_body(
- job_type='sample-hamiltonian',
- job_name='test_hamiltonian_job', # user-defined string, optional
- job_tags=['tag1', 'tag2'], # user-defined list of string identifiers, optional
- job_params={'device_type': 'dirac-3', 'relaxation_schedule': 1, 'sum_constraint': 1},
- polynomial_file_id=file_response['file_id'],
- )
- # Stage 4:
- # Submit the job and await the result.
- job_response = client.process_job(job_body=job_body)
- assert job_response["status"] == qc.JobStatus.COMPLETED.value
- print(
- f"Result [x_1, x_2] = {job_response['results']['solutions'][0]} is " +
- ("optimal" if job_response["results"]["energies"][0] == -1 else "suboptimal") +
- f" with H = {job_response['results']['energies'][0]}"
- )
- # This should output something similar to:
- # 2024-05-15 10:59:49 - Dirac allocation balance = 600 s
- # 2024-05-15 10:59:49 - Job submitted: job_id='6644ea05d448b017e54f9663'
- # 2024-05-15 10:59:49 - QUEUED
- # 2024-05-15 10:59:52 - RUNNING
- # 2024-05-15 11:00:46 - COMPLETED
- # 2024-05-15 11:00:48 - Dirac allocation balance = 598 s
- # Result [x_1, x_2] = [1, 0] is optimal with H = -1
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.