#![deny(missing_docs)]
#![warn(rustdoc::private_intra_doc_links)]
#![warn(rustdoc::missing_crate_level_docs)]
#![warn(rustdoc::missing_doc_code_examples)]
#![warn(rustdoc::private_doc_tests)]
#![deny(missing_debug_implementations)]
use qoqo_calculator::CalculatorError;
use qoqo_calculator::CalculatorFloat;
#[cfg(feature = "json_schema")]
use schemars::{
gen::SchemaGenerator,
schema::SchemaObject,
schema::{InstanceType, Schema},
JsonSchema,
};
use std::str::FromStr;
#[cfg(feature = "unstable_analog_operations")]
use struqture::StruqtureError;
use thiserror::Error;
pub const ROQOQO_VERSION: &str = env!("CARGO_PKG_VERSION");
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serialize", serde(try_from = "RoqoqoVersionSerializable"))]
#[cfg_attr(feature = "serialize", serde(into = "RoqoqoVersionSerializable"))]
struct RoqoqoVersion;
#[cfg(feature = "json_schema")]
impl JsonSchema for RoqoqoVersion {
fn schema_name() -> String {
"RoqoqoVersion".to_string()
}
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> Schema {
RoqoqoVersionSerializable::json_schema(gen)
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default)]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
struct RoqoqoVersionSerializable {
major_version: u32,
minor_version: u32,
}
impl TryFrom<RoqoqoVersionSerializable> for RoqoqoVersion {
type Error = RoqoqoError;
fn try_from(value: RoqoqoVersionSerializable) -> Result<Self, Self::Error> {
let mut rsplit = ROQOQO_VERSION.split('.').take(2);
let major_version = u32::from_str(
rsplit
.next()
.expect("Internal error: Version not conforming to semver"),
)
.expect("Internal error: Major version is not unsigned integer.");
let minor_version = u32::from_str(
rsplit
.next()
.expect("Internal error: Version not conforming to semver"),
)
.expect("Internal error: Minor version is not unsigned integer.");
if major_version != value.major_version {
return Err(RoqoqoError::VersionMissmatch {
library_major_version: major_version,
library_minor_version: minor_version,
data_major_version: value.major_version,
data_minor_version: value.minor_version,
});
}
if major_version == 0 {
if minor_version != value.minor_version {
return Err(RoqoqoError::VersionMissmatch {
library_major_version: major_version,
library_minor_version: minor_version,
data_major_version: value.major_version,
data_minor_version: value.minor_version,
});
}
} else if minor_version < value.minor_version {
return Err(RoqoqoError::VersionMissmatch {
library_major_version: major_version,
library_minor_version: minor_version,
data_major_version: value.major_version,
data_minor_version: value.minor_version,
});
}
Ok(RoqoqoVersion)
}
}
impl From<RoqoqoVersion> for RoqoqoVersionSerializable {
fn from(_: RoqoqoVersion) -> Self {
let mut rsplit = ROQOQO_VERSION.split('.').take(2);
let major_version = u32::from_str(
rsplit
.next()
.expect("Internal error: Version not conforming to semver"),
)
.expect("Internal error: Major version is not unsigned integer.");
let minor_version = u32::from_str(
rsplit
.next()
.expect("Internal error: Version not conforming to semver"),
)
.expect("Internal error: Minor version is not unsigned integer.");
RoqoqoVersionSerializable {
major_version,
minor_version,
}
}
}
#[inline]
fn update_roqoqo_version(
current_minimum_version: &mut (u32, u32, u32),
comparison_version: (u32, u32, u32),
) {
if current_minimum_version.0 < comparison_version.0
|| current_minimum_version.1 < comparison_version.1
|| current_minimum_version.2 < comparison_version.2
{
*current_minimum_version = comparison_version;
}
}
#[derive(Error, Debug, PartialEq)]
pub enum RoqoqoError {
#[error("Resulting gate matrix is not unitary. Please check values of alpha and beta: alpha_r: {alpha_r:?}, alpha_i: {alpha_i:?}, beta_r: {beta_r:?}, beta_i: {beta_i:?}, norm: {norm:?}.")]
UnitaryMatrixErrror {
alpha_r: f64,
alpha_i: f64,
beta_r: f64,
beta_i: f64,
norm: f64,
},
#[error("Mapping failed. Qubit map maps to qubit {qubit:?} but not from {qubit:?}")]
QubitMappingError {
qubit: usize,
},
#[error("Conversion from {start_type} to {end_type} failed")]
ConversionError {
start_type: &'static str,
end_type: &'static str,
},
#[error("TryFrom conversion failed")]
TryFromError,
#[error("Qubits {squbit} and {oqubit} incompatible. Gates acting on different qubits can not be multiplied.")]
MultiplicationIncompatibleQubits {
squbit: usize,
oqubit: usize,
},
#[error("Pauli product involves qubit {pp_qubit} but number qubits is lower {number_qubits}.")]
PauliProductExceedsQubits {
pp_qubit: usize,
number_qubits: usize,
},
#[error(
"Index of operator {index:?} exceeds Hilbert space dimension of {number_qubits} qubits."
)]
MismatchedOperatorDimension {
index: (usize, usize),
number_qubits: usize,
},
#[error(
"Dimension of register {dim:?} exceeds Hilbert space dimension of {number_qubits} qubits."
)]
MismatchedRegisterDimension {
dim: usize,
number_qubits: usize,
},
#[error("Name {name} of expectation value already taken.")]
ExpValUsedTwice {
name: String,
},
#[error("OutputRegister {name} is missing.")]
MissingRegister {
name: String,
},
#[error("Error occured in basis rotation measurement. {msg}")]
PauliZProductMeasurementError {
msg: String,
},
#[error("An error occured serializing a roqoqo object: {msg} ")]
SerializationError {
msg: String,
},
#[error("An error occured in roqoqo: {msg} ")]
GenericError {
msg: String,
},
#[error("Trying to deserialize data created with incompatible version of roqoqo Library version: {library_major_version}.{library_minor_version} Data version: {data_major_version}.{data_minor_version}. Try to convert data with roqoqo data conversion tool.")]
VersionMissmatch {
library_major_version: u32,
library_minor_version: u32,
data_major_version: u32,
data_minor_version: u32,
},
#[error(transparent)]
CalculatorError(#[from] CalculatorError),
#[cfg(feature = "unstable_analog_operations")]
#[error(transparent)]
StruqtureError(#[from] StruqtureError),
}
#[derive(Error, Debug, PartialEq)]
pub enum RoqoqoBackendError {
#[error("Operation {hqslang} not supported by backend {hqslang}: ")]
OperationNotInBackend {
backend: &'static str,
hqslang: &'static str,
},
#[error("Backend authentification information is missing: {msg} ")]
MissingAuthentification {
msg: String,
},
#[error("NetworkError communicating with: {msg} ")]
NetworkError {
msg: String,
},
#[error("Backend timed out: {msg} ")]
Timeout {
msg: String,
},
#[error("The file at this location already exists: {path} ")]
FileAlreadyExists {
path: String,
},
#[error("An error occured in the backend: {msg} ")]
GenericError {
msg: String,
},
#[error(transparent)]
RoqoqoError(#[from] RoqoqoError),
#[error(transparent)]
CalculatorError(#[from] CalculatorError),
}
#[cfg(feature = "json_schema")]
pub(crate) struct Complex64Def;
#[cfg(feature = "json_schema")]
impl JsonSchema for Complex64Def {
fn schema_name() -> String {
"Complex64".to_string()
}
fn json_schema(gen: &mut SchemaGenerator) -> Schema {
let mut schema = SchemaObject {
instance_type: Some(InstanceType::Number.into()),
..Default::default()
};
let obj = schema.object();
obj.required.insert("re".to_owned());
obj.required.insert("im".to_owned());
obj.properties
.insert("re".to_owned(), <f64>::json_schema(gen));
obj.properties
.insert("im".to_owned(), <f64>::json_schema(gen));
schema.into()
}
}
#[cfg(feature = "json_schema")]
pub(crate) struct Array1C64Def;
#[cfg(feature = "json_schema")]
impl JsonSchema for Array1C64Def {
fn schema_name() -> String {
"Array1_Complex64".to_string()
}
fn json_schema(gen: &mut SchemaGenerator) -> Schema {
let mut schema = SchemaObject {
instance_type: Some(InstanceType::Object.into()),
..Default::default()
};
let obj = schema.object();
obj.required.insert("v".to_owned());
obj.required.insert("dim".to_owned());
obj.required.insert("data".to_owned());
obj.properties
.insert("v".to_owned(), <u8>::json_schema(gen));
obj.properties
.insert("dim".to_owned(), <Vec<u8>>::json_schema(gen));
obj.properties.insert(
"data".to_owned(),
<Vec<Vec<Complex64Def>>>::json_schema(gen),
);
schema.into()
}
}
#[cfg(feature = "json_schema")]
pub(crate) struct Array2C64Def;
#[cfg(feature = "json_schema")]
impl JsonSchema for Array2C64Def {
fn schema_name() -> String {
"Array2_Complex64".to_string()
}
fn json_schema(gen: &mut SchemaGenerator) -> Schema {
let mut schema = SchemaObject {
instance_type: Some(InstanceType::Object.into()),
..Default::default()
};
let obj = schema.object();
obj.required.insert("v".to_owned());
obj.required.insert("dim".to_owned());
obj.required.insert("data".to_owned());
obj.properties
.insert("v".to_owned(), <u8>::json_schema(gen));
obj.properties
.insert("dim".to_owned(), <Vec<u8>>::json_schema(gen));
obj.properties.insert(
"data".to_owned(),
<Vec<Vec<Complex64Def>>>::json_schema(gen),
);
schema.into()
}
}
#[cfg(feature = "json_schema")]
pub(crate) struct Array2f64Def;
#[cfg(feature = "json_schema")]
impl JsonSchema for Array2f64Def {
fn schema_name() -> String {
"Array2_f64".to_string()
}
fn json_schema(gen: &mut SchemaGenerator) -> Schema {
let mut schema = SchemaObject {
instance_type: Some(InstanceType::Object.into()),
..Default::default()
};
let obj = schema.object();
obj.required.insert("v".to_owned());
obj.required.insert("dim".to_owned());
obj.required.insert("data".to_owned());
obj.properties
.insert("v".to_owned(), <u8>::json_schema(gen));
obj.properties
.insert("dim".to_owned(), <Vec<u8>>::json_schema(gen));
obj.properties
.insert("data".to_owned(), <Vec<f64>>::json_schema(gen));
schema.into()
}
}
#[doc(hidden)]
mod circuit;
pub use circuit::Circuit;
#[doc(hidden)]
pub use circuit::*;
#[cfg(feature = "circuitdag")]
mod circuitdag;
#[cfg(feature = "circuitdag")]
pub use circuitdag::CircuitDag;
pub mod backends;
pub mod devices;
pub mod measurements;
pub mod operations;
pub mod prelude;
#[doc(hidden)]
mod quantum_program;
pub mod registers;
pub use quantum_program::QuantumProgram;
pub mod noise_models;