#[repr(C)]
#[derive(Clone, Copy)]
pub struct RnnFfiCounts {
pub layers: u64,
pub weights: u64,
pub biases: u64,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct RnnFfiModelInfo {
pub layers: u64,
pub weights: u64,
pub biases: u64,
pub input_size: u64,
pub output_size: u64,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct RnnFfiAbiInfo {
pub abi_version: u32,
pub struct_size: u32,
pub flags: u64,
pub reserved0: u64,
pub reserved1: u64,
}
#[repr(C)]
pub struct RnnFfiModelHandle {
_private: [u8; 0],
}
pub fn api_version() -> u32 {
1
}
pub fn is_abi_compatible(requested: u32) -> bool {
requested == 1
}
pub fn abi_info() -> RnnFfiAbiInfo {
RnnFfiAbiInfo {
abi_version: 1,
struct_size: core::mem::size_of::<RnnFfiAbiInfo>() as u32,
flags: 0,
reserved0: 0,
reserved1: 0,
}
}
pub fn model_create_from_bytes(bytes: &[u8]) -> Result<*mut RnnFfiModelHandle, i32> {
match crate::std::model_std::ModelStd::from_bytes(bytes) {
Ok(m) => {
let boxed = Box::new(m);
Ok(Box::into_raw(boxed) as *mut RnnFfiModelHandle)
}
Err(_) => Err(-1),
}
}
pub fn model_destroy(handle: *mut RnnFfiModelHandle) -> i32 {
if handle.is_null() {
return 0;
}
unsafe {
let raw = handle as *mut crate::std::model_std::ModelStd;
drop(Box::from_raw(raw));
}
0
}
pub fn model_get_info(handle: *const RnnFfiModelHandle) -> Result<RnnFfiModelInfo, i32> {
if handle.is_null() {
return Err(-1);
}
unsafe {
let model = &*(handle as *const crate::std::model_std::ModelStd);
let (layers, weights, biases) = model.info();
Ok(RnnFfiModelInfo {
layers: layers as u64,
weights: weights as u64,
biases: biases as u64,
input_size: model.input_size as u64,
output_size: model.output_size as u64,
})
}
}
pub fn model_run(handle: *const RnnFfiModelHandle, input: &[f32], output: &mut [f32]) -> i32 {
if handle.is_null() {
return -1;
}
unsafe {
let model = &*(handle as *const crate::std::model_std::ModelStd);
match model.run_single(input) {
Ok(v) => {
if v.len() != output.len() {
return -1;
}
output.copy_from_slice(&v);
0
}
Err(_) => -1,
}
}
}
pub fn run_once(bytes: &[u8], input: &[f32], output: &mut [f32]) -> i32 {
match crate::std::model_std::ModelStd::from_bytes(bytes) {
Ok(m) => match m.run_single(input) {
Ok(v) => {
if v.len() != output.len() {
return -1;
}
output.copy_from_slice(&v);
0
}
Err(_) => -1,
},
Err(_) => -1,
}
}
pub fn rnn_ffi_api_version() -> u32 {
api_version()
}
pub fn rnn_ffi_is_abi_compatible(requested: u32) -> i32 {
if is_abi_compatible(requested) {
1
} else {
0
}
}
pub fn rnn_ffi_abi_info(out_info: &mut RnnFfiAbiInfo) -> i32 {
*out_info = abi_info();
0
}
fn inner_rnn_ffi_model_create_from_bytes_v1(
bytes_ptr: *const u8,
bytes_len: usize,
) -> *mut RnnFfiModelHandle {
if bytes_ptr.is_null() {
return core::ptr::null_mut();
}
let bytes = unsafe { core::slice::from_raw_parts(bytes_ptr, bytes_len) };
match crate::std::model_std::ModelStd::from_bytes(bytes) {
Ok(m) => Box::into_raw(Box::new(m)) as *mut RnnFfiModelHandle,
Err(_) => core::ptr::null_mut(),
}
}
pub fn rnn_ffi_model_create_from_bytes_v1(bytes: &[u8]) -> usize {
if bytes.is_empty() {
return 0usize;
}
inner_rnn_ffi_model_create_from_bytes_v1(bytes.as_ptr(), bytes.len()) as usize
}
pub fn rnn_ffi_model_create_from_bytes(bytes: &[u8]) -> usize {
rnn_ffi_model_create_from_bytes_v1(bytes)
}
fn inner_rnn_ffi_model_destroy(handle: *mut RnnFfiModelHandle) -> i32 {
model_destroy(handle)
}
pub fn rnn_ffi_model_destroy(handle: usize) -> i32 {
inner_rnn_ffi_model_destroy(handle as *mut RnnFfiModelHandle)
}
fn inner_rnn_ffi_model_get_info(
handle: *const RnnFfiModelHandle,
out: *mut u8,
out_len: *mut usize,
) -> i32 {
if out_len.is_null() {
return -1;
}
match model_get_info(handle) {
Ok(info) => {
let info_bytes_vec = unsafe {
core::slice::from_raw_parts(
(&info as *const RnnFfiModelInfo) as *const u8,
core::mem::size_of::<RnnFfiModelInfo>(),
)
.to_vec()
};
let needed: usize = core::mem::size_of::<RnnFfiModelInfo>();
unsafe {
if !out.is_null() {
let out_cap = *out_len;
if out_cap < needed {
*out_len = needed;
return -1;
}
let dst = core::slice::from_raw_parts_mut(out, out_cap);
dst[..needed].copy_from_slice(&info_bytes_vec[..needed]);
*out_len = needed;
} else {
*out_len = needed;
}
}
0
}
Err(e) => e,
}
}
pub fn rnn_ffi_model_get_info(handle: usize) -> Result<Vec<u8>, i32> {
let mut needed: usize = core::mem::size_of::<RnnFfiModelInfo>();
let mut buf = vec![0u8; needed];
let rc = inner_rnn_ffi_model_get_info(
handle as *const RnnFfiModelHandle,
buf.as_mut_ptr(),
&mut needed as *mut usize,
);
if rc != 0 {
return Err(rc);
}
buf.truncate(needed);
Ok(buf)
}
unsafe fn inner_rnn_ffi_model_run(
handle: *const RnnFfiModelHandle,
input_ptr: *const f32,
input_len: usize,
output_ptr: *mut f32,
output_len: usize,
) -> i32 {
if input_ptr.is_null() || output_ptr.is_null() {
return -1;
}
let input = core::slice::from_raw_parts(input_ptr, input_len);
let output = core::slice::from_raw_parts_mut(output_ptr, output_len);
model_run(handle, input, output)
}
pub fn rnn_ffi_model_run(handle: usize, input: &[f32], output: &mut [f32]) -> i32 {
unsafe {
inner_rnn_ffi_model_run(
handle as *const RnnFfiModelHandle,
input.as_ptr(),
input.len(),
output.as_mut_ptr(),
output.len(),
)
}
}
unsafe fn inner_rnn_ffi_run_v1(
bytes_ptr: *const u8,
bytes_len: usize,
input_ptr: *const f32,
input_len: usize,
output_ptr: *mut f32,
output_len: usize,
) -> i32 {
if bytes_ptr.is_null() {
return -1;
}
let bytes = core::slice::from_raw_parts(bytes_ptr, bytes_len);
if input_ptr.is_null() || output_ptr.is_null() {
return -1;
}
let input = core::slice::from_raw_parts(input_ptr, input_len);
let output = core::slice::from_raw_parts_mut(output_ptr, output_len);
run_once(bytes, input, output)
}
pub fn rnn_ffi_run_v1(bytes: &[u8], input: &[f32], output: &mut [f32]) -> i32 {
unsafe {
inner_rnn_ffi_run_v1(
if bytes.is_empty() {
core::ptr::null()
} else {
bytes.as_ptr()
},
bytes.len(),
input.as_ptr(),
input.len(),
output.as_mut_ptr(),
output.len(),
)
}
}