use std::fmt::{Display, Write};
#[derive(Debug)]
pub enum ZyxError {
ShapeError(Box<str>),
DTypeError(Box<str>),
IOError(std::io::Error),
ParseError(Box<str>),
AllocationError(Box<str>),
NoBackendAvailable,
BackendError(BackendError),
KernelLaunchFailure,
}
impl ZyxError {
#[track_caller]
#[must_use]
pub fn shape_error(e: Box<str>) -> Self {
let location = std::panic::Location::caller();
let mut e: String = e.into();
write!(e, ", {}:{}:{}", location.file(), location.line(), location.column()).unwrap();
Self::ShapeError(e.into())
}
#[track_caller]
#[must_use]
pub fn dtype_error(e: Box<str>) -> Self {
let location = std::panic::Location::caller();
let mut e: String = e.into();
write!(e, ", {}:{}:{}", location.file(), location.line(), location.column()).unwrap();
Self::DTypeError(e.into())
}
#[track_caller]
#[must_use]
pub fn parse_error(e: Box<str>) -> Self {
let location = std::panic::Location::caller();
let mut e: String = e.into();
write!(e, ", {}:{}:{}", location.file(), location.line(), location.column()).unwrap();
Self::ParseError(e.into())
}
}
impl std::fmt::Display for ZyxError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ZyxError::ShapeError(e) => f.write_str(e),
ZyxError::DTypeError(e) => f.write_fmt(format_args!("Wrong dtype {e:?}")),
ZyxError::IOError(e) => f.write_fmt(format_args!("IO {e}")),
ZyxError::ParseError(e) => f.write_fmt(format_args!("IO {e}")),
ZyxError::NoBackendAvailable => f.write_fmt(format_args!("No available backend")),
ZyxError::AllocationError(e) => f.write_fmt(format_args!("Allocation error {e}")),
ZyxError::BackendError(e) => f.write_fmt(format_args!("Backend {e}")),
ZyxError::KernelLaunchFailure => f.write_fmt(format_args!(
"Multiple kernel variations failed to launch. Could be autotuner issue, but more likely faulty hardware driver."
)),
}
}
}
impl std::error::Error for ZyxError {}
impl From<std::io::Error> for ZyxError {
#[track_caller]
fn from(value: std::io::Error) -> Self {
Self::IOError(value)
}
}
#[derive(Debug)]
pub struct BackendError {
pub status: ErrorStatus,
pub context: Box<str>,
}
impl From<BackendError> for ZyxError {
fn from(value: BackendError) -> Self {
ZyxError::BackendError(value)
}
}
impl Display for BackendError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("{:?}: {}", self.status, self.context))
}
}
#[derive(Debug)]
pub enum ErrorStatus {
DyLibNotFound,
Initialization,
Deinitialization,
DeviceEnumeration,
DeviceQuery,
MemoryAllocation,
MemoryDeallocation,
MemoryCopyH2P,
MemoryCopyP2H,
IncorrectKernelArg,
KernelCompilation,
KernelLaunch,
KernelSync,
}