#[cfg(feature = "unstable_chain_with_environment")]
use std::collections::HashMap;
#[cfg(feature = "unstable_qoqo_devices")]
use std::collections::HashSet;
use crate::RoqoqoBackendError;
#[cfg(feature = "unstable_qoqo_devices")]
use crate::{prelude::InvolveQubits, Circuit};
use ndarray::Array2;
mod generic_device;
pub use generic_device::GenericDevice;
mod all_to_all;
pub use all_to_all::AllToAllDevice;
mod square_lattice;
pub use square_lattice::SquareLatticeDevice;
pub trait Device {
fn single_qubit_gate_time(&self, hqslang: &str, qubit: &usize) -> Option<f64>;
fn single_qubit_gate_names(&self) -> Vec<String> {
self.to_generic_device().single_qubit_gate_names()
}
fn two_qubit_gate_names(&self) -> Vec<String> {
self.to_generic_device().two_qubit_gate_names()
}
fn multi_qubit_gate_names(&self) -> Vec<String> {
self.to_generic_device().multi_qubit_gate_names()
}
fn two_qubit_gate_time(&self, hqslang: &str, control: &usize, target: &usize) -> Option<f64>;
fn three_qubit_gate_time(
&self,
hqslang: &str,
control_0: &usize,
control_1: &usize,
target: &usize,
) -> Option<f64>;
fn multi_qubit_gate_time(&self, hqslang: &str, qubits: &[usize]) -> Option<f64>;
fn qubit_decoherence_rates(&self, qubit: &usize) -> Option<Array2<f64>>;
fn number_qubits(&self) -> usize;
fn two_qubit_edges(&self) -> Vec<(usize, usize)>;
#[allow(unused_variables)]
#[allow(unused_mut)]
fn change_device(&mut self, hqslang: &str, operation: &[u8]) -> Result<(), RoqoqoBackendError> {
Err(RoqoqoBackendError::GenericError {
msg: "The `change_device()` method has not been implemented.".to_string(),
})
}
fn to_generic_device(&self) -> GenericDevice;
}
#[cfg(feature = "unstable_qoqo_devices")]
pub trait QoqoDevice {
fn single_qubit_gate_time(&self, hqslang: &str, qubit: &usize) -> Option<f64>;
fn single_qubit_gate_names(&self) -> Vec<String>;
fn two_qubit_gate_names(&self) -> Vec<String>;
fn multi_qubit_gate_names(&self) -> Vec<String>;
fn two_qubit_gate_time(&self, hqslang: &str, control: &usize, target: &usize) -> Option<f64>;
#[allow(unused_variables)]
fn three_qubit_gate_time(
&self,
hqslang: &str,
control_0: &usize,
control_1: &usize,
target: &usize,
) -> Option<f64> {
None
}
fn multi_qubit_gate_time(&self, hqslang: &str, qubits: &[usize]) -> Option<f64>;
fn qubit_decoherence_rates(&self, qubit: &usize) -> Option<Array2<f64>>;
fn number_qubits(&self) -> usize;
fn longest_chains(&self) -> Vec<Vec<usize>>;
fn longest_closed_chains(&self) -> Vec<Vec<usize>>;
fn add_active_gate_noise(&self, circuit: &Circuit) -> Result<Circuit, RoqoqoBackendError> {
use crate::operations::GateOperation;
use crate::operations::InvolvedQubits;
let mut invovlved_qubits = HashSet::<usize>::new();
for op in circuit.iter() {
if let Ok(operation) = GateOperation::try_from(op) {
if let InvolvedQubits::Set(involved_set) = operation.involved_qubits() {
if invovlved_qubits.is_disjoint(&involved_set) {
invovlved_qubits.extend(involved_set)
} else {
return Err(RoqoqoBackendError::GenericError { msg: "Error add_active_gate_noise: Several unitary gates operate on same qubit in a parallel set of operations".to_string()});
}
}
}
}
Ok(circuit.clone())
}
fn two_qubit_edges(&self) -> Vec<(usize, usize)>;
#[allow(unused_variables)]
#[allow(unused_mut)]
fn change_device(&mut self, hqslang: &str, operation: &[u8]) -> Result<(), RoqoqoBackendError> {
Err(RoqoqoBackendError::GenericError {
msg: "The `change_device()` method has not been implemented.".to_string(),
})
}
}
#[cfg(feature = "unstable_chain_with_environment")]
pub type ChainAndEnvironment = (Vec<usize>, HashMap<usize, Vec<usize>>);
#[cfg(feature = "unstable_chain_with_environment")]
pub trait ChainWithEnvironmentDevice {
fn environment_chains(&self) -> Vec<ChainAndEnvironment>;
}