use std::{
ffi::CString,
os::raw::{c_char, c_int},
path::Path,
ptr,
};
use crate::object::Object;
use tvm_macros::Object;
use tvm_sys::ffi;
use crate::errors::Error;
use crate::String as TString;
use crate::{errors, function::Function};
#[repr(C)]
#[derive(Object, Debug)]
#[ref_name = "Module"]
#[type_key = "runtime.Module"]
pub struct ModuleNode {
base: Object,
}
crate::external! {
#[name("runtime.RuntimeEnabled")]
fn runtime_enabled(target: CString) -> i32;
#[name("runtime.ModuleLoadFromFile")]
fn load_from_file(file_name: CString, format: CString) -> Module;
#[name("runtime.ModuleSaveToFile")]
fn save_to_file(module: Module, name: TString, fmt: TString);
#[name("tvm.relay.module_export_library")]
fn export_library(module: Module, file_name: TString);
}
impl Module {
pub fn entry(&mut self) -> Option<Function> {
panic!()
}
pub fn get_function(&self, name: &str, query_import: bool) -> Result<Function, Error> {
let name = CString::new(name)?;
let mut fhandle = ptr::null_mut() as ffi::TVMFunctionHandle;
check_call!(ffi::TVMModGetFunction(
self.handle(),
name.as_ptr() as *const c_char,
query_import as c_int,
&mut fhandle as *mut _
));
if fhandle.is_null() {
return Err(errors::Error::NullHandle(name.into_string()?.to_string()));
}
Ok(Function::new(fhandle))
}
pub fn import_module(&self, dependent_module: Module) {
check_call!(ffi::TVMModImport(self.handle(), dependent_module.handle()))
}
pub fn load<P: AsRef<Path>>(path: &P) -> Result<Module, Error> {
let ext = CString::new(
path.as_ref()
.extension()
.unwrap_or_else(|| std::ffi::OsStr::new(""))
.to_str()
.ok_or_else(|| Error::ModuleLoadPath(path.as_ref().display().to_string()))?,
)?;
let cpath = CString::new(
path.as_ref()
.to_str()
.ok_or_else(|| Error::ModuleLoadPath(path.as_ref().display().to_string()))?,
)?;
let module = load_from_file(cpath, ext)?;
Ok(module)
}
pub fn save_to_file(&self, name: String, fmt: String) -> Result<(), Error> {
save_to_file(self.clone(), name.into(), fmt.into())
}
pub fn export_library(&self, name: String) -> Result<(), Error> {
export_library(self.clone(), name.into())
}
pub fn enabled(&self, target: &str) -> bool {
let target = CString::new(target).unwrap();
let enabled = runtime_enabled(target).unwrap();
enabled != 0
}
pub unsafe fn handle(&self) -> ffi::TVMModuleHandle {
self.0.clone().unwrap().into_raw() as *mut _
}
}