Skip to main content

TensorExecutor

Struct TensorExecutor 

Source
pub struct TensorExecutor<'program> {
    pub packed_values: Vec<f32>,
    /* private fields */
}
Expand description

Reusable buffers for running one program many times.

Fields§

§packed_values: Vec<f32>

After a run, packed_values[k] is the value of program.wire_order[k].

Implementations§

Source§

impl<'program> TensorExecutor<'program>

Source

pub fn new(program: &'program TensorProgram) -> TensorExecutor<'program>

Examples found in repository?
examples/ui_panel.rs (line 142)
132fn main() {
133    let compiled = ui_frame_circuit();
134    let report = compiled.verify(20_000).unwrap();
135    eprintln!(
136        "ui_frame: {} live operations in {} layers; verified on {} sampled inputs",
137        compiled.program.live_operation_count(),
138        compiled.program.layers.len(),
139        report.checked
140    );
141    let _ = (TOGGLE, SLIDER_LEFT);
142    let mut executor = TensorExecutor::new(&compiled.program);
143    let mut source = Vec::new();
144    let mut state = (false, false, false, 0u8, 0.0f32);
145    println!("frame,x,y,held,pressed,released,on,armed,dragging,level,thumb");
146    for (frame, (x, y, pressed, released, held)) in script().into_iter().enumerate() {
147        let args = (state.0, state.1, state.2, state.3, state.4, x, y, pressed, released);
148        source.clear();
149        args.encode(&mut source);
150        let outputs = executor.run(&source);
151        let next = (outputs[0] == 1.0, outputs[1] == 1.0, outputs[2] == 1.0, outputs[3] as u8, outputs[4]);
152        let expected = ui_frame(state.0, state.1, state.2, state.3, state.4, x, y, pressed, released);
153        assert_eq!(next, expected, "frame {frame}: the circuit disagrees with ui_frame()");
154        state = next;
155        println!(
156            "{frame},{x},{y},{},{},{},{},{},{},{},{}",
157            held as u8, pressed as u8, released as u8, state.0 as u8, state.1 as u8, state.2 as u8, state.3, state.4
158        );
159    }
160}
More examples
Hide additional examples
examples/life.rs (line 57)
34fn main() {
35    let compiled = life_step_circuit();
36    let report = compiled.verify(200).unwrap();
37    eprintln!(
38        "life_step: {} live operations in {} layers; verified on {} random grids",
39        compiled.program.live_operation_count(),
40        compiled.program.layers.len(),
41        report.checked
42    );
43    // Two gliders, a lightweight spaceship and an R-pentomino.
44    let mut grid = [[false; N]; N];
45    for (row, column) in [(1, 2), (2, 3), (3, 1), (3, 2), (3, 3)] {
46        grid[row][column] = true;
47    }
48    for (row, column) in [(14, 4), (15, 5), (16, 3), (16, 4), (16, 5)] {
49        grid[row][column] = true;
50    }
51    for (row, column) in [(4, 14), (4, 17), (5, 18), (6, 14), (6, 18), (7, 15), (7, 16), (7, 17), (7, 18)] {
52        grid[row][column] = true;
53    }
54    for (row, column) in [(16, 16), (16, 17), (17, 15), (17, 16), (18, 16)] {
55        grid[row][column] = true;
56    }
57    let mut executor = TensorExecutor::new(&compiled.program);
58    let mut source = Vec::new();
59    for generation in 0..120 {
60        println!(
61            "{}",
62            grid.iter().flat_map(|row| row.iter().map(|&alive| if alive { '#' } else { '.' })).collect::<String>()
63        );
64        source.clear();
65        (grid,).encode(&mut source);
66        let outputs = executor.run(&source);
67        let next: [[bool; N]; N] =
68            std::array::from_fn(|row| std::array::from_fn(|column| outputs[row * N + column] == 1.0));
69        assert_eq!(next, life_step(grid), "generation {generation}: the circuit disagrees with life_step()");
70        grid = next;
71    }
72}
Source

pub fn run(&mut self, source: &[f32]) -> &[f32]

Evaluate the program and return the roots’ values. The source is not range-checked; use Circuit::validate_source_ranges for that.

Examples found in repository?
examples/ui_panel.rs (line 150)
132fn main() {
133    let compiled = ui_frame_circuit();
134    let report = compiled.verify(20_000).unwrap();
135    eprintln!(
136        "ui_frame: {} live operations in {} layers; verified on {} sampled inputs",
137        compiled.program.live_operation_count(),
138        compiled.program.layers.len(),
139        report.checked
140    );
141    let _ = (TOGGLE, SLIDER_LEFT);
142    let mut executor = TensorExecutor::new(&compiled.program);
143    let mut source = Vec::new();
144    let mut state = (false, false, false, 0u8, 0.0f32);
145    println!("frame,x,y,held,pressed,released,on,armed,dragging,level,thumb");
146    for (frame, (x, y, pressed, released, held)) in script().into_iter().enumerate() {
147        let args = (state.0, state.1, state.2, state.3, state.4, x, y, pressed, released);
148        source.clear();
149        args.encode(&mut source);
150        let outputs = executor.run(&source);
151        let next = (outputs[0] == 1.0, outputs[1] == 1.0, outputs[2] == 1.0, outputs[3] as u8, outputs[4]);
152        let expected = ui_frame(state.0, state.1, state.2, state.3, state.4, x, y, pressed, released);
153        assert_eq!(next, expected, "frame {frame}: the circuit disagrees with ui_frame()");
154        state = next;
155        println!(
156            "{frame},{x},{y},{},{},{},{},{},{},{},{}",
157            held as u8, pressed as u8, released as u8, state.0 as u8, state.1 as u8, state.2 as u8, state.3, state.4
158        );
159    }
160}
More examples
Hide additional examples
examples/life.rs (line 66)
34fn main() {
35    let compiled = life_step_circuit();
36    let report = compiled.verify(200).unwrap();
37    eprintln!(
38        "life_step: {} live operations in {} layers; verified on {} random grids",
39        compiled.program.live_operation_count(),
40        compiled.program.layers.len(),
41        report.checked
42    );
43    // Two gliders, a lightweight spaceship and an R-pentomino.
44    let mut grid = [[false; N]; N];
45    for (row, column) in [(1, 2), (2, 3), (3, 1), (3, 2), (3, 3)] {
46        grid[row][column] = true;
47    }
48    for (row, column) in [(14, 4), (15, 5), (16, 3), (16, 4), (16, 5)] {
49        grid[row][column] = true;
50    }
51    for (row, column) in [(4, 14), (4, 17), (5, 18), (6, 14), (6, 18), (7, 15), (7, 16), (7, 17), (7, 18)] {
52        grid[row][column] = true;
53    }
54    for (row, column) in [(16, 16), (16, 17), (17, 15), (17, 16), (18, 16)] {
55        grid[row][column] = true;
56    }
57    let mut executor = TensorExecutor::new(&compiled.program);
58    let mut source = Vec::new();
59    for generation in 0..120 {
60        println!(
61            "{}",
62            grid.iter().flat_map(|row| row.iter().map(|&alive| if alive { '#' } else { '.' })).collect::<String>()
63        );
64        source.clear();
65        (grid,).encode(&mut source);
66        let outputs = executor.run(&source);
67        let next: [[bool; N]; N] =
68            std::array::from_fn(|row| std::array::from_fn(|column| outputs[row * N + column] == 1.0));
69        assert_eq!(next, life_step(grid), "generation {generation}: the circuit disagrees with life_step()");
70        grid = next;
71    }
72}

Auto Trait Implementations§

§

impl<'program> Freeze for TensorExecutor<'program>

§

impl<'program> RefUnwindSafe for TensorExecutor<'program>

§

impl<'program> Send for TensorExecutor<'program>

§

impl<'program> Sync for TensorExecutor<'program>

§

impl<'program> Unpin for TensorExecutor<'program>

§

impl<'program> UnsafeUnpin for TensorExecutor<'program>

§

impl<'program> UnwindSafe for TensorExecutor<'program>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<E> StoreElem<usize> for E

Source§

fn store(items: &mut [E], index: usize, value: E)

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.