use core::ffi::{c_void, CStr};
use crate::drv::{self, Loaded, NrtModelHandle, NrtTensorSetHandle, NRT_SUCCESS};
#[derive(Debug)]
pub enum NeuronError {
Unavailable,
MissingSymbol(&'static str),
Runtime(u32),
BadName,
}
pub struct Model {
l: &'static Loaded,
handle: NrtModelHandle,
}
impl Model {
pub fn load(neff: &[u8], start_nc: i32, nc_count: i32) -> Result<Self, NeuronError> {
let l = drv::loaded().ok_or(NeuronError::Unavailable)?;
let load = l.nrt_load.ok_or(NeuronError::MissingSymbol("nrt_load"))?;
let mut handle: NrtModelHandle = core::ptr::null_mut();
let r = unsafe { load(neff.as_ptr(), neff.len(), start_nc, nc_count, &mut handle) };
if r != NRT_SUCCESS {
return Err(NeuronError::Runtime(r));
}
Ok(Self { l, handle })
}
pub fn execute(&self, inputs: &TensorSet, outputs: &TensorSet) -> Result<(), NeuronError> {
let exec = self
.l
.nrt_execute
.ok_or(NeuronError::MissingSymbol("nrt_execute"))?;
let r = unsafe { exec(self.handle, inputs.handle, outputs.handle) };
if r != NRT_SUCCESS {
return Err(NeuronError::Runtime(r));
}
Ok(())
}
pub fn raw(&self) -> NrtModelHandle {
self.handle
}
}
impl Drop for Model {
fn drop(&mut self) {
if let Some(unload) = self.l.nrt_unload {
unsafe {
let _ = unload(self.handle);
}
}
}
}
pub struct TensorSet {
l: &'static Loaded,
handle: NrtTensorSetHandle,
}
impl TensorSet {
pub fn new() -> Result<Self, NeuronError> {
let l = drv::loaded().ok_or(NeuronError::Unavailable)?;
let alloc = l
.nrt_alloc_tensor_set
.ok_or(NeuronError::MissingSymbol("nrt_allocate_tensor_set"))?;
let mut handle: NrtTensorSetHandle = core::ptr::null_mut();
let r = unsafe { alloc(&mut handle) };
if r != NRT_SUCCESS {
return Err(NeuronError::Runtime(r));
}
Ok(Self { l, handle })
}
pub unsafe fn add(&mut self, name: &CStr, tensor: *mut c_void) -> Result<(), NeuronError> {
let add = self
.l
.nrt_add_tensor_to_set
.ok_or(NeuronError::MissingSymbol("nrt_add_tensor_to_tensor_set"))?;
let r = unsafe { add(self.handle, name.as_ptr(), tensor) };
if r != NRT_SUCCESS {
return Err(NeuronError::Runtime(r));
}
Ok(())
}
pub fn raw(&self) -> NrtTensorSetHandle {
self.handle
}
}
impl Drop for TensorSet {
fn drop(&mut self) {
if let Some(free) = self.l.nrt_free_tensor_set {
unsafe {
let _ = free(self.handle);
}
}
}
}