use core::mem::MaybeUninit;
pub use crate::error::Error;
pub type Result<T, E = Error> = core::result::Result<T, E>;
pub type BufferSize = u32;
pub type NnErrno = u16;
pub const NN_ERRNO_SUCCESS: NnErrno = 0;
pub const NN_ERRNO_INVALID_ARGUMENT: NnErrno = 1;
pub const NN_ERRNO_MISSING_MEMORY: NnErrno = 2;
pub const NN_ERRNO_BUSY: NnErrno = 3;
pub type TensorDimensions<'a> = &'a [u32];
pub type TensorType = u8;
pub const TENSOR_TYPE_F16: TensorType = 0;
pub const TENSOR_TYPE_F32: TensorType = 1;
pub const TENSOR_TYPE_U8: TensorType = 2;
pub const TENSOR_TYPE_I32: TensorType = 3;
pub type TensorData<'a> = &'a [u8];
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct Tensor<'a> {
pub dimensions: TensorDimensions<'a>,
pub r#type: TensorType,
pub data: TensorData<'a>,
}
pub type GraphBuilder<'a> = &'a [u8];
pub type GraphBuilderArray<'a> = &'a [GraphBuilder<'a>];
pub type Graph = u32;
pub type GraphEncoding = u8;
pub const GRAPH_ENCODING_OPENVINO: GraphEncoding = 0;
pub type ExecutionTarget = u8;
pub const EXECUTION_TARGET_CPU: ExecutionTarget = 0;
pub const EXECUTION_TARGET_GPU: ExecutionTarget = 1;
pub const EXECUTION_TARGET_TPU: ExecutionTarget = 2;
pub type GraphExecutionContext = u32;
pub unsafe fn load(
builder: GraphBuilderArray,
encoding: GraphEncoding,
target: ExecutionTarget,
) -> Result<Graph> {
let mut graph = MaybeUninit::uninit();
let rc = wasi_ephemeral_nn::load(
builder.as_ptr(),
builder.len(),
encoding,
target,
graph.as_mut_ptr(),
);
if let Some(err) = Error::from_raw_error(rc) {
Err(err)
} else {
Ok(graph.assume_init())
}
}
pub unsafe fn init_execution_context(graph: Graph) -> Result<GraphExecutionContext> {
let mut context = MaybeUninit::uninit();
let rc = wasi_ephemeral_nn::init_execution_context(graph, context.as_mut_ptr());
if let Some(err) = Error::from_raw_error(rc) {
Err(err)
} else {
Ok(context.assume_init())
}
}
pub unsafe fn set_input(context: GraphExecutionContext, index: u32, tensor: Tensor) -> Result<()> {
let rc = wasi_ephemeral_nn::set_input(context, index, &tensor as *const _ as *mut _);
if let Some(err) = Error::from_raw_error(rc) {
Err(err)
} else {
Ok(())
}
}
pub unsafe fn get_output(
context: GraphExecutionContext,
index: u32,
out_buffer: *mut u8,
out_buffer_max_size: BufferSize,
) -> Result<BufferSize> {
let mut bytes_written = MaybeUninit::uninit();
let rc = wasi_ephemeral_nn::get_output(
context,
index,
out_buffer,
out_buffer_max_size,
bytes_written.as_mut_ptr(),
);
if let Some(err) = Error::from_raw_error(rc) {
Err(err)
} else {
Ok(bytes_written.assume_init())
}
}
pub unsafe fn compute(context: GraphExecutionContext) -> Result<()> {
let rc = wasi_ephemeral_nn::compute(context);
if let Some(err) = Error::from_raw_error(rc) {
Err(err)
} else {
Ok(())
}
}
#[allow(improper_ctypes)]
pub mod wasi_ephemeral_nn {
use super::*;
#[link(wasm_import_module = "wasi_ephemeral_nn")]
extern "C" {
pub fn load(
builder_ptr: *const GraphBuilder,
builder_len: usize,
encoding: GraphEncoding,
target: ExecutionTarget,
graph: *mut Graph,
) -> NnErrno;
pub fn init_execution_context(graph: Graph, context: *mut GraphExecutionContext)
-> NnErrno;
pub fn set_input(
context: GraphExecutionContext,
index: u32,
tensor: *mut Tensor,
) -> NnErrno;
pub fn get_output(
context: GraphExecutionContext,
index: u32,
out_buffer: *mut u8,
out_buffer_max_size: BufferSize,
bytes_written: *mut BufferSize,
) -> NnErrno;
pub fn compute(context: GraphExecutionContext) -> NnErrno;
}
}