QCi Client Quick start

Device: Dirac-3

Welcome to the Quantum Computing Inc. (QCi) qci-client guide! This document will walk you through accessing our quantum optimization machines, including Dirac-1, Dirac-2, and Dirac-3, via a user-friendly REST API. Flexible API: Program interactions in your preferred language. Cloud-based Access: Streamlined access using uniquely generated API tokens. Comprehensive Guide: Learn to obtain, test, and utilize API tokens. Hands-on Example: Execute a simple problem using the qci-client and Python. Let's get started!

Obtaining an Access Token

To access our quantum optimization machines and run jobs using the qci-client, you'll need an active account and an API Access token.

Once you have your API token, follow these steps to connect to the qci-client and access our machines:

Installation

To follow our tutorial, ensure you have Python version 3.8 or higher installed on your system. To install the qci-client run the following command in your terminal:

  • pip install --upgrade "qci-client<5"

This will install the latest version of the qci-client (version 5 or higher). For a more organized development environment, we recommend using a virtual environment to isolate qci-client dependencies.

Testing your setup

1.0.1 Import the qci_client Package After installing the qci-client, let's verify your connection and authentication to the QCi API.

In [ ]:

  • #This line imports the qci-client library into your Python environment, making its functionalities accessible for use.
  • import qci_client as qc

1.0.2 Configure Variables Next, setup two variables: one for the API's URL and one for your token. The API URL tells the client where to connect, and your API token is what allows you to access the API.

  • The API URL is always: https://api.qci-prod.com
  • Replace <your_secret_token> with your actual API token (which should look like a long string of letters and numbers).

In [ ]:

  • api_url = "https://api.qci-prod.com"
  • api_token = "<your_secret_token>"

1.0.3 Create a Client Instance

In [ ]:

  • client = qc.QciClient(api_token=api_token, url=api_url)
  • print(client.api_token)
  • # Output: <your_secret_token>

This line creates a QciClient object, which acts as your interface to the QCi API. The apitokenapi_token and url arguments configure the client for your specific account. The print statement verifies the token is stored securely within the client object (avoid displaying your actual token!).

1.0.4 Verify Authentication

In [ ]:

  • print(client.get_allocations()["allocations"]["dirac"])
  • # Output: {'metered': True, 'seconds': 600}

Running a small job

Now that we've created a client instance and gained access to the API, let's proceed with running a small optimization problem on our Dirac-3 device. This exercise will help us become acquainted with the job pipeline.

First, we'll define the problem we want to solve. We aim to minimize the energy of a Hamiltonian function, which is described by a polynomial in two variables.

The optimization problem

We solve the following problem:

minimize(x1,x2)R2H(x1,x2)=x12+2x1x2x22subject tox1+x2=1,  x10,x20\begin{equation*} \begin{aligned} & \underset{(x_1,x_2) \in \mathbb{R}^2}{\text{minimize}} & & H(x_1,x_2) = -x_1^2 + 2\,x_1 x_2 - x_2^2\\ & \text{subject to} & & x_1 + x_2 = 1, \; x_1 \geq 0, x_2 \geq 0 \end{aligned} \end{equation*}

Step 1: Begin by creating an instance of the client using your API access token

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>",
  • )

Step 2:: Encode the problem data into a JSON file format so that it is recognized by the API. In this step, we prepare example data representing a small problem aimed at minimizing the polynomial:

In [ ]:

  • # 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,
  • }
  • }
  • }

Step 3: Upload the JSON file to the API. A unique file identifier (file_id) will be returned in the file_response, allowing for easy referencing of the uploaded data in subsequent tasks. This is useful when running a parameter sweep, for instance.

In [ ]:

  • file_response = client.upload_file(file=file)

Step 4: Prepare a job body using the file_id and other problem and device configuration metadata. This step involves constructing the job body to be submitted to the API, specifying the job type, the Dirac-3 device, and its configuration details.

In [ ]:

  • # 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'],
  • )

Where:

job type: Specifies the type of job to be performed. In this case, ’sample-hamiltonian’ indicates that the job involves creating a Hamiltonian.

job name: An optional user-defined string that names the job. Here, it’s set to ’test hamiltonian job’.

job tags: An optional list of user-defined string identifiers to tag the job for easier reference and organization. In this example, the tags are [’tag1’, ’tag2’].

job params: A dictionary containing parameters for configuring the job and the device. The keys and values specify that the device type is ’dirac-3’, with a relaxation schedule of 1 and a sum constraint of 1.

polynomial file id: The unique identifier for the uploaded polynomial file, retrieved from the file response ’file id’. This ID links the job to the specific problem data.

By preparing the job body in this manner, you set up all necessary configurations and metadata required by the API to process the optimization task on the Dirac-3 device.

Step 5: Submit the job body to the API as a job.

In [ ]:

  • # 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 example provides a basic introduction to using the qci-client to run jobs on Dirac systems. To delve deeper into the capabilities of these machines, explore our additional tutorials and documentation

Recommended Resources:

Dirac-3 User Guide

Example Notebooks: max-cut, portfolio optimization

These resources will help you learn advanced features to discover more complex usage scenarios and optimization techniques. You can experiment with various problem formulations and data structures. Most importantly, understanding best practices and gain insights into efficient use of Dirac systems.