Skip to main content

ruda_kernel/dsl/frontend/element/float/
tensor_float.rs

1use ruda_core::tf32;
2use ruda_core::ir::{ConstantValue, ElemType, FloatKind, Scope, Type};
3use half::f16;
4
5use crate::dsl::prelude::*;
6
7use super::{RudaPrimitive, RudaType, Float, IntoRuntime, NativeAssign, NativeExpand};
8
9impl RudaType for tf32 {
10    type ExpandType = NativeExpand<tf32>;
11}
12
13impl Scalar for tf32 {}
14impl RudaPrimitive for tf32 {
15    type Scalar = Self;
16    type Size = Const<1>;
17    type WithScalar<S: Scalar> = S;
18
19    /// Return the element type to use on GPU
20    fn as_type_native() -> Option<Type> {
21        Some(ElemType::Float(FloatKind::TF32).into())
22    }
23
24    fn from_const_value(value: ConstantValue) -> Self {
25        let ConstantValue::Float(value) = value else {
26            unreachable!()
27        };
28        tf32::from_f64(value)
29    }
30}
31
32impl IntoRuntime for tf32 {
33    fn __expand_runtime_method(self, _scope: &mut Scope) -> NativeExpand<Self> {
34        self.into()
35    }
36}
37
38impl Numeric for tf32 {
39    fn min_value() -> Self {
40        Self::from_f32(f32::MIN)
41    }
42    fn max_value() -> Self {
43        Self::from_f32(f32::MAX)
44    }
45}
46
47impl NativeAssign for tf32 {}
48
49impl Float for tf32 {
50    const DIGITS: u32 = 32;
51
52    const EPSILON: Self = tf32::from_f32(half::f16::EPSILON.to_f32_const());
53
54    const INFINITY: Self = tf32::from_f32(f32::INFINITY);
55
56    const MANTISSA_DIGITS: u32 = 10;
57
58    /// Maximum possible [`ruda_core::tf32`] power of 10 exponent
59    const MAX_10_EXP: i32 = 38;
60    /// Maximum possible [`ruda_core::tf32`] power of 2 exponent
61    const MAX_EXP: i32 = 128;
62
63    /// Minimum possible normal [`ruda_core::tf32`] power of 10 exponent
64    const MIN_10_EXP: i32 = -37;
65    /// One greater than the minimum possible normal [`ruda_core::tf32`] power of 2 exponent
66    const MIN_EXP: i32 = -125;
67
68    /// `MIN_POSITIVE` is defined by precision, so use `f16` as reference
69    const MIN_POSITIVE: Self = tf32::from_f32(f16::MIN_POSITIVE.to_f32_const());
70
71    const NAN: Self = tf32::from_f32(f32::NAN);
72
73    const NEG_INFINITY: Self = tf32::from_f32(f32::NEG_INFINITY);
74
75    const RADIX: u32 = 2;
76
77    fn new(val: f32) -> Self {
78        tf32::from_f32(val)
79    }
80}