use std::collections::HashMap;
use crate::arena::ArenaKey;
use crate::device::DeviceId;
use crate::graph::Graph;
use crate::shape::Shape;
use crate::tensor::{SparseTensorData, TensorData, TypeProto};
use crate::value::ValueId;
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub struct NodeId(pub u32);
impl ArenaKey for NodeId {
fn from_raw(raw: u32) -> Self {
NodeId(raw)
}
fn to_raw(self) -> u32 {
self.0
}
}
#[derive(Clone, Debug)]
pub struct Node {
pub id: NodeId,
pub name: String,
pub op_type: String,
pub domain: String,
pub inputs: Vec<Option<ValueId>>,
pub outputs: Vec<ValueId>,
pub attributes: HashMap<String, Attribute>,
pub doc_string: Option<String>,
pub device: Option<DeviceId>,
pub exec_order: Option<usize>,
}
impl Node {
pub fn new(
id: NodeId,
op_type: impl Into<String>,
inputs: Vec<Option<ValueId>>,
outputs: Vec<ValueId>,
) -> Self {
Self {
id,
name: String::new(),
op_type: op_type.into(),
domain: String::new(),
inputs,
outputs,
attributes: HashMap::new(),
doc_string: None,
device: None,
exec_order: None,
}
}
pub fn input_values(&self) -> impl Iterator<Item = ValueId> + '_ {
self.inputs.iter().filter_map(|slot| *slot)
}
pub fn attr(&self, name: &str) -> Option<&Attribute> {
self.attributes.get(name)
}
}
#[derive(Clone, Debug)]
pub enum Attribute {
Int(i64),
Float(f32),
String(Vec<u8>),
Ints(Vec<i64>),
Floats(Vec<f32>),
Strings(Vec<Vec<u8>>),
Tensor(TensorData),
Tensors(Vec<TensorData>),
SparseTensor(SparseTensorData),
SparseTensors(Vec<SparseTensorData>),
Graph(Box<Graph>),
Graphs(Vec<Graph>),
TypeProto(TypeProto),
TypeProtos(Vec<TypeProto>),
}
impl Attribute {
pub fn as_int(&self) -> Option<i64> {
match self {
Attribute::Int(v) => Some(*v),
_ => None,
}
}
pub fn as_float(&self) -> Option<f32> {
match self {
Attribute::Float(v) => Some(*v),
_ => None,
}
}
pub fn as_str(&self) -> Option<&str> {
match self {
Attribute::String(v) => std::str::from_utf8(v).ok(),
_ => None,
}
}
pub fn as_bytes(&self) -> Option<&[u8]> {
match self {
Attribute::String(v) => Some(v),
_ => None,
}
}
pub fn as_ints(&self) -> Option<&[i64]> {
match self {
Attribute::Ints(v) => Some(v),
_ => None,
}
}
pub fn as_shape(&self) -> Option<Shape> {
self.as_ints()
.map(|v| v.iter().map(|&d| (d as usize).into()).collect())
}
}