use alloc::format;
use alloc::string::String;
use cubecl_common::backtrace::BackTrace;
use serde::{Deserialize, Serialize};
use thiserror::Error;
use crate::{BoolDType, DType, FloatDType, IntDType, QuantConfig};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct DeviceSettings {
pub float_dtype: FloatDType,
pub int_dtype: IntDType,
pub bool_dtype: BoolDType,
pub quantization: QuantConfig,
}
impl DeviceSettings {
pub fn new(
float_dtype: impl Into<FloatDType>,
int_dtype: impl Into<IntDType>,
bool_dtype: impl Into<BoolDType>,
quantization: QuantConfig,
) -> Self {
Self {
float_dtype: float_dtype.into(),
int_dtype: int_dtype.into(),
bool_dtype: bool_dtype.into(),
quantization,
}
}
pub fn with_dtypes(
float_dtype: impl Into<FloatDType>,
int_dtype: impl Into<IntDType>,
bool_dtype: impl Into<BoolDType>,
) -> Self {
Self::new(float_dtype, int_dtype, bool_dtype, Default::default())
}
}
#[derive(Debug, Error)]
pub enum DeviceError {
#[error("Device {device} does not support the requested data type {dtype:?}")]
UnsupportedDType {
device: String,
dtype: DType,
},
#[error(
"Device {device} settings have already been initialized and cannot be changed.\n\
Default data types lock on the first tensor operation for a device (or on a previous \
`set_default_dtypes`/`configure` call). Configure the device before creating any tensor \
on it, or create tensors with an explicit dtype instead."
)]
AlreadyInitialized {
device: String,
},
}
impl DeviceError {
pub fn unsupported_dtype<D: core::fmt::Debug + ?Sized>(device: &D, dtype: DType) -> Self {
Self::UnsupportedDType {
device: format!("{device:?}"),
dtype,
}
}
pub fn already_initialized<D: core::fmt::Debug + ?Sized>(device: &D) -> Self {
Self::AlreadyInitialized {
device: format!("{device:?}"),
}
}
}
#[derive(Error, Serialize, Deserialize)]
pub enum ExecutionError {
#[error("An error happened during execution\nCaused by:\n {reason}")]
WithContext {
reason: String,
},
#[error("An error happened during execution\nCaused by:\n {reason}")]
Generic {
reason: String,
#[serde(skip)]
backtrace: BackTrace,
},
}
impl core::fmt::Debug for ExecutionError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_fmt(format_args!("{self}"))
}
}