use crate::{Arena, Result, check};
use iree_embedded_sys as sys;
pub type LibraryQueryFn = unsafe extern "C" fn(
max_version: u32,
environment: *const core::ffi::c_void,
) -> *const core::ffi::c_void;
pub struct Device {
raw: *mut sys::iree_hal_device_t,
}
impl Device {
pub fn local_sync_static(arena: &Arena, libraries: &[LibraryQueryFn]) -> Result<Self> {
let alloc = arena.as_iree_allocator();
unsafe {
let mut loader = core::ptr::null_mut();
check(sys::iree_hal_static_library_loader_create(
libraries.len() as _,
libraries.as_ptr() as *const sys::iree_hal_executable_library_query_fn_t,
sys::iree_hal_executable_import_provider_null(),
alloc,
&mut loader,
))?;
Self::from_loader(loader, alloc)
}
}
pub fn local_sync(arena: &Arena) -> Result<Self> {
let alloc = arena.as_iree_allocator();
unsafe {
let mut loader = core::ptr::null_mut();
check(sys::iree_hal_embedded_elf_loader_create(
core::ptr::null_mut(), alloc,
&mut loader,
))?;
Self::from_loader(loader, alloc)
}
}
unsafe fn from_loader(
mut loader: *mut sys::iree_hal_executable_loader_t,
alloc: sys::iree_allocator_t,
) -> Result<Self> {
unsafe {
let id = sys::iree_make_cstring_view(c"local-sync".as_ptr());
let mut device_allocator = core::ptr::null_mut();
let status =
sys::iree_hal_allocator_create_heap(id, alloc, alloc, &mut device_allocator);
let mut params: sys::iree_hal_sync_device_params_t = core::mem::zeroed();
sys::iree_hal_sync_device_params_initialize(&mut params);
params.arena_block_size = 4096;
let mut raw = core::ptr::null_mut();
let status = if status.is_null() {
sys::iree_hal_sync_device_create(
id,
¶ms,
1, &mut loader,
device_allocator,
alloc,
&mut raw,
)
} else {
status
};
sys::iree_hal_allocator_release(device_allocator);
sys::iree_hal_executable_loader_release(loader);
check(status)?;
Ok(Device { raw })
}
}
}
impl Device {
pub(crate) fn raw(&self) -> *mut sys::iree_hal_device_t {
self.raw
}
}
impl Drop for Device {
fn drop(&mut self) {
unsafe { sys::iree_hal_device_release(self.raw) };
}
}