Skip to main content

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::{eval::Tape, var::TracingArgError};
12
13/// Error type for tracing evaluation
14#[derive(thiserror::Error, Debug)]
15#[error(transparent)]
16pub struct TracingEvalError(#[from] pub TracingArgError);
17
18/// Evaluator for single values which simultaneously captures an execution trace
19///
20/// The trace can later be used to simplify the
21/// [`Function`](crate::eval::Function)
22/// using [`Function::simplify`](crate::eval::Function::simplify).
23///
24/// Tracing evaluators may contain intermediate storage (e.g. an array of VM
25/// registers), and should be constructed on a per-thread basis.
26pub trait TracingEvaluator: Default {
27    /// Data type used during evaluation
28    type Data: From<f32> + Copy + Clone;
29
30    /// Instruction tape used during evaluation
31    ///
32    /// This may be a literal instruction tape (in the case of VM evaluation),
33    /// or a metaphorical instruction tape (e.g. a JIT function).
34    type Tape: Tape<Storage = Self::TapeStorage>;
35
36    /// Associated type for tape storage
37    ///
38    /// This is a workaround for plumbing purposes
39    type TapeStorage;
40
41    /// Associated type for the trace captured during evaluation
42    type Trace;
43
44    /// Evaluates the given tape at a particular position
45    ///
46    /// `vars` should be a slice of values representing input arguments for each
47    /// of the tape's variables; use [`Tape::vars`] to map from
48    /// [`Var`](crate::var::Var) to position in the list.
49    ///
50    /// Returns an error if the `var` slice is not of sufficient length.
51    fn eval(
52        &mut self,
53        tape: &Self::Tape,
54        vars: &[Self::Data],
55    ) -> Result<TracingResult<'_, Self::Data, Self::Trace>, TracingEvalError>;
56
57    /// Build a new empty evaluator
58    fn new() -> Self {
59        Self::default()
60    }
61}
62
63/// Tuple of tracing evaluation result
64type TracingResult<'a, Data, Trace> = (&'a [Data], Option<&'a Trace>);