use crate::{tensor::Tensor, tensor::TensorInternal, Float};
use std::cell::UnsafeCell;
use std::fmt;
pub struct Graph<F: Float> {
node_set: UnsafeCell<Vec<TensorInternal<F>>>,
}
impl<'t, 'g, F: Float> Graph<F> {
pub(crate) fn install(&'g self, mut node: TensorInternal<F>) -> usize {
unsafe {
let inner = &mut *self.node_set.get();
let id = inner.len();
node.id = id;
inner.push(node);
id
}
}
#[inline]
pub(crate) unsafe fn access_inner(&self, i: usize) -> &'t TensorInternal<F> {
&(*self.node_set.get())[i]
}
#[inline]
pub(crate) unsafe fn access_inner_mut(&self, i: usize) -> &'t mut TensorInternal<F> {
&mut (*self.node_set.get())[i]
}
#[inline]
pub(crate) fn tensor(&'g self, id: usize) -> Tensor<'g, F> {
Tensor { id, graph: self }
}
}
impl<T: Float> fmt::Debug for Graph<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
unsafe {
let set = &*self.node_set.get();
let mut buf = format!("graph size: {}\n", set.len());
for node in set {
buf += format!("{}\n", node).as_str();
}
write!(f, "{}", buf)
}
}
}
pub fn run<F, FN, R>(f: FN) -> R
where
F: Float,
FN: FnOnce(&mut Graph<F>) -> R,
{
let mut g = Graph {
node_set: UnsafeCell::new(Vec::with_capacity(128)),
};
f(&mut g)
}
pub fn with<F, FN>(f: FN)
where
F: Float,
FN: FnOnce(&mut Graph<F>),
{
run(f);
}