Skip to main content

Node

Struct Node 

Source
pub struct Node<T>
where T: Copy + Clone,
{ pub data_container: Box<dyn Any>, pub data: Vec<T>, pub clk: fn((Vec<&[T]>, usize), &mut Box<dyn Any>, &mut Vec<T>), }

Fields§

§data_container: Box<dyn Any>

Stores data required to process the functions. This data can be specified the operations themselves. Allowing the operations to specify their own data containers, requires the use of boxed trait objects. This unfortunately induces a bit over runtime overhead. There might be a faster way to do this.

§data: Vec<T>

Stores the data of the operation. This is the data that will be polled. This value is public to allow others to change the value without having to call a function. Which is supped to help speed up the setting and polling of data

§clk: fn((Vec<&[T]>, usize), &mut Box<dyn Any>, &mut Vec<T>)

A function pointer that will be called when the operation has to process its data. All operations have to specify a function to process its data. This can as example contain the functionality to add two values. Here they can mutate the value of self.data and access the data contained in data_container. The &Vec acts an input from other operations. The length of the vector is dependant on how many operations are connected to it. Some operations can handle mutliple inputs (Add, Sub,…) while others like Diff can only handle one inputs and will ignore the others.

Implementations§

Source§

impl<T> Node<T>
where T: Copy + Clone,

Source

pub fn new( container: Box<dyn Any>, clk: fn((Vec<&[T]>, usize), &mut Box<dyn Any>, &mut Vec<T>), ) -> Self

Generates a new node. This is done by all the operations. A operation has to specify a function according to which its data will be processed. Additionally the node requires a value according to which it can initialize its data field. If this wouldn’t be provided, the network (and value) would be in a uninitialized state. Each operation can choose to specify a container to store data in it. Currently, all operations have to box a value and use it to init the node. This causes some unnecessary RAM usage. Maybe this could be avoided with Box::new_uninit(); But this would put us into a undefined state which is to be avoided…

§Example
use sac_base::network::node::Node;
use std::any::Any;
use core::ops;

// Example code of the differentiation which uses an additional buffered value to safe the
// last state. Instead of just one value, a whole struct could be allocated and moved into
// the node as storage
fn new<T>() -> Node<T>
    where T: Copy + ops::Sub<Output=T> + 'static + Default
{
    let storage = Box::new(T::default()) as Box<dyn Any>;
    let mut node = Node::new(storage, |data_input, data_buffer, output| {
        let (inputs, max_len) = data_input;
        let last_val: &mut T = data_buffer.downcast_mut::<T>().unwrap();
        inputs.into_iter().take(1).into_iter().for_each(|data| {
            data.into_iter().take(max_len).into_iter().for_each(|v| {
                let diff_result = *v - *last_val;
                output.insert(0, diff_result);
                *last_val = *v;
            })
        })
    });
    // Make sure we got a default value in location 0 of the vector
    node.data.push(T::default());
    return node;
}
Source

pub fn process(&mut self, inputs: (Vec<&[T]>, usize))

Triggers the execution of the provided callback

Source

pub fn feed(&mut self, input: &[T])

Sets the input value. Not necessarily needed since data is public.

Source

pub fn poll(&self) -> &[T]

Polls the value. Not necessarily needed since data is public. Currently the data is copied when polled.

Auto Trait Implementations§

§

impl<T> !RefUnwindSafe for Node<T>

§

impl<T> !Send for Node<T>

§

impl<T> !Sync for Node<T>

§

impl<T> !UnwindSafe for Node<T>

§

impl<T> Freeze for Node<T>

§

impl<T> Unpin for Node<T>
where T: Unpin,

§

impl<T> UnsafeUnpin for Node<T>

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V