#![cfg(not(target_arch = "wasm32"))]
use std::collections::HashMap;
use std::convert;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::{api, statevector::StateVector};
use crate::error::QasmSimError;
use crate::interpreter::{Computation, Histogram};
pub use api::get_gate_info;
pub use api::parse_and_link;
pub use api::simulate;
pub use api::simulate_with_shots;
macro_rules! measure {
($block:expr) => {{
use std::time::Instant;
let measurement = Instant::now();
let result = $block;
let elapsed = measurement.elapsed().as_millis();
(result, elapsed)
}};
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ExecutionTimes {
parsing_time: u128,
simulation_time: u128,
}
impl ExecutionTimes {
pub fn new(parsing_time: u128, simulation_time: u128) -> Self {
ExecutionTimes {
parsing_time,
simulation_time,
}
}
pub fn simulation_time(&self) -> u128 {
self.simulation_time
}
pub fn parsing_time(&self) -> u128 {
self.parsing_time
}
}
impl From<&[u128; 2]> for ExecutionTimes {
fn from(pair: &[u128; 2]) -> Self {
ExecutionTimes::new(pair[0], pair[1])
}
}
impl From<(u128, u128)> for ExecutionTimes {
fn from(pair: (u128, u128)) -> Self {
ExecutionTimes::new(pair.0, pair.1)
}
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Execution {
statevector: StateVector,
probabilities: Vec<f64>,
memory: HashMap<String, u64>,
histogram: Option<Histogram>,
times: ExecutionTimes,
}
impl Execution {
pub fn new(
statevector: StateVector,
probabilities: Vec<f64>,
memory: HashMap<String, u64>,
histogram: Option<Histogram>,
times: ExecutionTimes,
) -> Self {
Execution {
statevector,
probabilities,
memory,
histogram,
times,
}
}
pub fn statevector(&self) -> &StateVector {
&self.statevector
}
pub fn probabilities(&self) -> &Vec<f64> {
&self.probabilities
}
pub fn memory(&self) -> &HashMap<String, u64> {
&self.memory
}
pub fn histogram(&self) -> &Option<Histogram> {
&self.histogram
}
pub fn times(&self) -> &ExecutionTimes {
&self.times
}
}
impl convert::From<(Computation, u128, u128)> for Execution {
fn from(value: (Computation, u128, u128)) -> Self {
let (computation, parsing_time, simulation_time) = value;
Execution {
statevector: computation.statevector().clone(),
probabilities: computation.probabilities().to_vec(),
memory: computation.memory().clone(),
histogram: computation.histogram().clone(),
times: ExecutionTimes {
parsing_time,
simulation_time,
},
}
}
}
pub fn run(input: &str, shots: Option<usize>) -> api::Result<'_, Execution> {
let (linked, parsing_time) = measure!({ parse_and_link(input) });
let (out, simulation_time) = measure!({
match shots {
None => simulate(&linked?),
Some(shots) => simulate_with_shots(&linked?, shots),
}
});
let out = out.map_err(|err| QasmSimError::from((input, err)));
Ok(Execution::from((out?, parsing_time, simulation_time)))
}