tenferro-gpu 0.2.0

CubeCL-backed CUDA and WebGPU provider backends for tenferro tensors.
Documentation
use tenferro_core_ops::{descriptor as primitive_descriptor, DTypePolicy, PrimitiveOpKind};

/// Host-side launch family used by the CubeCL primitive dispatcher.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum GpuLaunchKind {
    BinaryFloatComplex,
    BinaryFloatOnly,
    UnaryFloatComplex,
    UnaryFloatOnly,
    CompareFloatToBool,
    SelectBoolFloat,
    ClampFloat,
    Reduction,
}

/// GPU-specific primitive metadata derived from the core operation catalog.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) struct GpuOpDescriptor {
    pub(crate) kind: PrimitiveOpKind,
    pub(crate) name: &'static str,
    pub(crate) dtype_policy: DTypePolicy,
    pub(crate) launch: GpuLaunchKind,
}

pub(crate) fn gpu_descriptor(kind: PrimitiveOpKind) -> Option<GpuOpDescriptor> {
    let launch = match kind {
        PrimitiveOpKind::Add | PrimitiveOpKind::Mul | PrimitiveOpKind::Div => {
            GpuLaunchKind::BinaryFloatComplex
        }
        PrimitiveOpKind::Maximum | PrimitiveOpKind::Minimum | PrimitiveOpKind::Pow => {
            GpuLaunchKind::BinaryFloatOnly
        }
        PrimitiveOpKind::Neg | PrimitiveOpKind::Conj => GpuLaunchKind::UnaryFloatComplex,
        PrimitiveOpKind::Abs
        | PrimitiveOpKind::Sign
        | PrimitiveOpKind::Exp
        | PrimitiveOpKind::Log
        | PrimitiveOpKind::Sin
        | PrimitiveOpKind::Cos
        | PrimitiveOpKind::Tanh
        | PrimitiveOpKind::Sqrt
        | PrimitiveOpKind::Rsqrt
        | PrimitiveOpKind::Expm1
        | PrimitiveOpKind::Log1p => GpuLaunchKind::UnaryFloatOnly,
        PrimitiveOpKind::Compare => GpuLaunchKind::CompareFloatToBool,
        PrimitiveOpKind::Select => GpuLaunchKind::SelectBoolFloat,
        PrimitiveOpKind::Clamp => GpuLaunchKind::ClampFloat,
        PrimitiveOpKind::ReduceSum
        | PrimitiveOpKind::ReduceProd
        | PrimitiveOpKind::ReduceMax
        | PrimitiveOpKind::ReduceMin => GpuLaunchKind::Reduction,
        _ => return None,
    };

    let descriptor = primitive_descriptor(kind);
    Some(GpuOpDescriptor {
        kind,
        name: descriptor.name,
        dtype_policy: descriptor.dtype_policy,
        launch,
    })
}

pub(crate) fn require_gpu_descriptor(
    kind: PrimitiveOpKind,
    expected: GpuLaunchKind,
) -> crate::Result<GpuOpDescriptor> {
    let descriptor = gpu_descriptor(kind).ok_or_else(|| {
        crate::Error::backend_failure(
            "gpu_dispatch",
            format!("primitive {kind:?} is not implemented by CubeCL dispatch"),
        )
    })?;
    debug_assert_eq!(descriptor.launch, expected);
    Ok(descriptor)
}

#[cfg(test)]
mod tests;