Bump dyn-any version + format code

This commit is contained in:
Dennis
2022-08-04 09:08:48 +02:00
committed by Keavon Chambers
parent c44e9d22e3
commit d09f023618
12 changed files with 464 additions and 513 deletions

View File

@@ -1,46 +1,32 @@
use core::marker::PhantomData;
use crate::Node;
pub struct FnNode<'n, T: Fn(<N as Node<'n>>::Output) -> O, N: Node<'n>, O>(
T,
N,
PhantomData<&'n O>,
);
pub struct FnNode<'n, T: Fn(<N as Node<'n>>::Output) -> O, N: Node<'n>, O>(T, N, PhantomData<&'n O>);
impl<'n, T: Fn(<N as Node<'n>>::Output) -> O, N: Node<'n>, O> Node<'n> for FnNode<'n, T, N, O> {
type Output = O;
type Output = O;
fn eval(&'n self) -> Self::Output {
self.0(self.1.eval())
}
fn eval(&'n self) -> Self::Output {
self.0(self.1.eval())
}
}
impl<'n, T: Fn(<N as Node<'n>>::Output) -> O, N: Node<'n>, O> FnNode<'n, T, N, O> {
pub fn new(f: T, input: N) -> Self {
FnNode(f, input, PhantomData)
}
pub fn new(f: T, input: N) -> Self {
FnNode(f, input, PhantomData)
}
}
pub struct FnNodeWithState<
'n,
T: Fn(<N as Node<'n>>::Output, &'n State) -> O,
N: Node<'n>,
O,
State: 'n,
>(T, N, State, PhantomData<&'n O>);
impl<'n, T: Fn(<N as Node<'n>>::Output, &'n State) -> O, N: Node<'n>, O: 'n, State: 'n> Node<'n>
for FnNodeWithState<'n, T, N, O, State>
{
type Output = O;
pub struct FnNodeWithState<'n, T: Fn(<N as Node<'n>>::Output, &'n State) -> O, N: Node<'n>, O, State: 'n>(T, N, State, PhantomData<&'n O>);
impl<'n, T: Fn(<N as Node<'n>>::Output, &'n State) -> O, N: Node<'n>, O: 'n, State: 'n> Node<'n> for FnNodeWithState<'n, T, N, O, State> {
type Output = O;
fn eval(&'n self) -> Self::Output {
self.0(self.1.eval(), &self.2)
}
fn eval(&'n self) -> Self::Output {
self.0(self.1.eval(), &self.2)
}
}
impl<'n, T: Fn(<N as Node<'n>>::Output, &'n State) -> O, N: Node<'n>, O: 'n, State: 'n>
FnNodeWithState<'n, T, N, O, State>
{
pub fn new(f: T, input: N, state: State) -> Self {
FnNodeWithState(f, input, state, PhantomData)
}
impl<'n, T: Fn(<N as Node<'n>>::Output, &'n State) -> O, N: Node<'n>, O: 'n, State: 'n> FnNodeWithState<'n, T, N, O, State> {
pub fn new(f: T, input: N, state: State) -> Self {
FnNodeWithState(f, input, state, PhantomData)
}
}

View File

@@ -14,62 +14,62 @@ pub mod ops;
pub mod value;
pub trait Node<'n> {
type Output; // TODO: replace with generic associated type
type Output; // TODO: replace with generic associated type
fn eval(&'n self) -> Self::Output;
fn eval(&'n self) -> Self::Output;
}
impl<'n, N: Node<'n>> Node<'n> for &'n N {
type Output = N::Output;
type Output = N::Output;
fn eval(&'n self) -> Self::Output {
Node::eval(*self)
}
fn eval(&'n self) -> Self::Output {
Node::eval(*self)
}
}
pub trait NodeInput {
type Nodes;
type Nodes;
fn new(input: Self::Nodes) -> Self;
fn new(input: Self::Nodes) -> Self;
}
trait FQN {
fn fqn(&self) -> &'static str;
fn fqn(&self) -> &'static str;
}
trait Input<I> {
unsafe fn input(&self, input: I);
unsafe fn input(&self, input: I);
}
#[cfg(feature = "async")]
#[async_trait]
pub trait AsyncNode<'n> {
type Output; // TODO: replace with generic associated type
type Output; // TODO: replace with generic associated type
async fn eval_async(&'n self) -> Self::Output;
async fn eval_async(&'n self) -> Self::Output;
}
#[cfg(feature = "async")]
#[async_trait]
impl<'n, N: Node<'n> + Sync> AsyncNode<'n> for N {
type Output = N::Output;
type Output = N::Output;
async fn eval_async(&'n self) -> Self::Output {
Node::eval(self)
}
async fn eval_async(&'n self) -> Self::Output {
Node::eval(self)
}
}
pub trait Cache {
fn clear(&mut self);
fn clear(&mut self);
}
#[cfg(not(feature = "gpu"))]
extern crate alloc;
#[cfg(not(feature = "gpu"))]
impl<'n, I, O: 'n> Node<'n, I> for alloc::boxed::Box<dyn Node<'n, I, Output = O>> {
type Output = O;
type Output = O;
fn eval(&'n self, input: &'n I) -> Self::Output {
self.as_ref().eval(input)
}
fn eval(&'n self, input: &'n I) -> Self::Output {
self.as_ref().eval(input)
}
}

View File

@@ -3,165 +3,156 @@ use core::{marker::PhantomData, ops::Add};
use crate::{Node, NodeInput};
#[repr(C)]
pub struct AddNode<'n, L: Add<R>, R, I1: Node<'n, Output = L>, I2: Node<'n, Output = R>>(
pub I1,
pub I2,
PhantomData<&'n (L, R)>,
);
impl<'n, L: Add<R>, R, I1: Node<'n, Output = L>, I2: Node<'n, Output = R>> Node<'n>
for AddNode<'n, L, R, I1, I2>
{
type Output = <L as Add<R>>::Output;
fn eval(&'n self) -> Self::Output {
self.0.eval() + self.1.eval()
}
pub struct AddNode<'n, L: Add<R>, R, I1: Node<'n, Output = L>, I2: Node<'n, Output = R>>(pub I1, pub I2, PhantomData<&'n (L, R)>);
impl<'n, L: Add<R>, R, I1: Node<'n, Output = L>, I2: Node<'n, Output = R>> Node<'n> for AddNode<'n, L, R, I1, I2> {
type Output = <L as Add<R>>::Output;
fn eval(&'n self) -> Self::Output {
self.0.eval() + self.1.eval()
}
}
impl<'n, L: Add<R>, R, I1: Node<'n, Output = L>, I2: Node<'n, Output = R>>
AddNode<'n, L, R, I1, I2>
{
pub fn new(input: (I1, I2)) -> AddNode<'n, L, R, I1, I2> {
AddNode(input.0, input.1, PhantomData)
}
impl<'n, L: Add<R>, R, I1: Node<'n, Output = L>, I2: Node<'n, Output = R>> AddNode<'n, L, R, I1, I2> {
pub fn new(input: (I1, I2)) -> AddNode<'n, L, R, I1, I2> {
AddNode(input.0, input.1, PhantomData)
}
}
#[repr(C)]
pub struct CloneNode<'n, N: Node<'n, Output = &'n O>, O: Clone + 'n>(pub N, PhantomData<&'n ()>);
impl<'n, N: Node<'n, Output = &'n O>, O: Clone> Node<'n> for CloneNode<'n, N, O> {
type Output = O;
fn eval(&'n self) -> Self::Output {
self.0.eval().clone()
}
type Output = O;
fn eval(&'n self) -> Self::Output {
self.0.eval().clone()
}
}
impl<'n, N: Node<'n, Output = &'n O>, O: Clone> CloneNode<'n, N, O> {
pub const fn new(node: N) -> CloneNode<'n, N, O> {
CloneNode(node, PhantomData)
}
pub const fn new(node: N) -> CloneNode<'n, N, O> {
CloneNode(node, PhantomData)
}
}
#[repr(C)]
pub struct FstNode<'n, N: Node<'n>>(pub N, PhantomData<&'n ()>);
impl<'n, T: 'n, U, N: Node<'n, Output = (T, U)>> Node<'n> for FstNode<'n, N> {
type Output = T;
fn eval(&'n self) -> Self::Output {
let (a, _) = self.0.eval();
a
}
type Output = T;
fn eval(&'n self) -> Self::Output {
let (a, _) = self.0.eval();
a
}
}
#[repr(C)]
/// Destructures a Tuple of two values and returns the first one
pub struct SndNode<'n, N: Node<'n>>(pub N, PhantomData<&'n ()>);
impl<'n, T, U: 'n, N: Node<'n, Output = (T, U)>> Node<'n> for SndNode<'n, N> {
type Output = U;
fn eval(&'n self) -> Self::Output {
let (_, b) = self.0.eval();
b
}
type Output = U;
fn eval(&'n self) -> Self::Output {
let (_, b) = self.0.eval();
b
}
}
#[repr(C)]
/// Return a tuple with two instances of the input argument
pub struct DupNode<'n, N: Node<'n>>(N, PhantomData<&'n ()>);
impl<'n, N: Node<'n>> Node<'n> for DupNode<'n, N> {
type Output = (N::Output, N::Output);
fn eval(&'n self) -> Self::Output {
(self.0.eval(), self.0.eval()) //TODO: use Copy/Clone implementation
}
type Output = (N::Output, N::Output);
fn eval(&'n self) -> Self::Output {
(self.0.eval(), self.0.eval()) //TODO: use Copy/Clone implementation
}
}
impl<'n, N: Node<'n>> NodeInput for DupNode<'n, N> {
type Nodes = N;
type Nodes = N;
fn new(input: Self::Nodes) -> Self {
Self(input, PhantomData)
}
fn new(input: Self::Nodes) -> Self {
Self(input, PhantomData)
}
}
#[repr(C)]
/// Return the Input Argument
pub struct IdNode<'n, N: Node<'n>>(N, PhantomData<&'n ()>);
impl<'n, N: Node<'n>> Node<'n> for IdNode<'n, N> {
type Output = N::Output;
fn eval(&'n self) -> Self::Output {
self.0.eval()
}
type Output = N::Output;
fn eval(&'n self) -> Self::Output {
self.0.eval()
}
}
impl<'n, N: Node<'n>> NodeInput for IdNode<'n, N> {
type Nodes = N;
type Nodes = N;
fn new(input: Self::Nodes) -> Self {
Self(input, PhantomData)
}
fn new(input: Self::Nodes) -> Self {
Self(input, PhantomData)
}
}
pub fn foo() {
let unit = crate::value::UnitNode;
let value = IdNode(crate::value::ValueNode(2u32), PhantomData);
let value2 = crate::value::ValueNode(4u32);
let dup = DupNode(&value, PhantomData);
fn int(_: (), state: &u32) -> &u32 {
state
}
fn swap<'n>(input: (&'n u32, &'n u32)) -> (&'n u32, &'n u32) {
(input.1, input.0)
}
let fnn = crate::generic::FnNode::new(swap, &dup);
let fns = crate::generic::FnNodeWithState::new(int, &unit, 42u32);
let _ = fnn.eval();
let _ = fns.eval();
let snd = SndNode(&fnn, PhantomData);
let _ = snd.eval();
let add = AddNode(&snd, value2, PhantomData);
let _ = add.eval();
let unit = crate::value::UnitNode;
let value = IdNode(crate::value::ValueNode(2u32), PhantomData);
let value2 = crate::value::ValueNode(4u32);
let dup = DupNode(&value, PhantomData);
fn int(_: (), state: &u32) -> &u32 {
state
}
fn swap<'n>(input: (&'n u32, &'n u32)) -> (&'n u32, &'n u32) {
(input.1, input.0)
}
let fnn = crate::generic::FnNode::new(swap, &dup);
let fns = crate::generic::FnNodeWithState::new(int, &unit, 42u32);
let _ = fnn.eval();
let _ = fns.eval();
let snd = SndNode(&fnn, PhantomData);
let _ = snd.eval();
let add = AddNode(&snd, value2, PhantomData);
let _ = add.eval();
}
#[cfg(target_arch = "spirv")]
pub mod gpu {
//#![deny(warnings)]
#[repr(C)]
pub struct PushConsts {
n: u32,
node: u32,
}
use super::*;
use crate::{structural::ComposeNodeOwned, Node};
//use crate::Node;
use spirv_std::glam::UVec3;
const ADD: AddNode<u32> = AddNode(PhantomData);
const OPERATION: ComposeNodeOwned<'_, (u32, u32), u32, FstNode<u32, u32>, DupNode<u32>> =
ComposeNodeOwned::new(FstNode(PhantomData, PhantomData), DupNode(PhantomData));
//#![deny(warnings)]
#[repr(C)]
pub struct PushConsts {
n: u32,
node: u32,
}
use super::*;
use crate::{structural::ComposeNodeOwned, Node};
//use crate::Node;
use spirv_std::glam::UVec3;
const ADD: AddNode<u32> = AddNode(PhantomData);
const OPERATION: ComposeNodeOwned<'_, (u32, u32), u32, FstNode<u32, u32>, DupNode<u32>> = ComposeNodeOwned::new(FstNode(PhantomData, PhantomData), DupNode(PhantomData));
#[allow(unused)]
#[spirv(compute(threads(64)))]
pub fn spread(
#[spirv(global_invocation_id)] global_id: UVec3,
#[spirv(storage_buffer, descriptor_set = 0, binding = 0)] a: &[(u32, u32)],
#[spirv(storage_buffer, descriptor_set = 0, binding = 1)] y: &mut [(u32, u32)],
#[spirv(push_constant)] push_consts: &PushConsts,
) {
fn node_graph(input: Input) -> Output {
let n0 = ValueNode::new(input);
let n1 = IdNode::new(n0);
let n2 = IdNode::new(n1);
return n2.eval();
}
let gid = global_id.x as usize;
// Only process up to n, which is the length of the buffers.
if global_id.x < push_consts.n {
y[gid] = node_graph(a[gid]);
}
}
#[allow(unused)]
#[spirv(compute(threads(64)))]
pub fn add(
#[spirv(global_invocation_id)] global_id: UVec3,
#[spirv(storage_buffer, descriptor_set = 0, binding = 0)] a: &[(u32, u32)],
#[spirv(storage_buffer, descriptor_set = 0, binding = 1)] y: &mut [u32],
#[spirv(push_constant)] push_consts: &PushConsts,
) {
let gid = global_id.x as usize;
// Only process up to n, which is the length of the buffers.
if global_id.x < push_consts.n {
y[gid] = ADD.eval(a[gid]);
}
}
#[allow(unused)]
#[spirv(compute(threads(64)))]
pub fn spread(
#[spirv(global_invocation_id)] global_id: UVec3,
#[spirv(storage_buffer, descriptor_set = 0, binding = 0)] a: &[(u32, u32)],
#[spirv(storage_buffer, descriptor_set = 0, binding = 1)] y: &mut [(u32, u32)],
#[spirv(push_constant)] push_consts: &PushConsts,
) {
fn node_graph(input: Input) -> Output {
let n0 = ValueNode::new(input);
let n1 = IdNode::new(n0);
let n2 = IdNode::new(n1);
return n2.eval();
}
let gid = global_id.x as usize;
// Only process up to n, which is the length of the buffers.
if global_id.x < push_consts.n {
y[gid] = node_graph(a[gid]);
}
}
#[allow(unused)]
#[spirv(compute(threads(64)))]
pub fn add(
#[spirv(global_invocation_id)] global_id: UVec3,
#[spirv(storage_buffer, descriptor_set = 0, binding = 0)] a: &[(u32, u32)],
#[spirv(storage_buffer, descriptor_set = 0, binding = 1)] y: &mut [u32],
#[spirv(push_constant)] push_consts: &PushConsts,
) {
let gid = global_id.x as usize;
// Only process up to n, which is the length of the buffers.
if global_id.x < push_consts.n {
y[gid] = ADD.eval(a[gid]);
}
}
}

View File

@@ -6,57 +6,57 @@ use crate::Node;
pub struct IntNode<const N: u32>;
impl<'n, const N: u32> Node<'n> for IntNode<N> {
type Output = u32;
fn eval(&self) -> u32 {
N
}
type Output = u32;
fn eval(&self) -> u32 {
N
}
}
#[derive(Default)]
pub struct ValueNode<T>(pub T);
impl<'n, T: 'n> Node<'n> for ValueNode<T> {
type Output = &'n T;
fn eval(&'n self) -> Self::Output {
&self.0
}
type Output = &'n T;
fn eval(&'n self) -> Self::Output {
&self.0
}
}
impl<T> ValueNode<T> {
pub const fn new(value: T) -> ValueNode<T> {
ValueNode(value)
}
pub const fn new(value: T) -> ValueNode<T> {
ValueNode(value)
}
}
#[derive(Default)]
pub struct DefaultNode<T>(PhantomData<T>);
impl<'n, T: Default + 'n> Node<'n> for DefaultNode<T> {
type Output = T;
fn eval(&self) -> T {
T::default()
}
type Output = T;
fn eval(&self) -> T {
T::default()
}
}
#[repr(C)]
/// Return the unit value
pub struct UnitNode;
impl<'n> Node<'n> for UnitNode {
type Output = ();
fn eval(&'n self) -> Self::Output {}
type Output = ();
fn eval(&'n self) -> Self::Output {}
}
pub struct InputNode<T>(MaybeUninit<T>, AtomicBool);
impl<'n, T: 'n> Node<'n> for InputNode<T> {
type Output = &'n T;
fn eval(&'n self) -> Self::Output {
if self.1.load(core::sync::atomic::Ordering::SeqCst) {
unsafe { self.0.assume_init_ref() }
} else {
panic!("tried to access an input before setting it")
}
}
type Output = &'n T;
fn eval(&'n self) -> Self::Output {
if self.1.load(core::sync::atomic::Ordering::SeqCst) {
unsafe { self.0.assume_init_ref() }
} else {
panic!("tried to access an input before setting it")
}
}
}
impl<T> InputNode<T> {
pub const fn new() -> InputNode<T> {
InputNode(MaybeUninit::uninit(), AtomicBool::new(false))
}
pub const fn new() -> InputNode<T> {
InputNode(MaybeUninit::uninit(), AtomicBool::new(false))
}
}