Writing a New Provider
A step-by-step guide to implementing a new provider class.
Overview
To integrate a quantum device or simulator with qBraid Runtime, you’ll need to create a custom provider class. A provider includes a
collection of devices and runtime specifications. Each QuantumProvider
should implement a get_devices
method to retrieve
QuantumDevice
objects, which describe the device’s supported operations, the program types accepted as run input, and other
dynamic runtime instructions. Finally, devices must implement a submit()
method to execute or
queue programs, returning a QuantumJob
object. This standardization allows users and APIs to uniformly submit jobs and retrieve
results, ensuring compatibility across different providers and devices.
Here are the high-level components required to establish a complete runtime implementation:
Provider Setup
Implement a QuantumProvider
subclass that manages authentication and
remote access to the available device(s).
Device + Runtime Configuration
Implement a QuantumDevice
subclass and its submit()
method. Optionally
incorporate a custom ConversionScheme
to broaden the range of quantum
program types that can be accepted as run input.
Job Management
Implement a QuantumJob
subclass that handles interactions with a running
job. Optionally incorporate a QuantumJobResult
subclass to systematically
process and present data collected from job executions.
QuantumProvider
The provider class is responsible for managing interactions with various quantum services and for converting device metadata into accessible Python objects.
For a simple provider implementation example, see qbraid.runtime.ionq.provider.py ↗
Server Requests
Creating a provider class requires the following REST API endpoints:
GET
/devices
(or similar) - To retrieve metadata about available quantum devices.POST
/job
(or similar) - To submit a quantum job for execution on a specified device.GET
/job
(or similar) - To retrieve the status and results of an executed quantum job.
If you already have a Python client for interacting with your REST API server, you can skip this section and go directly to Provider Setup.
For those who need to set up a Python client, the qbraid.runtime.Session
, a subclass of requests.Session,
is designed to manage secure HTTP connections to custom endpoints. It ensures encrypted and authenticated communication for quantum
providers and offers customizations for management of headers and secret keys, configurable retries for 5xx
errors, and more.
Below is a minimal example demonstrating how one could set up authenticated requests to the previously mentioned endpoints:
In the above example, base_url
corresponds to your API endpoint. The qBraid Session
class distinguishes between headers
and auth_headers
, ensuring that values in auth_headers
are masked in all responses to safeguard against the inadvertent
exposure of secret keys.
The qBraid Session
class offers additional customizable options such as the total number of retries for requests, the number
of connection retries, the backoff factor between retry attempts, and more. For further details, refer to the linked
API Reference below.
API Reference:
qbraid.runtime.Session ↗
TargetProfile
The qbraid.runtime.TargetProfile
encapsulates the configuration settings and runtime protocol(s) for a quantum device, presenting
them as a read-only dictionary. This class plays a crucial role in orchestrating the processes required for the submission of
quantum jobs in the current environment.
Specifically, the TargetProfile
class specifies domain and device-specific instructions to tailor quantum programs to the
intermediate representation (IR) required for submission through the provider’s API and execution on the quantum backend. This
includes compilation steps, type conversions, data mappings, and other essential runtime transformations.
Below is an example implementation of a TargetProfile:
API Reference:
qbraid.runtime.TargetProfile ↗
Provider Setup
Each QuantumProvider
subclass must implement both a get_device
and a get_devices
method. These methods process raw device data,
adapting it into a TargetProfile
for each device, and return either a single QuantumDevice
object or a list of them. In this example,
we use the MySession
class to handle API requests; however, this is illustrative and not mandatory. API interactions can also be managed
directly through other means.
In cases where the API data does not directly conform to the format needed to instantiate a TargetProfile
, additional mappings and
adaptations will typically be necessary. Below is an example implementation of a provider using MySession
to construct a MyDevice
object. We will explore implementations of QuantumDevice
subclasses in the next section.
API Reference:
qbraid.runtime.QuantumProvider ↗
QuantumDevice
The qbraid.runtime.QuantumDevice
class describes the unique parameters and operational settings necessary for executing quantum
programs on specific hardware.
API Reference:
qbraid.runtime.QuantumDevice ↗
The device objects are the core component of the providers. These objects are how users can interface between
quantum computing frameworks and hardware/simulators to execute circuits. Any QuantumDevice
subclass must
implement both a status
and submit
method.
A minimum working example could look like:
QuantumJob
The qbraid.runtime.QuantumJob
class represents the transitional states of quantum programs, managing both ongoing and completed
quantum computations.
API Reference:
qbraid.runtime.QuantumJob ↗