use std::collections::HashSet;
use rlx_ir::{Graph, Op};
use rlx_runtime::{Device, Session};
pub struct Model {
compiled: rlx_runtime::CompiledGraph,
params: HashSet<String>,
bound: HashSet<String>,
}
impl Model {
pub fn new(graph: Graph) -> Self {
let device = rlx_runtime::fastest_device_for(&graph);
Self::on(graph, device)
}
pub fn on(graph: Graph, device: Device) -> Self {
let params = graph
.nodes()
.iter()
.filter_map(|n| match &n.op {
Op::Param { name } => Some(name.clone()),
_ => None,
})
.collect();
Self {
compiled: Session::new(device).compile(graph),
params,
bound: HashSet::new(),
}
}
pub fn param_names(&self) -> impl Iterator<Item = &str> {
self.params.iter().map(String::as_str)
}
pub fn unbound(&self) -> Vec<&str> {
self.params
.difference(&self.bound)
.map(String::as_str)
.collect()
}
pub fn set(&mut self, name: &str, data: &[f32]) -> &mut Self {
if self.params.contains(name) {
self.compiled.set_param(name, data);
self.bound.insert(name.to_string());
}
self
}
pub fn load<'a, I>(&mut self, weights: I) -> &mut Self
where
I: IntoIterator<Item = (&'a str, &'a [f32])>,
{
for (name, data) in weights {
self.set(name, data);
}
self
}
pub fn run(&mut self, inputs: &[(&str, &[f32])]) -> Vec<Vec<f32>> {
self.compiled.run(inputs)
}
}