1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
// Copyright © 2021-2023 HQS Quantum Simulations GmbH. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language governing permissions and
// limitations under the License.
#![deny(missing_docs)]
#![deny(rustdoc::missing_crate_level_docs)]
#![deny(missing_debug_implementations)]
//! Qoqo quantum computing toolkit
//!
//! Quantum Operation Quantum Operation
//! Yes we use [reduplication](https://en.wikipedia.org/wiki/Reduplication)
use pyo3::prelude::*;
use pyo3::types::PyDict;
use pyo3::wrap_pymodule;
pub mod operations;
pub mod measurements;
pub mod devices;
mod circuit;
pub use circuit::{convert_into_circuit, CircuitWrapper, OperationIteratorWrapper};
mod quantum_program;
pub use quantum_program::{convert_into_quantum_program, QuantumProgramWrapper};
pub mod noise_models;
#[cfg(feature = "circuitdag")]
mod circuitdag;
#[cfg(feature = "circuitdag")]
pub use circuitdag::{convert_into_circuitdag, CircuitDagWrapper};
/// qoqo version information, used for qoqo import/export checks
pub const QOQO_VERSION: &str = env!("CARGO_PKG_VERSION");
use roqoqo::{RoqoqoBackendError, RoqoqoError};
use thiserror::Error;
/// Errors that can occur in qoqo.
#[derive(Error, Debug, PartialEq)]
pub enum QoqoError {
/// Error an Operation cannot be extracted from PyAny object passed from python.
#[error("Converting PyAny to Operation not possible")]
ConversionError,
/// Error a Circuit cannot be extracted from PyAny object passed from python.
#[error("Cannot extract roqoqo object from python object")]
CannotExtractObject,
/// Error for version mismatch between separately compiled packages.
///
/// Error when trying to extract a roqoqo object from a PyAny python object that has been created
/// from a python package that has been compiled separately.
/// To avoid unexpected behaviour this is only allowed when qoqo and roqoqo in both packages are the same version.
#[error("Package versions of qoqo and roqoqo do not match versions of qoqo object passed from python")]
VersionMismatch,
/// Transparent forwarding of roqoqo errors.
#[error(transparent)]
RoqoqoError(#[from] RoqoqoError),
}
/// Errors that can occur in qoqo backends.
#[derive(Error, Debug, PartialEq)]
pub enum QoqoBackendError {
/// Error a Circuit cannot be extracted from PyAny object passed from python.
#[error("Cannot extract rust object from python object")]
CannotExtractObject,
/// Error for version mismatch between separately compiled packages.
///
/// Error when trying to extract a Backend or Device from a PyAny python object that has been created
/// from a python package that has been compiled separately.
/// To avoid unexpected behaviour this is only allowed when qoqo and roqoqo in both packages are the same version.
#[error("Package versions of qoqo backend and roqoqo backend do not match versions of qoqo object passed from python")]
VersionMismatch,
/// Transparent forwarding of roqoqo errors.
#[error(transparent)]
RoqoqoBackendError(#[from] RoqoqoBackendError),
}
/// Quantum Operation Quantum Operation (qoqo)
///
/// Yes, we use reduplication.
///
/// qoqo is the HQS python package to represent quantum circuits.
///
/// .. autosummary::
/// :toctree: generated/
///
/// Circuit
/// CircuitDag
/// QuantumProgram
/// operations
/// measurements
/// devices
/// noise_models
///
#[pymodule]
fn qoqo(_py: Python, module: &Bound<PyModule>) -> PyResult<()> {
module.add_class::<CircuitWrapper>()?;
module.add_class::<QuantumProgramWrapper>()?;
#[cfg(feature = "circuitdag")]
module.add_class::<CircuitDagWrapper>()?;
let wrapper = wrap_pymodule!(operations::operations);
module.add_wrapped(wrapper)?;
let wrapper2 = wrap_pymodule!(measurements::measurements);
module.add_wrapped(wrapper2)?;
let wrapper3 = wrap_pymodule!(devices::devices);
module.add_wrapped(wrapper3)?;
let wrapper4 = wrap_pymodule!(noise_models::noise_models);
module.add_wrapped(wrapper4)?;
// Adding nice imports corresponding to maturin example
let system = PyModule::import_bound(_py, "sys")?;
let binding = system.getattr("modules")?;
let system_modules: &Bound<PyDict> = binding.downcast()?;
system_modules.set_item("qoqo.operations", module.getattr("operations")?)?;
system_modules.set_item("qoqo.measurements", module.getattr("measurements")?)?;
system_modules.set_item("qoqo.devices", module.getattr("devices")?)?;
system_modules.set_item("qoqo.noise_models", module.getattr("noise_models")?)?;
Ok(())
}