qoqo_qryd/lib.rs
1// Copyright © 2021-2022 HQS Quantum Simulations GmbH. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
4// in compliance with the License. You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software distributed under the
9// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
10// express or implied. See the License for the specific language governing permissions and
11// limitations under the License.
12
13#![deny(missing_docs)]
14#![deny(missing_crate_level_docs)]
15#![deny(missing_debug_implementations)]
16#![allow(ambiguous_glob_reexports)]
17
18//! # qoqo-qryd
19//!
20//! Components for the qoqo/roqoqo quantum toolkit by [HQS Quantum Simulations](https://quantumsimulations.de) that support QRyd quantum computers.
21//!
22//! The qoqo-qryd/roqoqo-qryd packages provide three components
23//!
24//! * devices: python/rust representation of QRyd devices
25//! * operations: roqoqo Pragma operations specific to QRyd devices that can change the topology of QRyd devices
26//! * simulator (optional): A QuEST based simulator for QRyd devices that checks the availability of the quantum operations on a chosen device during simulation
27
28#[cfg(feature = "web-api")]
29use pyo3::exceptions::PyValueError;
30use pyo3::prelude::*;
31use pyo3::types::PyDict;
32use pyo3::wrap_pymodule;
33
34/// qoqo utilities for QRyd quantum computers.
35///
36/// Provides devices for the QRyd quantum hardware for the qoqo quantum toolkit.
37/// Also provides qoqo PRAGMA operations specific to those devices.
38/// Includes an optional QRydSimulator backend.
39/// Furthermore, provides a collection of all QRyd as well as Tweezer devices for the WebAPI.
40///
41/// .. autosummary::
42/// :toctree: generated/
43///
44/// qryd_devices
45/// api_devices
46/// pragma_operations
47/// SimulatorBackend
48/// APIBackend
49/// tweezer_devices
50/// emulator_devices
51///
52pub mod qryd_devices;
53pub use qryd_devices::*;
54
55pub mod pragma_operations;
56pub use pragma_operations::*;
57
58/// QRyd Tweezer Devices.
59///
60pub mod tweezer_devices;
61pub use tweezer_devices::*;
62
63/// QRyd Emulator Devices.
64///
65pub mod emulator_devices;
66pub use emulator_devices::*;
67
68#[cfg(feature = "simulator")]
69pub mod simulator_backend;
70#[cfg(feature = "simulator")]
71pub use simulator_backend::SimulatorBackendWrapper;
72
73/// QRyd WebAPI Backend.
74///
75/// The WebAPI Backend implements methods available in the QRyd Web API.
76///
77#[cfg(feature = "web-api")]
78pub mod api_backend;
79#[cfg(feature = "web-api")]
80pub use api_backend::APIBackendWrapper;
81
82/// Collection of all QRyd devices for WebAPI.
83///
84/// At the moment only contains a square and a triangular device.
85///
86pub mod api_devices;
87pub use api_devices::*;
88
89/// Creates a new TweezerDevice instance containing populated tweezer data or EmulatorDevice instance.
90///
91/// This requires a valid QRYD_API_TOKEN. Visit `https://thequantumlaend.de/get-access/` to get one.
92///
93/// Args
94/// device_name (Optional[str]): The name of the device to instantiate. Defaults to "qryd_emulator".
95/// access_token (Optional[str]): An access_token is required to access QRYD hardware and emulators.
96/// The access_token can either be given as an argument here
97/// or set via the environmental variable `$QRYD_API_TOKEN`.
98/// seed (Optional[int]): Optionally overwrite seed value from downloaded device instance.
99/// dev (Optional[bool]): The boolean to set the dev header to.
100/// api_version (Optional[str]): The version of the QRYD API to use. Defaults to "v1_1".
101///
102/// Returns
103/// Union[TweezerDevice, EmulatorDevice]: Either the TweezerDevice or EmulatorDevice instance
104/// depending on the pulled information.
105///
106/// Raises:
107/// RoqoqoBackendError
108#[cfg(feature = "web-api")]
109#[pyfunction]
110pub fn device_from_api(
111 device_name: Option<String>,
112 access_token: Option<String>,
113 seed: Option<usize>,
114 dev: Option<bool>,
115 api_version: Option<String>,
116) -> PyResult<PyObject> {
117 Python::with_gil(|py| -> PyResult<PyObject> {
118 match roqoqo_qryd::device_from_api(device_name, access_token, seed, dev, api_version) {
119 Ok(device) => match device {
120 roqoqo_qryd::CombinedDevice::Tweezer(tweezer_device) => Ok(TweezerDeviceWrapper {
121 internal: tweezer_device,
122 }
123 .into_py(py)),
124 roqoqo_qryd::CombinedDevice::Emulator(emulator_device) => {
125 Ok(EmulatorDeviceWrapper {
126 internal: emulator_device,
127 }
128 .into_py(py))
129 }
130 },
131 Err(err) => Err(PyValueError::new_err(format!("{:}", err))),
132 }
133 })
134}
135
136/// QRyd utilities for qoqo quantum computation toolkit.
137///
138/// qoqo is the HQS python package to represent quantum circuits.
139///
140/// .. autosummary::
141/// :toctree: generated/
142///
143/// api_devices
144/// Backend
145/// pragma_operations
146/// qryd_devices
147/// tweezer_devices
148/// emulator_devices
149/// device_from_api
150///
151///
152#[pymodule]
153fn qoqo_qryd(_py: Python, module: &Bound<PyModule>) -> PyResult<()> {
154 #[cfg(feature = "simulator")]
155 module.add_class::<SimulatorBackendWrapper>()?;
156 #[cfg(feature = "web-api")]
157 module.add_class::<APIBackendWrapper>()?;
158 #[cfg(feature = "web-api")]
159 module.add_function(wrap_pyfunction!(device_from_api, module)?)?;
160 let wrapper = wrap_pymodule!(qryd_devices::qryd_devices);
161 module.add_wrapped(wrapper)?;
162 let wrapper = wrap_pymodule!(api_devices::api_devices);
163 module.add_wrapped(wrapper)?;
164 let wrapper = wrap_pymodule!(tweezer_devices::tweezer_devices);
165 module.add_wrapped(wrapper)?;
166 // Adding nice imports corresponding to maturin example
167 let wrapper = wrap_pymodule!(pragma_operations::pragma_operations);
168 module.add_wrapped(wrapper)?;
169 let wrapper = wrap_pymodule!(emulator_devices::emulator_devices);
170 module.add_wrapped(wrapper)?;
171 // Adding nice imports corresponding to maturin example
172 let system = PyModule::import_bound(_py, "sys")?;
173 let binding = system.getattr("modules")?;
174 let system_modules: &Bound<PyDict> = binding.downcast()?;
175 system_modules.set_item(
176 "qoqo_qryd.pragma_operations",
177 module.getattr("pragma_operations")?,
178 )?;
179 system_modules.set_item("qoqo_qryd.qryd_devices", module.getattr("qryd_devices")?)?;
180 system_modules.set_item("qoqo_qryd.api_devices", module.getattr("api_devices")?)?;
181 system_modules.set_item(
182 "qoqo_qryd.tweezer_devices",
183 module.getattr("tweezer_devices")?,
184 )?;
185 system_modules.set_item(
186 "qoqo_qryd.emulator_devices",
187 module.getattr("emulator_devices")?,
188 )?;
189 Ok(())
190}