adapton_lab/labdef.rs
1//use adapton::engine::Cnt; // Counters for engine costs
2use adapton::engine::Name; // Names, for naming things uniquely
3use adapton::reflect::DCG;
4use adapton::reflect::Val;
5use adapton::reflect::trace::Trace;
6use rand::Rng;
7use std::marker::PhantomData;
8
9/// A bit that controls how names are placed in the input; See `README.md` for more.
10#[derive(Clone,Debug)]
11pub enum NominalStrategy {
12 Regular,
13 ByContent,
14}
15
16/// Parameters for generating and editing input; See `README.md` for more.
17#[derive(Clone,Debug)]
18pub struct GenerateParams {
19 pub size: usize,
20 pub gauge: usize,
21 pub nominal_strategy:NominalStrategy
22}
23
24/// Generic method for generating a random input.
25/// See `README.md` for more.
26pub trait Generate<T> {
27 fn generate<R:Rng>(rng:&mut R, params:&GenerateParams) -> T;
28}
29
30/// Generic process for editing an input randomly, in a stateful sequence of edits.
31/// See `README.md` for more.
32pub trait Edit<T,S> : Clone {
33 fn edit_init<R:Rng>(rng:&mut R, params:&GenerateParams) -> S;
34 fn edit<R:Rng>(pre_edit:T, edit_state:S, rng:&mut R, params:&GenerateParams) -> (T, S);
35}
36
37/// Generic notion of a computation to run naively and incrementally.
38/// It has specific `Input` and `Output` types, and a way to `compute`
39/// the `Output` from the `Input`.
40/// See `README.md` for more.
41pub trait Compute<Input,Output> {
42 fn compute(Input) -> Output;
43}
44
45/// Like Compute, but also provides a `demand` size, for lazy algorithms.
46pub trait ComputeDemand<Input,Output> {
47 fn compute(Input, usize) -> Output;
48}
49
50impl<Input,Output,X:Compute<Input,Output>> ComputeDemand<Input,Output> for X {
51 fn compute(inp:Input, _demand:usize) -> Output {
52 X::compute(inp)
53 }
54}
55
56/// _lab definition_: generic notion of an incremental computation
57/// that can be evaluated and tested. We instantiate this structure
58/// once for each test in our test suite. We implement the `LabDef`
59/// trait generically for this structure. See `catalog` module for
60/// example instances.
61pub struct LabDef<Input,EditSt,Output,
62 Editor: Generate<Input>+Edit<Input,EditSt>,
63 Archivist:ComputeDemand<Input,Output>>
64{
65 pub identity: Name,
66 pub url: Option<String>,
67
68 pub editor: PhantomData<Editor>,
69 pub archivist: PhantomData<Archivist>,
70
71 pub input: PhantomData<Input>,
72 pub editst: PhantomData<EditSt>,
73 pub output: PhantomData<Output>
74}
75
76/// _lab_: Abstracts over parts of a lab definition of type `LabDef`:
77/// Hides the `Input`, `Output` and `Archivist` types of a `LabDef`.
78pub trait Lab {
79 fn name(self:&Self) -> Name;
80 fn url(self:&Self) -> &Option<String>;
81 fn run(self:&Self, params:&LabParams) -> LabResults;
82}
83
84/// Parameters to running a single lab experiment.
85#[derive(Clone,Debug)]
86pub struct LabParams {
87 pub sample_params: SampleParams,
88 // TODO: Pretty-print input and output structures; graphmovie dump of experiment
89 /// Number of change-batches to perform in a loop; each is interposed with computing the new output.
90 pub change_batch_loopc: usize,
91}
92
93/// Parameters for collecting a single sample. In addition to these
94/// parameters, the experiment maintains a Rng based on the
95/// input_seeds, below; this Rng is given to Edit::edit to generate
96/// psuedo-random edits, in batches. For each engine, this Rng is
97/// sequenced across successive samples. Given an input_seeds vector,
98/// there is one unique Rng sequence for each engine's sequence of
99/// samples.
100#[derive(Clone,Debug)]
101pub struct SampleParams {
102 /// We convert this seed into a random-number-generator before generating and editing.
103 pub input_seeds: Vec<usize>,
104 /// Other parameters for generating the input.
105 pub generate_params: GenerateParams,
106 /// _demand_: For lazy algorithms, the number of output elements to
107 /// force, e.g., by producing a vector of output data. Eager
108 /// algorithms ignore this parameter (they always produce _all_ of
109 /// their output).
110 pub demand: usize,
111 /// Whether to validate the output after each computation using the naive and DCG engines
112 pub validate_output: bool,
113 /// Size of each batch of changes.
114 pub change_batch_size: usize,
115 /// Reflect the trace (See `adapton::engine::reflect::trace::Trace`).
116 pub reflect_trace: bool,
117 /// Reflect the DCG (See `adapton::engine::reflect::DCG`), including
118 /// its values (See `adapton::engine::reflect_val`).
119 pub reflect_dcg: bool,
120}
121
122/// The result of a lab is a sequence of samples.
123#[derive(Clone,Debug)]
124pub struct LabResults {
125 pub samples: Vec<Sample>
126}
127
128/// The experiment consists of a loop over samples. For each sample,
129/// we switch back and forth between using the Naive engine, and using
130/// the DCG engine. We want to interleave this way for each sample in
131/// order to compare outputs and metrics (counts and timings) on a
132/// fine-grained scale.
133#[derive(Clone,Debug)]
134pub struct Sample {
135 //pub params: SampleParams,
136 pub batch_name: usize, // Index/name the change batches; one sample per compute + change batch
137 pub dcg_sample: EngineSample,
138 pub naive_sample: EngineSample,
139 pub output_valid: Option<bool>
140}
141
142/// To sample a single engine, we record metrics for processing the
143/// input (left vertical edge in `README.md` diagram).
144#[derive(Clone,Debug)]
145pub struct EngineSample {
146 /// TODO: Rename: 'editor' (for editor role)
147 pub process_input: EngineMetrics,
148 /// TODO: Rename: 'archivist' (for archivist role)
149 pub compute_output: EngineMetrics,
150
151 pub input: Option<Val>,
152 pub output: Option<Val>,
153}
154
155/// For each engine, for each sampled subcomputation, we record the
156/// real time (in nanoseconds) and engine-based counters for DCG costs.
157#[derive(Clone,Debug)]
158pub struct EngineMetrics {
159 /// Time in milliseconds.
160 pub time_ns: u64,
161 /// Counts of engine (engine trace-level) operations (See
162 /// `engine::reflect::trace::Trace`) during the sample.
163// pub engine_cnt: Cnt,
164 /// The reflected traces of the DCG during the sample; empty if this
165 /// option is disabled.
166 pub reflect_traces: Vec<Trace>,
167 /// The reflected version of the DCG, at the conclusion of the
168 /// sample; None if this option is disabled.
169 pub reflect_dcg: Option<DCG>,
170}