hpt 0.1.3

High Performance Tensor (HPT) - A fast, efficient, and user-friendly tensor computation library for Rust
Documentation
use cudarc::driver::DeviceRepr;
use hpt_allocator::{
    traits::{Allocator, AllocatorOutputRetrive},
    Cuda,
};
use hpt_common::{error::base::TensorError, shape::shape::Shape};
use hpt_traits::{
    ops::normalization::NormalizationOps,
    tensor::{CommonBounds, TensorInfo},
};
use hpt_types::{
    dtype::{CudaType, TypeCommon},
    into_scalar::Cast,
    into_vec::IntoVec,
    type_promote::{FloatOutBinary, FloatOutUnary, FloatOutUnaryPromote, NormalOut},
};

use crate::tensor_base::_Tensor;

use super::layernorm::layernorm;
use super::softmax::{contiguous_softmax, uncontiguous_softmax};
type FloatBinaryType<T> = <T as FloatOutBinary>::Output;

impl<T, const DEVICE: usize, A> NormalizationOps for _Tensor<T, Cuda, DEVICE, A>
where
    T: CommonBounds
        + FloatOutBinary
        + Cast<FloatBinaryType<T>>
        + FloatOutUnary<Output = FloatBinaryType<T>>
        + CudaType
        + DeviceRepr,
    <T as FloatOutUnaryPromote>::Intermediate: DeviceRepr,
    T::Vec: FloatOutUnary<Output = <FloatBinaryType<T> as TypeCommon>::Vec>
        + IntoVec<<FloatBinaryType<T> as TypeCommon>::Vec>,
    FloatBinaryType<T>: CommonBounds
        + FloatOutUnary<Output = FloatBinaryType<T>>
        + NormalOut<T, Output = FloatBinaryType<T>>
        + CudaType
        + DeviceRepr,
    <FloatBinaryType<T> as TypeCommon>::Vec:
        FloatOutUnary<Output = <FloatBinaryType<T> as TypeCommon>::Vec>,
    A: Allocator + Send + Sync,
    A::Output: AllocatorOutputRetrive,
{
    type Output = _Tensor<FloatBinaryType<T>, Cuda, DEVICE, A>;

    type OutputMeta = FloatBinaryType<T>;

    fn layernorm<S: Into<Shape>>(
        &self,
        normalized_shape: S,
        gamma: Option<&Self::Output>,
        beta: Option<&Self::Output>,
        eps: Self::OutputMeta,
    ) -> Result<Self::Output, TensorError>
    where
        usize: Cast<Self::OutputMeta>,
    {
        let normalized_shape: Shape = normalized_shape.into();
        layernorm(
            self,
            gamma,
            beta,
            eps,
            &normalized_shape,
            None::<Self::Output>,
        )
    }

    fn softmax(&self, axis: i64) -> Result<Self::Output, TensorError> {
        let res = if self.is_contiguous() && self.parent().is_none() {
            contiguous_softmax(self, axis, None::<Self::Output>, false)?
        } else {
            uncontiguous_softmax(self, axis, None::<Self::Output>, false)?
        };
        Ok(res)
    }

    fn log_softmax(&self, axis: i64) -> Result<Self::Output, TensorError> {
        let res = if self.is_contiguous() && self.parent().is_none() {
            contiguous_softmax(self, axis, None::<Self::Output>, true)?
        } else {
            uncontiguous_softmax(self, axis, None::<Self::Output>, true)?
        };
        Ok(res)
    }
}