use crate::hip;
use std::fmt;
use std::error::Error as StdError;
use std::ffi::CStr;
use super::bindings;
#[derive(Debug, Clone, Copy)]
pub struct Error {
status: u32, }
pub type Result<T> = std::result::Result<T, Error>;
impl Error {
pub fn new(status: u32) -> Self {
Self { status }
}
pub fn is_success(&self) -> bool {
self.status == bindings::hsa_status_t_HSA_STATUS_SUCCESS
}
pub fn code(&self) -> u32 {
self.status
}
pub fn from_hsa_status<T>(status: u32) -> Result<T>
where
T: Default,
{
if status == bindings::hsa_status_t_HSA_STATUS_SUCCESS {
Ok(T::default())
} else {
Err(Error::new(status))
}
}
pub fn from_hsa_status_with_value<T>(status: u32, value: T) -> Result<T> {
if status == bindings::hsa_status_t_HSA_STATUS_SUCCESS {
Ok(value)
} else {
Err(Error::new(status))
}
}
pub fn description(&self) -> &'static str {
match self.status {
bindings::hsa_status_t_HSA_STATUS_SUCCESS => "Success",
bindings::hsa_status_t_HSA_STATUS_ERROR => "Generic error",
bindings::hsa_status_t_HSA_STATUS_ERROR_INVALID_ARGUMENT => "Invalid argument",
bindings::hsa_status_t_HSA_STATUS_ERROR_OUT_OF_RESOURCES => "Out of resources",
bindings::hsa_status_t_HSA_STATUS_ERROR_NOT_INITIALIZED => "Not initialized",
bindings::hsa_status_t_HSA_STATUS_ERROR_INVALID_AGENT => "Invalid agent",
bindings::hsa_status_t_HSA_STATUS_ERROR_INVALID_REGION => "Invalid region",
_ => unsafe {
let mut error_str_ptr = std::ptr::null();
if bindings::rocprofiler_error_string(&mut error_str_ptr) == bindings::hsa_status_t_HSA_STATUS_SUCCESS && !error_str_ptr.is_null() {
let c_str = CStr::from_ptr(error_str_ptr);
match c_str.to_str() {
Ok(s) => {
s
}
Err(_) => "Unknown error (invalid UTF-8 in error string)",
}
} else {
"Unknown error"
}
}
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "ROCProfiler error {}: {}", self.status, self.description())
}
}
impl StdError for Error {}
impl From<hip::Error> for Error {
fn from(error: hip::Error) -> Self {
Error::new(bindings::hsa_status_t_HSA_STATUS_ERROR)
}
}