fidget_core/eval/
tracing.rs

1//! Capturing a trace of function evaluation for further optimization
2//!
3//! Tracing evaluators are run on a single data type and capture a trace of
4//! execution, which is the [`Trace` associated type](TracingEvaluator::Trace).
5//!
6//! The resulting trace can be used to simplify the original function.
7//!
8//! It is unlikely that you'll want to use these traits or types directly;
9//! they're implementation details to minimize code duplication.
10
11use crate::{Error, eval::Tape};
12
13/// Evaluator for single values which simultaneously captures an execution trace
14///
15/// The trace can later be used to simplify the
16/// [`Function`](crate::eval::Function)
17/// using [`Function::simplify`](crate::eval::Function::simplify).
18///
19/// Tracing evaluators may contain intermediate storage (e.g. an array of VM
20/// registers), and should be constructed on a per-thread basis.
21pub trait TracingEvaluator: Default {
22    /// Data type used during evaluation
23    type Data: From<f32> + Copy + Clone;
24
25    /// Instruction tape used during evaluation
26    ///
27    /// This may be a literal instruction tape (in the case of VM evaluation),
28    /// or a metaphorical instruction tape (e.g. a JIT function).
29    type Tape: Tape<Storage = Self::TapeStorage>;
30
31    /// Associated type for tape storage
32    ///
33    /// This is a workaround for plumbing purposes
34    type TapeStorage;
35
36    /// Associated type for the trace captured during evaluation
37    type Trace;
38
39    /// Evaluates the given tape at a particular position
40    ///
41    /// `vars` should be a slice of values representing input arguments for each
42    /// of the tape's variables; use [`Tape::vars`] to map from
43    /// [`Var`](crate::var::Var) to position in the list.
44    ///
45    /// Returns an error if the `var` slice is not of sufficient length.
46    fn eval(
47        &mut self,
48        tape: &Self::Tape,
49        vars: &[Self::Data],
50    ) -> Result<TracingResult<'_, Self::Data, Self::Trace>, Error>;
51
52    /// Build a new empty evaluator
53    fn new() -> Self {
54        Self::default()
55    }
56}
57
58/// Tuple of tracing evaluation result
59type TracingResult<'a, Data, Trace> = (&'a [Data], Option<&'a Trace>);