microsoft/qdk
Publicmirrored fromhttps://github.com/microsoft/qdkAvailable
source/resource_estimator/src/estimates/layout.rs
100lines · modecode
| 1 | // Copyright (c) Microsoft Corporation. |
| 2 | // Licensed under the MIT License. |
| 3 | |
| 4 | use serde::Serialize; |
| 5 | |
| 6 | use super::Error; |
| 7 | use super::{ErrorBudget, ErrorBudgetStrategy}; |
| 8 | |
| 9 | /// Trait to model post-layout logical overhead |
| 10 | pub trait Overhead { |
| 11 | /// The number of logical qubits to execute the algorithm after mapping |
| 12 | /// |
| 13 | /// This number does not include qubit used to produce magic states. |
| 14 | fn logical_qubits(&self) -> Result<u64, String>; |
| 15 | |
| 16 | /// The number of logical unit cycles to execute the algorithm |
| 17 | /// |
| 18 | /// This number is a lower bound for the execution time of the algorithm, |
| 19 | /// and might be extended by assuming no-ops. |
| 20 | fn logical_depth(&self, budget: &ErrorBudget) -> Result<u64, String>; |
| 21 | |
| 22 | /// The number of magic states |
| 23 | /// |
| 24 | /// The index is used to indicate the type of magic states and must be |
| 25 | /// supported by available factory builders in the physical estimation. |
| 26 | fn num_magic_states(&self, budget: &ErrorBudget, index: usize) -> Result<u64, String>; |
| 27 | |
| 28 | /// When implemented, prunes the error budget with respect to the provided |
| 29 | /// strategy |
| 30 | #[allow(unused_variables)] |
| 31 | fn prune_error_budget(&self, budget: &mut ErrorBudget, strategy: ErrorBudgetStrategy) {} |
| 32 | } |
| 33 | |
| 34 | /// This is the realized logical overhead after applying an error budget. This |
| 35 | /// structure has two purposes: 1) it is used to store the realized logical |
| 36 | /// overhead, once the error budget partition is decided into the resource |
| 37 | /// estimation result; 2) it can be used to pass a logical overhead to the |
| 38 | /// resource estimation API, if it does not depend on the error budget, since it |
| 39 | /// also implements the [`Overhead`] trait. |
| 40 | #[derive(Serialize)] |
| 41 | #[serde(rename_all = "camelCase")] |
| 42 | pub struct RealizedOverhead { |
| 43 | logical_qubits: u64, |
| 44 | logical_depth: u64, |
| 45 | num_magic_states: Vec<u64>, |
| 46 | } |
| 47 | |
| 48 | impl RealizedOverhead { |
| 49 | pub fn from_overhead( |
| 50 | overhead: &impl Overhead, |
| 51 | budget: &ErrorBudget, |
| 52 | num_magic_state_types: usize, |
| 53 | ) -> Result<Self, Error> { |
| 54 | let logical_qubits = overhead |
| 55 | .logical_qubits() |
| 56 | .map_err(Error::AlgorithmicLogicalQubitsComputationFailed)?; |
| 57 | let logical_depth = overhead |
| 58 | .logical_depth(budget) |
| 59 | .map_err(Error::AlgorithmicLogicalDepthComputationFailed)?; |
| 60 | let num_magic_states = (0..num_magic_state_types) |
| 61 | .map(|index| overhead.num_magic_states(budget, index)) |
| 62 | .collect::<Result<_, _>>() |
| 63 | .map_err(Error::NumberOfMagicStatesComputationFailed)?; |
| 64 | |
| 65 | Ok(Self { |
| 66 | logical_qubits, |
| 67 | logical_depth, |
| 68 | num_magic_states, |
| 69 | }) |
| 70 | } |
| 71 | |
| 72 | #[must_use] |
| 73 | pub fn logical_qubits(&self) -> u64 { |
| 74 | self.logical_qubits |
| 75 | } |
| 76 | |
| 77 | #[must_use] |
| 78 | pub fn logical_depth(&self) -> u64 { |
| 79 | self.logical_depth |
| 80 | } |
| 81 | |
| 82 | #[must_use] |
| 83 | pub fn num_magic_states(&self) -> &[u64] { |
| 84 | &self.num_magic_states |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | impl Overhead for RealizedOverhead { |
| 89 | fn logical_qubits(&self) -> Result<u64, String> { |
| 90 | Ok(self.logical_qubits) |
| 91 | } |
| 92 | |
| 93 | fn logical_depth(&self, _budget: &ErrorBudget) -> Result<u64, String> { |
| 94 | Ok(self.logical_depth) |
| 95 | } |
| 96 | |
| 97 | fn num_magic_states(&self, _budget: &ErrorBudget, index: usize) -> Result<u64, String> { |
| 98 | Ok(self.num_magic_states[index]) |
| 99 | } |
| 100 | } |
| 101 | |