spectre/analysis/
montecarlo.rs1use crate::{Input, Spectre};
4use serde::{Deserialize, Serialize};
5use std::fmt::{Display, Formatter};
6use std::ops::Deref;
7use substrate::simulation::data::Save;
8use substrate::simulation::{Analysis, Simulator, SupportedBy};
9use substrate::types::schematic::{NestedNode, NestedTerminal, RawNestedNode};
10use type_dispatch::impl_dispatch;
11
12#[derive(Copy, Clone, Default, Debug, Eq, PartialEq, Serialize, Deserialize)]
14pub enum Variations {
15 #[default]
17 Process,
18 Mismatch,
20 All,
22}
23
24impl Display for Variations {
25 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
26 write!(
27 f,
28 "{}",
29 match self {
30 Self::Process => "process",
31 Self::Mismatch => "mismatch",
32 Self::All => "all",
33 }
34 )
35 }
36}
37
38#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
40pub struct MonteCarlo<A> {
41 pub variations: Variations,
43 pub numruns: usize,
45 pub seed: Option<u64>,
47 pub firstrun: Option<usize>,
49 pub analysis: A,
51}
52
53#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
55pub struct Output<T>(pub(crate) Vec<T>);
56
57impl<T> Deref for Output<T> {
58 type Target = Vec<T>;
59
60 fn deref(&self) -> &Self::Target {
61 &self.0
62 }
63}
64
65impl<T> Output<T> {
66 pub fn into_inner(self) -> Vec<T> {
69 self.0
70 }
71}
72
73impl<A: SupportedBy<Spectre>> From<MonteCarlo<A>> for MonteCarlo<Vec<Input>> {
74 fn from(value: MonteCarlo<A>) -> Self {
75 let mut analysis = Vec::new();
76 value.analysis.into_input(&mut analysis);
77 MonteCarlo {
78 variations: value.variations,
79 numruns: value.numruns,
80 seed: value.seed,
81 firstrun: value.firstrun,
82 analysis,
83 }
84 }
85}
86
87#[impl_dispatch({NestedNode; RawNestedNode; NestedTerminal})]
88impl<T, A: Analysis> Save<Spectre, MonteCarlo<A>> for T
89where
90 T: Save<Spectre, A>,
91{
92 type SaveKey = <T as Save<Spectre, A>>::SaveKey;
93 type Saved = Vec<<T as Save<Spectre, A>>::Saved>;
94
95 fn save(
96 &self,
97 ctx: &substrate::simulation::SimulationContext<Spectre>,
98 opts: &mut <Spectre as Simulator>::Options,
99 ) -> <Self as Save<Spectre, MonteCarlo<A>>>::SaveKey {
100 self.save(ctx, opts)
101 }
102
103 fn from_saved(
104 output: &<MonteCarlo<A> as Analysis>::Output,
105 key: &<Self as Save<Spectre, MonteCarlo<A>>>::SaveKey,
106 ) -> <Self as Save<Spectre, MonteCarlo<A>>>::Saved {
107 output
108 .0
109 .iter()
110 .map(|output| T::from_saved(output, key))
111 .collect()
112 }
113}
114
115impl<A: Analysis> Analysis for MonteCarlo<A> {
143 type Output = Output<A::Output>;
144}
145
146impl<A: SupportedBy<Spectre>> SupportedBy<Spectre> for MonteCarlo<A> {
147 fn into_input(self, inputs: &mut Vec<<Spectre as Simulator>::Input>) {
148 inputs.push(self.into());
149 }
150 fn from_output(
151 outputs: &mut impl Iterator<Item = <Spectre as Simulator>::Output>,
152 ) -> <Self as Analysis>::Output {
153 let item = outputs.next().unwrap();
154 let output: Output<Vec<crate::Output>> = item.try_into().unwrap();
155 Output(
156 output
157 .0
158 .into_iter()
159 .map(|out| A::from_output(&mut out.into_iter()))
160 .collect(),
161 )
162 }
163}