Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export rust QCS ClientConfiguration to python #235

Merged
merged 46 commits into from
Jan 27, 2023
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
a712312
refactor(lib): remove unused module
Shadow53 Jan 6, 2023
47bf6e0
refactor(lib)!: use num::Complex instead of custom typedef
Shadow53 Jan 6, 2023
8a68b83
chore(lib): remove newly removed lint
Shadow53 Jan 6, 2023
fd97469
refactor(lib)!: use Cow<str> instead of &str for execution
Shadow53 Jan 6, 2023
c2879aa
style(lib): resolve clippy lints
Shadow53 Jan 6, 2023
aa729d1
feat(python): start directly wrapping types from the Rust SDK
Shadow53 Jan 6, 2023
dbbc6e3
refactor(lib)!: replace Box<str> -> String, &str -> Cow<str>
Shadow53 Jan 9, 2023
87a39e1
feat(python): wrap more types for Python
Shadow53 Jan 9, 2023
6ad951b
feat(python): add missing wrappers for remaining types
Shadow53 Jan 9, 2023
d1cf077
refactor(python): change how Complex64ReadoutValues converts to/from …
Shadow53 Jan 9, 2023
e847da7
chore(python): use rigetti-pyo3 from git, not local path
Shadow53 Jan 10, 2023
1ae1298
feat(python): define default arguments to methods
Shadow53 Jan 10, 2023
1136799
feat: add more constructor helpers to qpu client
jselig-rigetti Jan 19, 2023
2e3171f
chore: work in progress testing the qpu client
jselig-rigetti Jan 19, 2023
b352749
chore: mr cleanup
jselig-rigetti Jan 19, 2023
bc18576
chore: use nested pyi files
jselig-rigetti Jan 19, 2023
3461ee0
chore: clean up imports and declarations
jselig-rigetti Jan 19, 2023
e6fbbd1
chore: impl eq through __richcmp__
jselig-rigetti Jan 20, 2023
f0fc5b7
chore: type stubs for all exports
jselig-rigetti Jan 23, 2023
ef9a28e
doc(lib): explain seeming type disagreement
Shadow53 Jan 23, 2023
5600581
refactor(python): simplify code, remove TODO
Shadow53 Jan 23, 2023
7ef8bda
fix: typedict base class
jselig-rigetti Jan 23, 2023
c15aaea
Merge branch '208-return-pyo3-types' into 231-qcs-client-config
jselig-rigetti Jan 23, 2023
bfda07d
chore(python): remove unnecessary comments
Shadow53 Jan 24, 2023
258a664
refactor(lib): avoid confusion by changing Complex32 -> Complex<f32>
Shadow53 Jan 24, 2023
94c5a99
chore(python): bump minimum python version to 3.8
Shadow53 Jan 24, 2023
11002e2
chore(python): bump rigetti-pyo3
Shadow53 Jan 24, 2023
b9c91f3
chore(python): gitignore __pycache__
Shadow53 Jan 24, 2023
2babc4d
chore(lib): update tokio, disable unused warp features
Shadow53 Jan 24, 2023
01bf1d9
Merge branch '208-return-pyo3-types' into 231-qcs-client-config
jselig-rigetti Jan 24, 2023
e921666
chore: add import
jselig-rigetti Jan 24, 2023
f57b65f
fix: add methods for variants
jselig-rigetti Jan 24, 2023
601d2a4
Add `list_quantum_processors` helper (#234)
jselig-rigetti Jan 24, 2023
f5b819f
Merge branch 'main' into 231-qcs-client-config
jselig-rigetti Jan 24, 2023
ac2d5ea
chore: ignore api-bound pytest
jselig-rigetti Jan 24, 2023
e3595c1
chore(python): update pyi definitions and use better struct serializa…
jselig-rigetti Jan 25, 2023
1da3a51
chore(python): add pyo3 usage tests
jselig-rigetti Jan 25, 2023
a5b06c7
chore(python): update return type definition for executable methods
jselig-rigetti Jan 25, 2023
0977032
chore: make all attributes into properties
jselig-rigetti Jan 26, 2023
a146bb6
chore: make default timeout a static value
jselig-rigetti Jan 27, 2023
09cbd5e
chore: use fixed version of rigetti-pyo3
jselig-rigetti Jan 27, 2023
8300983
fix: mr feedback
jselig-rigetti Jan 27, 2023
a484284
fix: link formatting in comment
jselig-rigetti Jan 27, 2023
db1c96e
fix: use pyclass instead of wrappers
jselig-rigetti Jan 27, 2023
b93dcd4
fix: remove needless lifetime, per ci
jselig-rigetti Jan 27, 2023
c095c59
fix: mr suggestions
jselig-rigetti Jan 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ qcs-api/docs
# macOS
.DS_Store

# pytest artifacts
# Python artifacts
**/__pycache__
crates/python/qcs_sdk/*.so
12 changes: 6 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions crates/lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ lazy_static = "1.4.0"
log = "0.4.17"
num = { version = "0.4.0", features = ["serde"] }
qcs-api = "0.2.1"
qcs-api-client-common = "0.2.7"
qcs-api-client-openapi = "0.3.8"
qcs-api-client-grpc = "0.2.7"
qcs-api-client-common = "0.3.0"
qcs-api-client-openapi = "0.4.0"
qcs-api-client-grpc = "0.3.0"
quil-rs = "0.15"
reqwest = { version = "0.11.12", default-features = false, features = ["rustls-tls", "json"] }
rmp-serde = "1.1.1"
Expand All @@ -42,7 +42,7 @@ erased-serde = "0.3.23"
float-cmp = "0.9.0"
hex = "0.4.3"
maplit = "1.0.2"
qcs-api-client-grpc = { version = "0.2.7", features = ["server"] }
qcs-api-client-grpc = { version = "0.3.0", features = ["server"] }
simple_logger = { version = "2.3.0", default-features = false }
tempfile = "3.3.0"
tokio = { version = "1.21.2", features = ["macros", "rt-multi-thread"] }
Expand Down
54 changes: 53 additions & 1 deletion crates/lib/src/api.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! This module provides convenience functions to handle compilation,
//! translation, parameter arithmetic rewriting, and results collection.

use std::{collections::HashMap, str::FromStr};
use std::{collections::HashMap, str::FromStr, time::Duration};

use num::Complex;
use qcs_api_client_grpc::{
Expand All @@ -10,9 +10,11 @@ use qcs_api_client_grpc::{
get_controller_job_results_request::Target, GetControllerJobResultsRequest,
},
};
use qcs_api_client_openapi::apis::{quantum_processors_api, Error as OpenAPIError};
use quil_rs::expression::Expression;
use quil_rs::{program::ProgramError, Program};
use serde::Serialize;
use tokio::time::error::Elapsed;

use crate::qpu::{
self,
Expand Down Expand Up @@ -313,3 +315,53 @@ pub async fn retrieve_results(
.map(ExecutionResults::from)
.ok_or_else(|| GrpcClientError::ResponseEmpty("Controller Job Execution Results".into()))
}

/// API Errors encountered when trying to list available quantum processors.
#[derive(Debug, thiserror::Error)]
pub enum ListQuantumProcessorsError {
/// Failed the http call
#[error("Failed to list processors via API: {0}")]
ApiError(#[from] OpenAPIError<quantum_processors_api::ListQuantumProcessorsError>),

/// Pagination did not finish before timeout
#[error("API pagination did not finish before timeout: {0:?}")]
TimeoutError(#[from] Elapsed),
}

/// Query the QCS API for the names of all available quantum processors.
/// If `None`, the default `timeout` used is 10 seconds.
pub async fn list_quantum_processors(
client: &Qcs,
timeout: Option<Duration>,
) -> Result<Vec<String>, ListQuantumProcessorsError> {
let timeout = timeout.unwrap_or_else(|| Duration::from_secs(10));
Shadow53 marked this conversation as resolved.
Show resolved Hide resolved

tokio::time::timeout(timeout, async move {
let mut quantum_processors = vec![];
let mut page_token = None;

loop {
let result = quantum_processors_api::list_quantum_processors(
&client.get_openapi_client(),
Some(100),
page_token.as_deref(),
)
.await?;

let mut data = result
.quantum_processors
.into_iter()
.map(|qpu| qpu.id)
.collect::<Vec<_>>();
quantum_processors.append(&mut data);

page_token = result.next_page_token;
if page_token.is_none() {
break;
}
}

Ok(quantum_processors)
})
.await?
}
2 changes: 1 addition & 1 deletion crates/lib/src/executable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ impl Executable<'_, '_> {
if let Some(config) = &self.config {
Ok(config.clone())
} else {
let config = ClientConfiguration::load().await?;
let config = ClientConfiguration::load_default().await?;
self.config = Some(config.clone());
Ok(config)
}
Expand Down
4 changes: 3 additions & 1 deletion crates/lib/src/qpu/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ pub struct Qcs {
impl Qcs {
/// Create a [`Qcs`] and initialize it with the user's default [`ClientConfiguration`]
pub async fn load() -> Result<Self, LoadError> {
ClientConfiguration::load().await.map(Self::with_config)
ClientConfiguration::load_default()
.await
.map(Self::with_config)
}

/// Create a [`Qcs`] and initialize it with the given [`ClientConfiguration`]
Expand Down
9 changes: 6 additions & 3 deletions crates/python/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@ crate-type = ["cdylib"]

[dependencies]
qcs = { path = "../lib" }
qcs-api-client-common = "0.2.7"
qcs-api-client-grpc = "0.2.7"
qcs-api-client-common = "0.3.0"
qcs-api-client-grpc = "0.3.0"
pyo3 = { version = "0.17", features = ["extension-module"] }
pyo3-asyncio = { version = "0.17", features = ["tokio-runtime"] }
quil-rs = "0.15"
tokio = "1.21"
qcs-api = "0.2.1"
rigetti-pyo3 = { version = "0.1.0-rc.0", features = ["extension-module", "complex"] }
rigetti-pyo3 = { version = "0.1.0-rc.0", features = [
"extension-module",
"complex",
] }
serde_json = "1.0.86"

[build-dependencies]
Expand Down
166 changes: 0 additions & 166 deletions crates/python/qcs_sdk.pyi

This file was deleted.

4 changes: 4 additions & 0 deletions crates/python/qcs_sdk/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# See the following documentation for why this file is necessary:
# https://pyo3.rs/v0.18.0/python_typing_hints#__init__py-content

from .qcs_sdk import *
23 changes: 23 additions & 0 deletions crates/python/qcs_sdk/__init__.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from .api import *

from .qpu.client import (
QcsClient as QcsClient
)

from ._execution_data import (
QPU as QPU,
QVM as QVM,
ReadoutMap as ReadoutMap,
)

from ._executable import (
Executable as Executable,
ExeParameter as ExeParameter,
JobHandle as JobHandle,
QcsExecutionError as QcsExecutionError,
Service as Service,
)

from ._register_data import (
RegisterData as RegisterData,
)
Loading