#[derive(Debug, Clone)]
pub enum CudaDispatchError {
CudaNotAvailable,
RuntimeError(String),
FeatureNotEnabled,
}
impl std::fmt::Display for CudaDispatchError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
CudaDispatchError::CudaNotAvailable => {
write!(f, "CUDA runtime not available on this host")
}
CudaDispatchError::RuntimeError(msg) => {
write!(f, "CUDA runtime error: {msg}")
}
CudaDispatchError::FeatureNotEnabled => {
write!(f, "feature `cuda_kernels` not enabled at compile time")
}
}
}
}
pub const GAMMA_PTX_STUB: &str = r#"
// gamma_batch.cu (stub — not compiled)
//
// __global__ void gamma_batch_kernel(const float* in, float* out, int n) {
// int idx = blockIdx.x * blockDim.x + threadIdx.x;
// if (idx >= n) return;
// out[idx] = tgammaf(in[idx]); // CUDA built-in
// }
"#;
pub const ERF_PTX_STUB: &str = r#"
// erf_batch.cu (stub — not compiled)
//
// __global__ void erf_batch_kernel(const float* in, float* out, int n) {
// int idx = blockIdx.x * blockDim.x + threadIdx.x;
// if (idx >= n) return;
// out[idx] = erff(in[idx]); // CUDA built-in
// }
"#;
pub const BESSEL_J0_PTX_STUB: &str = r#"
// bessel_j0_batch.cu (stub — not compiled)
//
// __global__ void bessel_j0_batch_kernel(const float* in, float* out, int n) {
// int idx = blockIdx.x * blockDim.x + threadIdx.x;
// if (idx >= n) return;
// out[idx] = j0f(in[idx]); // POSIX math built-in (available in libm / CUDA)
// }
"#;
#[allow(unused_variables)]
pub fn gamma_batch_cuda(xs: &[f64]) -> Result<Vec<f64>, CudaDispatchError> {
#[cfg(feature = "cuda_kernels")]
{
return Err(CudaDispatchError::RuntimeError(
"cuda_kernels feature is declared but not yet implemented".into(),
));
}
#[allow(unreachable_code)]
Err(CudaDispatchError::FeatureNotEnabled)
}
#[allow(unused_variables)]
pub fn erf_batch_cuda(xs: &[f64]) -> Result<Vec<f64>, CudaDispatchError> {
#[cfg(feature = "cuda_kernels")]
{
return Err(CudaDispatchError::RuntimeError(
"cuda_kernels feature is declared but not yet implemented".into(),
));
}
#[allow(unreachable_code)]
Err(CudaDispatchError::FeatureNotEnabled)
}
#[allow(unused_variables)]
pub fn bessel_j0_batch_cuda(xs: &[f64]) -> Result<Vec<f64>, CudaDispatchError> {
#[cfg(feature = "cuda_kernels")]
{
return Err(CudaDispatchError::RuntimeError(
"cuda_kernels feature is declared but not yet implemented".into(),
));
}
#[allow(unreachable_code)]
Err(CudaDispatchError::FeatureNotEnabled)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_gamma_cuda_stub_returns_feature_not_enabled() {
let xs = vec![1.0_f64, 2.0, 3.0];
let result = gamma_batch_cuda(&xs);
assert!(
matches!(
result,
Err(CudaDispatchError::FeatureNotEnabled) | Err(CudaDispatchError::RuntimeError(_))
),
"unexpected result: {:?}",
result
);
}
#[test]
fn test_erf_cuda_stub_returns_error() {
let xs = vec![0.0_f64, 1.0];
let result = erf_batch_cuda(&xs);
assert!(result.is_err());
}
#[test]
fn test_bessel_j0_cuda_stub_returns_error() {
let xs = vec![0.0_f64, 2.405];
let result = bessel_j0_batch_cuda(&xs);
assert!(result.is_err());
}
#[test]
fn test_cuda_dispatch_error_display() {
let e = CudaDispatchError::CudaNotAvailable;
assert!(e.to_string().contains("not available"));
let e2 = CudaDispatchError::RuntimeError("device OOM".into());
assert!(e2.to_string().contains("device OOM"));
let e3 = CudaDispatchError::FeatureNotEnabled;
assert!(e3.to_string().contains("cuda_kernels"));
}
#[test]
fn test_ptx_stub_sources_are_non_empty() {
assert!(!GAMMA_PTX_STUB.is_empty());
assert!(!ERF_PTX_STUB.is_empty());
assert!(!BESSEL_J0_PTX_STUB.is_empty());
}
}