qcs-sdk-rust
The qcs crate is a high-level interface to Rigetti's Quantum Cloud Services,
allowing Rust developers to run Quil programs on Rigetti's QPUs.
This crate is a Rust port of PyQuil, though it currently has a much smaller feature set.
For the C-bindings to this library, check out qcs-sdk-c
Documentation
This crate is documented primarily via rustdoc comments and examples, which are available on docs.rs.
Features
The crate supports several features, and some of them imply others, forming a DAG:
| Feature | Description | Implied Features |
|---|---|---|
manual-tests |
Used to run tests that require some manual setup. | |
experimental |
Enables experimental features specific to Rigetti QPUs. | |
tracing |
Enables the tracing features in qcs-api-client-* crates. |
|
tracing-config |
Enables the tracing-config features in qcs-api-client-* crates. |
tracing |
tracing-opentelemetry |
Enables tracing with OpenTelemetry. | tracing-config |
python |
Exposes Python bindings via PyO3. | experimental, tracing-opentelemtry |
stubs |
Enables Python typing for stub generation. | python |
In addition, there currently exists the feature _insecure-issuer-validation
which enables a feature of the same name in the qcs-api-client-common crate.
The purpose of the feature there, as here, is to relax token issuer validation during testing.
It is not intended to be used in production, and not considered part of the public API.
Changes Post Crate Merge
Prior to v0.21 (for Python users) and v0.25 (for Rust users),
this repository maintained separate a crate to expose Python bindings to this library.
Starting at the above versions, we've merged those crate together,
supported by the python feature flag.
With this change, we've united the version numbers for packages.
The new version comes with breaking changes for Python users,
which are summarized below and detailed in the CHANGELOG.
For the trouble, we now support the latest versions of PyO3 and Python.
This comes with improvements to security, stability, and performance
and makes our codebase much easier to support moving forward.
Rust Breaking Changes
For Rust consumers,
the previously Unit-variants of the qvm::api::AddressRequest enum
are now empty tuple variants to make them compatible with PyO3's "Complex enums".
That means the following variants must have () appended to their usages:
// Previously you could use this:
match address_request
// Now you must use this:
match address_request
Python Breaking Changes
For Python consumers, please be aware of the following changes:
- We are dropping support for Python 3.9 and adding support through Python 3.13.
- We no longer wrap Rust types with an additional layer for Python interop,
but instead directly expose them as
#[pyclass]es; in particular, thefrom_*,as_*,to_*,is_*, andinnermethods have been removed, You should replace their usage with more typical Python operations (see below for examples). - Some Python classes that conceptually represented a collection of possible types
now operate as if they were simply a type alias of those possibilities:
- The
Registerclass is now simplylist[int] | list[complex]. - The ISA
Familyenumeration is now a simple enum of known values; unknown values are represented simply as theirstrname. - These classes remain "Complex Enums" with different class variants,
but in many cases, functions and constructors have been updated
to accept any of the aliased varaints, and the
innermethod returns the same:RegisterData:list[list[int]] | list[list[float]] | list[list[complex]]ReadoutValues:list[int] | list[float] | list[complex]MemoryValues:list[int] | list[float]
- The
compiler.quilc.CompilationResult.programis now aquil.Programinstead of astr. To obtain thestrrepresentation, simply callto_quil()on the program.Service.Quilchas been renamedService.QUILCto match other Python enumeration variants.ExecutionDatanow requiresresult_data, whereas it had been optional forpicklesupport. Constructing it without explicitresult_datais almost certainly a bug, so now that it implements__getnewargs__, theresult_dataparameter is required.- Most synchronous wrappers around
_asyncmethods and functions now raise an error if used within an async context. You should useawaitand the_asyncmethod instead. Although some synchronous wrappers may happen to work within an async context incidentally, it is not officially supported behavior, and you should use their async counterparts.
Specific Python Examples
Instead of using from_*, just use the target class's constructor directly.
For example:
- readout_value = ReadoutValues.from_integer([0, 1])
+ readout_value = ReadoutValues.Integer([0, 1])
Replace is_*, to_*, as_*, and inner with match.
Here's an example of extracting inner elements:
:
:
return
:
If needed, you can replace inner with _0, usually paired with an isinstance check.
Keep in mind that enumerated subclasses are often named after the class they take as a parameter.
The following asserts are all valid:
=
assert
assert
assert ==
Development
Most development tasks are automated with cargo-make (like make,
but you can have dependencies on other Rust tools and a ton of useful tasks are built in).
Install cargo-make by doing cargo install cargo-make.
Then you can invoke it with either cargo make <task> or makers <task>.
Tasks are defined in files called Makefile.toml.
In order to run all checks exactly the same way that CI does, use makers ci-flow from the project root (workspace).
Dependencies
Because this library relies on [ØMQ], [cmake] is required:
- macOS [Homebrew] :
brew install cmake - Windows [Chocolatey]:
choco install cmake - Debian:
apt install cmake
Running Tests
The best way to go about this is via makers or cargo make with no task.
This will default to dev-test-flow which formats all code, builds, and tests everything.
Any tests which cannot be run in CI should be run with makers manual.
These tests require configured QCS credentials with access to internal functions,
as well as a connection to the Rigetti VPN.
Linting
makers lint will lint run all static checks.
Documentation
To build the docs.rs-style docs, run makers docs.
You can also do makers serve-docs to launch a local webserver for viewing immediately.
Release
To release this crate, manually run the release workflow in GitHub Actions.