pub struct Node<T>{
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
Implementations§
Source§impl<T> Node<T>
impl<T> Node<T>
Sourcepub fn new(
container: Box<dyn Any>,
clk: fn((Vec<&[T]>, usize), &mut Box<dyn Any>, &mut Vec<T>),
) -> Self
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;
}Sourcepub fn process(&mut self, inputs: (Vec<&[T]>, usize))
pub fn process(&mut self, inputs: (Vec<&[T]>, usize))
Triggers the execution of the provided callback