Skip to main content

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}