#[derive(Debug, thiserror::Error)]
pub(crate) enum CudaFftError {
#[error("invalid cuFFT configuration field: {field}")]
InvalidConfiguration { field: &'static str },
#[error("failed to load cuFFT symbol {name}: {source}")]
SymbolLoad {
name: String,
#[source]
source: libloading::Error,
},
#[error("failed to load cuFFT library (tried {paths}): {source}; attempts: {attempts}")]
LibraryLoad {
paths: String,
attempts: String,
#[source]
source: libloading::Error,
},
#[error("no cuFFT library candidates configured")]
NoLibraryCandidates,
#[error("cuFFT call {function} failed with status {status}")]
CufftStatus { function: &'static str, status: i32 },
#[error("CUDA interop failed during {operation}: {source}")]
Interop {
operation: &'static str,
#[source]
source: tenferro_tensor::BoxError,
},
#[error("primary cuFFT error: {primary}; suppressed error: {suppressed}")]
WithSuppressed {
#[source]
primary: Box<Self>,
suppressed: Box<Self>,
},
#[error("internal cuFFT plan invariant failed: {message}")]
InternalInvariant { message: &'static str },
}
pub(crate) fn into_tensor_error(op: &'static str, source: CudaFftError) -> tenferro_tensor::Error {
match source {
CudaFftError::InvalidConfiguration { field } => tenferro_tensor::Error::invalid_argument(
op,
field,
"cuFFT descriptor configuration is invalid",
),
CudaFftError::InternalInvariant { message } => {
tenferro_tensor::Error::Internal(message.into())
}
CudaFftError::LibraryLoad { .. } | CudaFftError::SymbolLoad { .. } => {
tenferro_tensor::Error::io_source(op, source)
}
source => tenferro_tensor::Error::backend_source(op, source),
}
}
impl CudaFftError {
pub(crate) fn interop(operation: &'static str, source: tenferro_tensor::Error) -> Self {
Self::Interop {
operation,
source: Box::new(source),
}
}
pub(crate) fn internal(message: &'static str) -> Self {
Self::InternalInvariant { message }
}
pub(crate) fn with_suppressed(primary: Self, suppressed: Self) -> Self {
Self::WithSuppressed {
primary: Box::new(primary),
suppressed: Box::new(suppressed),
}
}
#[cfg(test)]
pub(crate) fn test_interop(operation: &'static str) -> Self {
Self::Interop {
operation,
source: Box::new(std::io::Error::other("fake CUDA interop failure")),
}
}
}