use std::time::Duration;
use crate::client::{OpenApiClientError, Qcs, DEFAULT_HTTP_API_TIMEOUT};
use qcs_api_client_openapi::{
apis::{
quantum_processors_api::{
self, get_instruction_set_architecture, GetInstructionSetArchitectureError,
},
Error as OpenApiError,
},
models::InstructionSetArchitecture,
};
use tokio::time::error::Elapsed;
pub mod api;
mod execution;
#[cfg(feature = "experimental")]
pub mod experimental;
#[cfg(feature = "python")]
pub mod isa;
#[cfg(feature = "python")]
pub mod python;
pub mod result_data;
pub mod translation;
pub(crate) use execution::{Error as ExecutionError, Execution};
#[allow(clippy::module_name_repetitions)]
pub use result_data::{QpuResultData, ReadoutValues};
pub async fn get_isa(
quantum_processor_id: &str,
client: &Qcs,
) -> Result<InstructionSetArchitecture, GetIsaError> {
#[cfg(feature = "tracing")]
tracing::debug!(
"getting instruction set architecture for {}",
quantum_processor_id
);
get_instruction_set_architecture(&client.get_openapi_client(), quantum_processor_id)
.await
.map_err(OpenApiClientError::RequestFailed)
}
pub type GetIsaError = OpenApiClientError<GetInstructionSetArchitectureError>;
#[derive(Debug, thiserror::Error)]
pub enum ListQuantumProcessorsError {
#[error("Failed to list processors via API: {0}")]
ApiError(#[from] OpenApiError<quantum_processors_api::ListQuantumProcessorsError>),
#[error("API pagination did not finish before timeout.")]
TimeoutError(#[from] Elapsed),
}
pub async fn list_quantum_processors(
client: &Qcs,
timeout: Option<Duration>,
) -> Result<Vec<String>, ListQuantumProcessorsError> {
#[cfg(feature = "tracing")]
tracing::debug!("listing quantum processors");
let timeout = timeout.unwrap_or(DEFAULT_HTTP_API_TIMEOUT);
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?
}
#[derive(Debug, thiserror::Error)]
pub enum ListISAsError {
#[error("Failed to list processors via API: {0}")]
ApiError(#[from] OpenApiError<quantum_processors_api::ListInstructionSetArchitecturesError>),
#[error("API pagination did not finish before timeout.")]
TimeoutError(#[from] Elapsed),
}
pub async fn list_isas(
client: &Qcs,
timeout: Option<Duration>,
) -> Result<Vec<String>, ListISAsError> {
#[cfg(feature = "tracing")]
tracing::debug!("listing instruction set architectures");
let timeout = timeout.unwrap_or(DEFAULT_HTTP_API_TIMEOUT);
tokio::time::timeout(timeout, async move {
let mut quantum_processors = vec![];
let mut page_token = None;
loop {
let result = quantum_processors_api::list_instruction_set_architectures(
&client.get_openapi_client(),
Some(5),
page_token.as_deref(),
)
.await?;
let mut data = result
.instruction_set_architectures
.into_iter()
.map(|isa| isa.name)
.collect::<Vec<_>>();
quantum_processors.append(&mut data);
page_token = result.next_page_token;
if page_token.is_none() {
break;
}
}
Ok(quantum_processors)
})
.await?
}