use std::ffi::{c_char, c_int, c_void};
use crate::TfLiteDelegate;
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct TfLiteXNNPackDelegateOptions {
pub num_threads: c_int,
pub flags: u32,
pub weights_cache: *mut c_void,
pub handle_variable_ops: bool,
pub weight_cache_file_path: *const c_char,
}
#[derive(Debug)]
pub struct XnnPackFunctions {
pub options_default: unsafe extern "C" fn() -> TfLiteXNNPackDelegateOptions,
pub create: unsafe extern "C" fn(*const TfLiteXNNPackDelegateOptions) -> *mut TfLiteDelegate,
pub delete: unsafe extern "C" fn(*mut TfLiteDelegate),
}
impl XnnPackFunctions {
#[must_use]
pub unsafe fn try_load(lib: &libloading::Library) -> Option<Self> {
unsafe {
Some(Self {
options_default: *lib.get(b"TfLiteXNNPackDelegateOptionsDefault\0").ok()?,
create: *lib.get(b"TfLiteXNNPackDelegateCreate\0").ok()?,
delete: *lib.get(b"TfLiteXNNPackDelegateDelete\0").ok()?,
})
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn options_clone_copy() {
let opts = TfLiteXNNPackDelegateOptions {
num_threads: 4,
flags: 1,
weights_cache: std::ptr::null_mut(),
handle_variable_ops: false,
weight_cache_file_path: std::ptr::null(),
};
let copied = opts;
assert_eq!(copied.num_threads, 4);
assert_eq!(copied.flags, 1);
}
#[test]
fn options_debug() {
let opts = TfLiteXNNPackDelegateOptions {
num_threads: 2,
flags: 0,
weights_cache: std::ptr::null_mut(),
handle_variable_ops: false,
weight_cache_file_path: std::ptr::null(),
};
let debug = format!("{opts:?}");
assert!(debug.contains("num_threads"));
assert!(debug.contains('2'));
}
#[test]
fn options_struct_size() {
let size = std::mem::size_of::<TfLiteXNNPackDelegateOptions>();
let expected = if cfg!(target_pointer_width = "64") {
32
} else {
20
};
assert_eq!(
size, expected,
"TfLiteXNNPackDelegateOptions has unexpected size: {size} bytes (expected {expected})",
);
}
}