Line data Source code
1 : // Copyright © 2021 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 : //! Traits defining the standard functions for roqoqo devices.
14 : //!
15 : //! Devices in roqoqo have two use cases:
16 : //!
17 : //! * Abstract devices: Contain abstract information for the model of a quantum computer and its parameters.
18 : //! They can be used to determine which Operations are available on a specific device model.
19 : //! A typical example are abstract linear chains of square lattices in which two-qubit operations are only
20 : //! available between neighbouring qubits.
21 : //!
22 : //! The abstract devices can also encode a noise model. Roqoqo noise models are in general based on a (pseudo) time
23 : //! needed to execute a quantum operation and Lindblad rates for the qubits in the device.
24 : //! Specifically in the noise model each qubit undergoes a continuous Lindblad-type decoherence time evolution:
25 : //!
26 : //! $$
27 : //! \frac{d}{dt}\rho = \sum_{i,j=0}^{2} M_{i,j} L_{i} \rho L_{j}^{\dagger} - \frac{1}{2} \{ L_{j}^{\dagger} L_i, \rho \} \\\\
28 : //! L_0 = \sigma^{+} \\\\
29 : //! L_1 = \sigma^{-} \\\\
30 : //! L_3 = \sigma^{z}
31 : //! $$
32 : //! Note that as long as gate times and decoherence rates are scaled inversely any kind of units can be used,
33 : //! but we recommend using nanoseconds and inverse nanosecconds as units for gate times and decoherence rates.
34 : //!
35 : //!
36 : //! * Actual hardware devices: These devices are provided by roqoqo backends and contain the necessary information for
37 : //! accessing the quantum computing hardware. The devices also encode a connectivity model
38 : //!
39 :
40 : use ndarray::Array2;
41 :
42 : use crate::RoqoqoBackendError;
43 :
44 : /// Trait for roqoqo devices.
45 : ///
46 : /// Defines standard functions available for roqoqo devices.
47 : pub trait Device {
48 : /// Returns the gate time of a single qubit operation if the single qubit operation is available on device.
49 : ///
50 : /// The base assumption
51 : ///
52 : /// # Arguments
53 : ///
54 : /// * `hqslang` - The hqslang name of a single qubit gate.
55 : /// * `qubit` - The qubit the gate acts on
56 : ///
57 : /// # Returns
58 : ///
59 : /// * `Some<f64>` - The gate time.
60 : /// * `None` - The gate is not available on the device.
61 : fn single_qubit_gate_time(&self, hqslang: &str, qubit: &usize) -> Option<f64>;
62 :
63 : /// Returns the gate time of a two qubit operation if the two qubit operation is available on device-.
64 : ///
65 : ///
66 : /// # Arguments
67 : ///
68 : /// * `hqslang` - The hqslang name of a two qubit gate.
69 : /// * `control` - The control qubit the gate acts on
70 : /// * `target` - The target qubit the gate acts on
71 : ///
72 : /// # Returns
73 : ///
74 : /// * `Some<f64>` - The gate time.
75 : /// * `None` - The gate is not available on the device.
76 : fn two_qubit_gate_time(&self, hqslang: &str, control: &usize, target: &usize) -> Option<f64>;
77 :
78 : /// Returns the gate time of a multi qubit operation if the multi qubit operation is available on device.
79 : ///
80 : ///
81 : /// # Arguments
82 : ///
83 : /// * `hqslang` - The hqslang name of a multi qubit gate.
84 : /// * `qubits` - The qubits the gate acts on
85 : ///
86 : /// # Returns
87 : ///
88 : /// * `Some<f64>` - The gate time.
89 : /// * `None` - The gate is not available on the device.
90 : fn multi_qubit_gate_time(&self, hqslang: &str, qubits: &[usize]) -> Option<f64>;
91 :
92 : /// Returns the matrix of the decoherence rates of the Lindblad equation.
93 : ///
94 : /// $$
95 : /// \frac{d}{dt}\rho = \sum_{i,j=0}^{2} M_{i,j} L_{i} \rho L_{j}^{\dagger} - \frac{1}{2} \{ L_{j}^{\dagger} L_i, \rho \} \\\\
96 : /// L_0 = \sigma^{+} \\\\
97 : /// L_1 = \sigma^{-} \\\\
98 : /// L_3 = \sigma^{z}
99 : /// $$
100 : ///
101 : /// # Arguments
102 : ///
103 : /// * `qubit` - The qubit for which the rate matrix M is returned
104 : ///
105 : /// # Returns
106 : ///
107 : /// * `Some<Array2<f64>>` - The decoherence rates.
108 : /// * `None` - The qubit is not part of the device.
109 : fn qubit_decoherence_rates(&self, qubit: &usize) -> Option<Array2<f64>>;
110 :
111 : /// Returns the number of qubits the device supports.
112 : fn number_qubits(&self) -> usize;
113 :
114 : /// Changes the device topology based on a Pragma operation.
115 : ///
116 : /// Specific devices and backends can allow changes to the device topology.
117 : /// These changes are represented by Pragma operations that are only available for
118 : /// the corresponding backend.
119 : /// This function provides a generic interface for changing the devices with the help of
120 : /// these Pragma operations.
121 : /// In normal operation the backend specific Pragma operations are wrapped in a [crate::operations::PragmaChangeDevice]
122 : /// wrapper operation and encoded in binary form with the [bincode] crate.
123 : /// This function takes the encoded binary representation, tries to deserialize it internally
124 : /// and applies the corresponding changes.
125 : ///
126 : /// For most devices the default behaviour is that the device cannot be changed
127 : /// and the function returns a corresponding RoqoqoBackendError
128 : ///
129 : /// # Arguments
130 : ///
131 : /// * `hqslang` - The hqslang name of the wrapped operation
132 : /// * `operation` - The Pragma operation encoded in binary form using the [bincode] crate
133 : #[allow(unused_variables)]
134 : #[allow(unused_mut)]
135 1 : fn change_device(&mut self, hqslang: &str, operation: &[u8]) -> Result<(), RoqoqoBackendError> {
136 1 : Err(RoqoqoBackendError::GenericError {
137 1 : msg: "The device ".to_string(),
138 1 : })
139 1 : }
140 : }
|