Resources

This chapter describes supported Solver Application Programming Interface (SAPI) resources and provides example usages.

Examples Setup

The examples below use the following setup:

>>> import base64
>>> import hashlib
>>> import json
>>> import os
>>> import requests
>>> import struct
>>> from urllib.parse import urlencode
...
>>> SAPI_HOME = "https://na-west-1.cloud.dwavesys.com/sapi/v2"
... # Replace with your API token
>>> SAPI_TOKEN = "ABC-1234567...345678"     
...
>>> session = requests.Session()
>>> session.headers = {'X-Auth-Token': SAPI_TOKEN, 'Content-type': 'application/json'}

For some examples of uploading problems to Leap™ quantum-classical hybrid solvers, a serialized binary quadratic model (\(\text{E} = -ab\)) is also used. The following code uses Ocean to serialize the problem to the required format.1

>>> import dimod
>>> bqm = dimod.BinaryQuadraticModel({}, {'xy': -1}, 'BINARY')
>>> bqm_ser = bqm.to_file().read()
1

For details of the required format, see the dimod to_file() method.

$ export SAPI_HOME=https://na-west-1.cloud.dwavesys.com/sapi/v2
$ export SAPI_TOKEN=ABC-1234567...345678       # Replace with your API token

For some examples of uploading problems to Leap™ quantum-classical hybrid solvers, a serialized binary quadratic model (\(\text{E} = -ab\)) is also used. The dimod to_file() method is used to serialize the problem, which is saved to a file.

SAPI Resources

SAPI provides the following resources and methods.

Table 59 SAPI Resources

Resource

Method

Reference

/bqm/multipart

POST

Initiate Upload of Problem Data

/bqm/multipart/<problem_data_id>/part/<part>

PUT

Upload Problem Data

/bqm/multipart/<problem_data_id>/combine

POST

Submit a Checksum for a Problem Upload

/bqm/multipart/<problem_data_id>/status

GET

Status of a Problem Upload

/problems/

POST

Submit Problems

/problems/

DELETE

Cancel Multiple Problems

/problems/<problem_id>

DELETE

Cancel a Problem by ID

/problems/

GET

List Problems

/problems/<problem_id>/

GET

Retrieve a Problem

/problems/<problem_id>/info

GET

Retrieve Problem Information

/problems/<problem_id>/answer/

GET

Retrieve an Answer

/problems/<problem_id>/messages/

GET

Retrieve Problem Messages

/solvers/remote/

GET

Retrieve Available Solvers

/solvers/remote/<solver_id>/

GET

Retrieve Solver Fields

Initiate Upload of Problem Data

For Leap quantum-classical hybrid solvers, you must upload your problem to Leap using the $SAPI_HOME/bqm/multipart/* endpoints before submitting a SAPI request to run the problem. For large problems (starting from several megabytes and higher), upload the problem data in multiple parts.

  • Maximum problem size currently supported is 50 GB.

  • Size of all parts must be 5M (5242880 bytes), except the last, which may be smaller.

To initiate the uploading of a problem, in a single part for small problems or multiple parts for problems of several megabytes and higher, send an HTTP POST request to bqm/multipart.

The POST request body should contain the number of bytes—size, as an integer—required to store the problem.

SAPI returns an identifier, of type UUID, for the uploaded problem.

This example initiates an upload of the serialized BQM, bqm_ser, created in the Examples Setup section.

>>> size = len(bqm_ser)
>>> r = session.post(f"{SAPI_HOME}/bqm/multipart",
...                  json={"size": size})

This example sets the size of the uploaded problem, size, to the number of bytes of the serialized BQM of the Examples Setup section.

$ size=312
$ curl -H "X-Auth-Token: $SAPI_TOKEN" -H "Content-type: application/json" \
  -X POST $SAPI_HOME/bqm/multipart/ -d '{"size": '"$size"'}'
{"id":"be806ff1-09d3-49d4-bba1-3008790c99d6"}

Upload Problem Data

To upload a problem, or parts of a large problem, send an HTTP PUT request to bqm/multipart/<problem_data_id>/part/<part> (for each part, where <part> is an integer beginning at 1).

The POST request body should contain the data for (one part of) the problem, encoded as described in the dimod to_file() method, and the header should contain the MD5 checksum.

For a multi-part upload, data size for each part should be 5 MB (5242880 bytes), except for the last part, which may be smaller.

This example uses the identifier problem_data_id returned from the Initiate Upload of Problem Data example and an MD5 hash calculated above.

>>> r = session.put(f"{SAPI_HOME}/bqm/multipart/{problem_data_id}/part/1",
...                  headers={"Content-type": "application/octet-stream",
...                           "Content-MD5": "mkDiHuw5xZD3ocYSikE4nw=="},
...                  data=bqm_ser)

This example sets the identifier, problem_data_id, of the problem data to be uploaded to the value returned from the Initiate Upload of Problem Data example, the MD5 checksum, md5, to the value calculated above, and the uploaded data to the BQM of the Examples Setup section saved to file my_bqm.txt.

$ problem_data_id="be806ff1-09d3-49d4-bba1-3008790c99d6"
$ md5="mkDiHuw5xZD3ocYSikE4nw=="
$ curl -H "X-Auth-Token: $SAPI_TOKEN" -H "Content-MD5: $md5" -H \
  "Content-type: application/octet-stream" -X PUT \
  $SAPI_HOME/bqm/multipart/$problem_data_id/part/1 -T my_bqm.txt

Submit a Checksum for a Problem Upload

To complete an upload of problem data, send an HTTP POST request to bqm/multipart/<problem_data_id>/combine.

The POST request body should contain the checksum for the entire problem, as a string.

This example uses the identifier problem_data_id returned from the Initiate Upload of Problem Data example and a checksum calculated above.

>>> r = session.post(f"{SAPI_HOME}/bqm/multipart/{problem_data_id}/combine",
...                   json={"checksum": "baf79ab99e269f7fda21e927b33345e9"})

This example sets the identifier, problem_data_id, of the problem data to be uploaded to the value returned from the Initiate Upload of Problem Data example and the checksum, checksum, to the value calculated above.

$ problem_data_id="be806ff1-09d3-49d4-bba1-3008790c99d6"
$ checksum="baf79ab99e269f7fda21e927b33345e9"
$ curl  -H "X-Auth-Token: $SAPI_TOKEN" -H "Content-type: application/json" \
  -X POST $SAPI_HOME/bqm/multipart/$problem_data_id/combine/ -d '{"checksum":'"$checksum"'}'

Status of a Problem Upload

To query the status of an in-progress problem upload, send an HTTP GET request to bqm/multipart/<problem_data_id>/status.

The GET request should contain no body.

SAPI returns the status as a string with parts and checksums.

This example uses the identifier problem_data_id returned from the Initiate Upload of Problem Data example.

>>> r = session.get(f"{SAPI_HOME}/bqm/multipart/{problem_data_id}/status")

This example sets the identifier, problem_data_id, of the problem data being uploaded to the value returned from the Initiate Upload of Problem Data example.

$ problem_data_id="be806ff1-09d3-49d4-bba1-3008790c99d6"
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/bqm/multipart/$problem_data_id/status

Submit Problems

To submit problems to a Leap solver, send an HTTP POST request to problems.

The POST request body should contain the JSON-encoded fields described below. When possible, if you have more than one problem, submit them in a single query.2

For an example of sumitting a problem to a quantum processing unit (QPU) sampler, see the End-to-End Examples section.

This example uses the identifier problem_data_id returned from the Initiate Upload of Problem Data example and Leap hybrid solver solver_hybrid_bqm selected as in the Submit a Problem to a Quantum-Classical Hybrid Solver section.

>>> r = session.post(f"{SAPI_HOME}/problems",
...                   json=[{"solver": solver_hybrid_bqm,
...                          "label": "REST Submission to hybrid BQM solver",
...                          "data": {"format": "ref", "data": problem_data_id},
...                          "type": "bqm",
...                          "params": {"time_limit": 5}}])

This example sets the identifier, problem_data_id, of the problem data being uploaded to the value returned from the Initiate Upload of Problem Data example and sets the requested solver to hybrid_binary_quadratic_model_version2p, a Leap solver available to the user account that executed this example.

$ problem_data_id="be806ff1-09d3-49d4-bba1-3008790c99d6"
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/problems -X POST \
  -d '[{"type":"bqm","label": "REST Submission to hybrid BQM solver", \
  "solver":"hybrid_binary_quadratic_model_version2p", \
  "data":{"format": "ref", "data": "'"$problem_data_id"'"}, \
  "params":{"time_limit":5}}]'
2

The request body is JSON data enclosed in a list. For submitting multiple problems in a single query, the list is the comma-separated fields of each problem: [{"solver": ...},{"solver": ...},...{"solver": ...}]

Cancel Multiple Problems

To cancel pending problems (problems with status PENDING), send an HTTP DELETE request to problems.

The request body should be a JSON-encoded list of problem IDs; if the request body is empty, the request has no effect.

When possible, if you have more than one problem to cancel, submit them in a single query.

>>> id_list = ["74d9344c-0160-47bc-b7b1-e245b2ffd955",
...            "25f98470-bc55-476c-9042-120bbc0336cf"]
...
>>> r = session.delete(f"{SAPI_HOME}/problems", json=id_list)
$ id_list=[\"74d9344c-0160-47bc-b7b1-e245b2ffd955\",\"25f98470-bc55-476c-9042-120bbc0336cf\"]
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/problems -X DELETE -d $id_list

Cancel a Problem by ID

To cancel a previously submitted problem, make an HTTP DELETE request to problems/<problem_id>.

The request should contain no body.

>>> problem_id = "74d9344c-0160-47bc-b7b1-e245b2ffd955"
...
>>> r = session.delete(f"{SAPI_HOME}/problems/{problem_id}")
$ problem_id="74d9344c-0160-47bc-b7b1-e245b2ffd955"
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/problems/$problem_id -X DELETE

List Problems

To retrieve a list of previously submitted problems, send an HTTP GET request to problems.

The request should contain no body.

You can filter the results using one or more optional filter keys, concatenated with an ampersand (“&”).

>>> r = session.get(f"{SAPI_HOME}/problems/?max_results=3")
$ filter="solver=Advantage_system4.1&max_results=3"
$ curl  -H "X-Auth-Token: $SAPI_TOKEN" -X GET "$SAPI_HOME/problems/?$filter"

Retrieve a Problem

To retrieve a previously submitted problem, send an HTTP GET request to problems/<problem_id>.

The request should contain no body.

>>> problem_id = "74d9344c-0160-47bc-b7b1-e245b2ffd955"
...
>>> r = session.get(f"{SAPI_HOME}/problems/{problem_id}")
$ problem_id="74d9344c-0160-47bc-b7b1-e245b2ffd955"
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/problems/$problem_id -X GET

Retrieve Problem Information

To retrieve information about a problem, send an HTTP GET request to problems/<problem_id>/info:

The request should contain no body.

>>> problem_id = "74d9344c-0160-47bc-b7b1-e245b2ffd955"
...
>>> r = session.get(f"{SAPI_HOME}/problems/{problem_id}/info")
$ problem_id="74d9344c-0160-47bc-b7b1-e245b2ffd955"
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/problems/$problem_id/info -X GET

Retrieve an Answer

To retrieve an answer for a problem, send an HTTP GET request to problems/<problem_id>/answer.

The request should contain no body.

>>> problem_id = "74d9344c-0160-47bc-b7b1-e245b2ffd955"
...
>>> r = session.get(f"{SAPI_HOME}/problems/{problem_id}/answer")
$ problem_id="74d9344c-0160-47bc-b7b1-e245b2ffd955"
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/problems/$problem_id/answer -X GET

Retrieve Problem Messages

To retrieve messages for a problem, send an HTTP GET request to problems/<problem_id>/messages.

The request should contain no body.

>>> problem_id = "74d9344c-0160-47bc-b7b1-e245b2ffd955"
...
>>> r = session.get(f"{SAPI_HOME}/problems/{problem_id}/messages")
$ problem_id="74d9344c-0160-47bc-b7b1-e245b2ffd955"
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/problems/$problem_id/messages -X GET

Retrieve Available Solvers

To retrieve a list of available Leap solvers, send an HTTP GET request to solvers/remote.

The request should contain no body.

By default, all solver fields are returned. You can use the filter parameter to get a subset of solver fields.

>>> filter = urlencode({"filter": "none,+id,+status,+avg_load,+properties.num_qubits,+properties.category"})
...
>>> r = session.get(f"{SAPI_HOME}/solvers/remote/?{filter}")
$ filter="filter=none%2C%2Bid%2C%2Bstatus"
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/solvers/remote/?filter

Retrieve Solver Fields

To retrieve the fields of a solver, send an HTTP GET request to solvers/remote/<solver_id>.

By default, all solver fields are returned. You can use the filter parameter to get a subset of solver fields.

>>> solver_name = "Advantage_system4.1"
>>> r = session.get(f"{SAPI_HOME}/solvers/remote/{solver_name}")
$ solver_name="Advantage_system4.1"
$ filter="none%2C%2Bstatus%2C%2Bavg_load%2C%2Bproperties.num_qubits"
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/solvers/remote/$solver_name/?filter