use thiserror::Error;
#[derive(Debug, Error, Clone, PartialEq, Eq)]
pub enum AcceleratorError {
#[error("accelerator backend unavailable: {0}")]
BackendUnavailable(String),
#[error("CUDA device {ordinal} was not found")]
DeviceNotFound { ordinal: usize },
#[error("accelerator resource belongs to backend {expected}, not backend {found}")]
BackendMismatch { expected: u64, found: u64 },
#[error("FVM state belongs to plan {found}, not plan {expected}")]
PlanMismatch { expected: u64, found: u64 },
#[error("device allocation of {bytes} bytes failed: {reason}")]
AllocationFailed { bytes: usize, reason: String },
#[error("CUDA kernel compilation failed: {0}")]
KernelCompilationFailed(String),
#[error("CUDA module load failed: {0}")]
ModuleLoadFailed(String),
#[error("CUDA kernel `{0}` was not found")]
KernelNotFound(String),
#[error("CUDA kernel launch failed: {0}")]
KernelLaunchFailed(String),
#[error("CUDA stream index {index} is out of range for {stream_count} streams")]
InvalidStreamIndex { index: usize, stream_count: usize },
#[error("CUDA event operation failed: {0}")]
EventFailed(String),
#[error("CUDA sparse-library operation failed: {0}")]
SparseLibraryFailed(String),
#[error("device transfer failed: {0}")]
DeviceTransferFailed(String),
#[error("stale topology plan: expected version {expected}, found {found}")]
StaleTopologyPlan { expected: u64, found: u64 },
#[error("stale atlas plan: expected version {expected}, found {found}")]
StaleAtlasPlan { expected: u64, found: u64 },
#[error("stale geometry plan: expected epoch {expected}, found {found}")]
StaleGeometryPlan { expected: u64, found: u64 },
#[error("buffer length mismatch: expected {expected}, found {found}")]
LengthMismatch { expected: usize, found: usize },
#[error("{what} value {value} exceeds the device ABI limit")]
IndexOverflow { what: &'static str, value: usize },
#[error("unsupported device value type: {0}")]
UnsupportedDeviceType(&'static str),
#[error("invalid accelerator plan: {0}")]
InvalidPlan(String),
}