mirror of
https://github.com/pykeio/ort
synced 2026-04-25 16:34:55 +02:00
251 lines
8.0 KiB
Rust
251 lines
8.0 KiB
Rust
use alloc::sync::Arc;
|
|
use core::{
|
|
ffi::{self, CStr},
|
|
marker::PhantomData,
|
|
ptr::NonNull
|
|
};
|
|
|
|
use crate::{AsPointer, ortsys, util::with_cstr_ptr_array};
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
pub enum LogLevel {
|
|
Verbose,
|
|
Info,
|
|
Warning,
|
|
Error,
|
|
Fatal
|
|
}
|
|
|
|
impl From<LogLevel> for ort_sys::OrtLoggingLevel {
|
|
fn from(value: LogLevel) -> Self {
|
|
match value {
|
|
LogLevel::Verbose => ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_VERBOSE,
|
|
LogLevel::Info => ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_INFO,
|
|
LogLevel::Warning => ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_WARNING,
|
|
LogLevel::Error => ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_ERROR,
|
|
LogLevel::Fatal => ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_FATAL
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<ort_sys::OrtLoggingLevel> for LogLevel {
|
|
fn from(value: ort_sys::OrtLoggingLevel) -> Self {
|
|
match value {
|
|
ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_VERBOSE => LogLevel::Verbose,
|
|
ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_INFO => LogLevel::Info,
|
|
ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_WARNING => LogLevel::Warning,
|
|
ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_ERROR => LogLevel::Error,
|
|
ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_FATAL => LogLevel::Fatal
|
|
}
|
|
}
|
|
}
|
|
|
|
macro_rules! trace {
|
|
($($arg:tt)+) => {{
|
|
#[cfg(feature = "tracing")]
|
|
tracing::trace!($($arg)+);
|
|
}}
|
|
}
|
|
macro_rules! debug {
|
|
($($arg:tt)+) => {{
|
|
#[cfg(feature = "tracing")]
|
|
tracing::debug!($($arg)+);
|
|
}}
|
|
}
|
|
macro_rules! info {
|
|
($($arg:tt)+) => {{
|
|
#[cfg(feature = "tracing")]
|
|
tracing::info!($($arg)+);
|
|
}}
|
|
}
|
|
macro_rules! warning {
|
|
($($arg:tt)+) => {{
|
|
#[cfg(feature = "tracing")]
|
|
tracing::warn!($($arg)+);
|
|
}}
|
|
}
|
|
macro_rules! error {
|
|
($($arg:tt)+) => {{
|
|
#[cfg(feature = "tracing")]
|
|
tracing::error!($($arg)+);
|
|
}}
|
|
}
|
|
pub(crate) use debug;
|
|
pub(crate) use error;
|
|
pub(crate) use info;
|
|
pub(crate) use trace;
|
|
pub(crate) use warning;
|
|
|
|
macro_rules! create {
|
|
($name:ident, $ptr:expr) => {
|
|
$crate::trace!(target: "ort::lifetime", "+NEW {} @ {:p}", stringify!($name), $ptr);
|
|
};
|
|
}
|
|
macro_rules! drop {
|
|
($name:ident, $ptr:expr) => {
|
|
$crate::trace!(target: "ort::lifetime", "-DROP {} @ {:p}", stringify!($name), $ptr);
|
|
};
|
|
}
|
|
pub(crate) use create;
|
|
pub(crate) use drop;
|
|
|
|
pub(crate) fn default_log_level() -> ort_sys::OrtLoggingLevel {
|
|
#[cfg(feature = "std")]
|
|
match std::env::var("ORT_LOG").as_deref() {
|
|
Ok("fatal") => ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_FATAL,
|
|
Ok("error") => ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_ERROR,
|
|
Ok("warning") => ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_WARNING,
|
|
Ok("info") => ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_INFO,
|
|
Ok("verbose") => ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_VERBOSE,
|
|
_ => ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_ERROR
|
|
}
|
|
#[cfg(not(feature = "std"))]
|
|
ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_WARNING
|
|
}
|
|
|
|
/// Callback from C that will handle ONNX logging, forwarding ONNX's logs to the `tracing` crate.
|
|
#[cfg(feature = "tracing")]
|
|
pub(crate) extern "system" fn tracing_logger(
|
|
_params: *mut ffi::c_void,
|
|
severity: ort_sys::OrtLoggingLevel,
|
|
_: *const ffi::c_char,
|
|
id: *const ffi::c_char,
|
|
code_location: *const ffi::c_char,
|
|
message: *const ffi::c_char
|
|
) {
|
|
assert!(!code_location.is_null());
|
|
assert!(!message.is_null());
|
|
assert!(!id.is_null());
|
|
|
|
let code_location = unsafe { CStr::from_ptr(code_location) }.to_str().unwrap_or("<decode error>");
|
|
let message = unsafe { CStr::from_ptr(message) }.to_str().unwrap_or("<decode error>");
|
|
let id = unsafe { CStr::from_ptr(id) }.to_str().unwrap_or("<decode error>");
|
|
|
|
let span = tracing::span!(tracing::Level::TRACE, "ort", id = id, location = code_location);
|
|
|
|
match severity {
|
|
ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_VERBOSE => tracing::event!(parent: &span, tracing::Level::TRACE, "{message}"),
|
|
ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_INFO => tracing::event!(parent: &span, tracing::Level::INFO, "{message}"),
|
|
ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_WARNING => tracing::event!(parent: &span, tracing::Level::WARN, "{message}"),
|
|
ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_ERROR => tracing::event!(parent: &span, tracing::Level::ERROR, "{message}"),
|
|
ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_FATAL => tracing::event!(parent: &span, tracing::Level::ERROR, "(FATAL): {message}")
|
|
}
|
|
}
|
|
|
|
/// `LoggerFunction` accepts the message's [`LogLevel`], its category, log ID, code location, and the message
|
|
/// itself.
|
|
pub type LoggerFunction = Arc<dyn Fn(LogLevel, &str, &str, &str, &str) + Send + Sync>;
|
|
|
|
pub(crate) extern "system" fn custom_logger(
|
|
logger: *mut ffi::c_void,
|
|
severity: ort_sys::OrtLoggingLevel,
|
|
category: *const ffi::c_char,
|
|
id: *const ffi::c_char,
|
|
code_location: *const ffi::c_char,
|
|
message: *const ffi::c_char
|
|
) {
|
|
if category.is_null() || code_location.is_null() || message.is_null() || id.is_null() {
|
|
return;
|
|
}
|
|
|
|
let category = unsafe { CStr::from_ptr(code_location) }.to_str().unwrap_or("<decode error>");
|
|
let code_location = unsafe { CStr::from_ptr(code_location) }.to_str().unwrap_or("<decode error>");
|
|
let message = unsafe { CStr::from_ptr(message) }.to_str().unwrap_or("<decode error>");
|
|
let id = unsafe { CStr::from_ptr(id) }.to_str().unwrap_or("<decode error>");
|
|
|
|
let logger = logger.cast::<LoggerFunction>();
|
|
unsafe { (*logger)(LogLevel::from(severity), category, id, code_location, message) };
|
|
}
|
|
|
|
/// A reference to a session's logger, typically obtained in custom operator contexts.
|
|
///
|
|
/// Messages can be logged to a [`Logger`] via the [`log!`](crate::log) macro.
|
|
#[derive(Debug)]
|
|
pub struct Logger<'a> {
|
|
ptr: NonNull<ort_sys::OrtLogger>,
|
|
_p: PhantomData<&'a ()>
|
|
}
|
|
|
|
impl<'a> Logger<'a> {
|
|
pub(crate) unsafe fn from_raw(ptr: NonNull<ort_sys::OrtLogger>) -> Self {
|
|
Self { ptr, _p: PhantomData }
|
|
}
|
|
|
|
/// Returns the current [`LogLevel`] of this logger.
|
|
pub fn level(&self) -> LogLevel {
|
|
let mut log_level = ort_sys::OrtLoggingLevel::ORT_LOGGING_LEVEL_VERBOSE;
|
|
ortsys![unsafe Logger_GetLoggingSeverityLevel(self.ptr(), &mut log_level as *mut ort_sys::OrtLoggingLevel as *mut _).expect("infallible")];
|
|
LogLevel::from(log_level)
|
|
}
|
|
|
|
/// Logs a message to this logger with the given level and message.
|
|
///
|
|
/// For more convenient usage, see the [`log!`](crate::log) macro.
|
|
pub fn log(&self, level: LogLevel, message: &str, file_path: &str, line: u32, func_name: &str) {
|
|
let _ = with_cstr_ptr_array(&[message, func_name], &|arr| {
|
|
let (message, func_name) = (arr[0], arr[1]);
|
|
#[cfg(target_family = "windows")]
|
|
{
|
|
let file_path = crate::util::str_to_os_char(file_path);
|
|
ortsys![unsafe Logger_LogMessage(self.ptr.as_ptr(), level.into(), message, file_path.as_ptr(), line as _, func_name)?];
|
|
Ok(())
|
|
}
|
|
#[cfg(not(target_family = "windows"))]
|
|
crate::util::with_cstr(file_path.as_bytes(), &|file_path| {
|
|
ortsys![unsafe Logger_LogMessage(self.ptr.as_ptr(), level.into(), message, file_path.as_ptr(), line as _, func_name)?];
|
|
Ok(())
|
|
})
|
|
});
|
|
}
|
|
}
|
|
|
|
impl<'a> AsPointer for Logger<'a> {
|
|
type Sys = ort_sys::OrtLogger;
|
|
|
|
fn ptr(&self) -> *const Self::Sys {
|
|
self.ptr.as_ptr()
|
|
}
|
|
}
|
|
|
|
/// Logs a message to a given [`Logger`].
|
|
///
|
|
/// ```
|
|
/// # use ort::operator::{Kernel, KernelContext};
|
|
/// struct MyKernel;
|
|
///
|
|
/// impl Kernel for MyKernel {
|
|
/// fn compute(&mut self, ctx: &KernelContext) -> ort::Result<()> {
|
|
/// let logger = ctx.logger()?;
|
|
/// ort::log!(logger, Warning @ "something is off");
|
|
///
|
|
/// // log!() can also be used with formatting arguments:
|
|
/// ort::log!(logger, Info @ "value: {:?}", 42);
|
|
///
|
|
/// Ok(())
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// See [`LogLevel`] for supported log levels.
|
|
#[macro_export]
|
|
macro_rules! log {
|
|
($logger:expr, $level:ident @ $fmt:expr) => {{
|
|
($logger).log(
|
|
$crate::logging::LogLevel::$level,
|
|
&$crate::__private::alloc::format!($fmt),
|
|
$crate::__private::core::file!(),
|
|
$crate::__private::core::line!(),
|
|
$crate::__private::core::module_path!()
|
|
);
|
|
}};
|
|
($logger:expr, $level:ident @ $fmt:expr, $($arg:tt),+) => {{
|
|
($logger).log(
|
|
$crate::logging::LogLevel::$level,
|
|
&$crate::__private::alloc::format!($fmt, $($arg),+),
|
|
$crate::__private::core::file!(),
|
|
$crate::__private::core::line!(),
|
|
$crate::__private::core::module_path!()
|
|
);
|
|
}};
|
|
}
|