atlas_core/
dtype.rs

1// SPDX-License-Identifier: AGPL-3.0-only
2
3use serde::{Deserialize, Serialize};
4
5/// Supported quantization and precision types for Atlas kernels.
6///
7/// Each variant maps to a specific bit-width and numeric format used by
8/// SM121 tensor cores or CUDA ALU paths.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
10pub enum DType {
11    /// 4-bit floating point (1 sign + 2 exponent + 1 mantissa)
12    /// Used for NVFP4 weight storage. Values: {0, 0.5, 1, 1.5, 2, 3, 4, 6}
13    E2M1,
14
15    /// 8-bit floating point (1 sign + 4 exponent + 3 mantissa)
16    /// Used for NVFP4 block scales and FP8 quantization
17    FP8E4M3,
18
19    /// 8-bit floating point (1 sign + 5 exponent + 2 mantissa)
20    /// Used for some FP8 quantization schemes
21    FP8E5M2,
22
23    /// 16-bit brain floating point
24    BF16,
25
26    /// 16-bit IEEE floating point
27    FP16,
28
29    /// 32-bit IEEE floating point
30    FP32,
31}
32
33impl DType {
34    /// Size in bytes per element. E2M1 is sub-byte (4 bits) but we report
35    /// the packed size (2 elements per byte).
36    pub const fn element_size_bits(&self) -> usize {
37        match self {
38            DType::E2M1 => 4,
39            DType::FP8E4M3 | DType::FP8E5M2 => 8,
40            DType::BF16 | DType::FP16 => 16,
41            DType::FP32 => 32,
42        }
43    }
44
45    /// Number of elements that pack into a 32-bit word.
46    pub const fn elements_per_u32(&self) -> usize {
47        32 / self.element_size_bits()
48    }
49}
50
51/// Quantization configuration for a weight tensor.
52#[derive(Debug, Clone, Serialize, Deserialize)]
53pub struct QuantConfig {
54    /// Weight storage type (e.g., E2M1 for NVFP4)
55    pub weight_type: DType,
56
57    /// Scale factor type (e.g., FP8E4M3 for NVFP4 block scales)
58    pub scale_type: DType,
59
60    /// Number of weights per scale factor (block size)
61    pub group_size: usize,
62
63    /// Global scale factor type (FP32 for NVFP4)
64    pub global_scale_type: DType,
65}
66
67impl QuantConfig {
68    /// NVFP4: E2M1 weights with FP8 block scales (group_size=16)
69    pub fn nvfp4() -> Self {
70        Self {
71            weight_type: DType::E2M1,
72            scale_type: DType::FP8E4M3,
73            group_size: 16,
74            global_scale_type: DType::FP32,
75        }
76    }
77
78    /// FP8 per-tensor quantization
79    pub fn fp8() -> Self {
80        Self {
81            weight_type: DType::FP8E4M3,
82            scale_type: DType::FP32,
83            group_size: 0, // per-tensor
84            global_scale_type: DType::FP32,
85        }
86    }
87}