metrale_model_layers/layers/ops/dispatch_proj/
cutlass.rs1use super::*;
13
14fn dequant_fp8_bf16_cached(
21 gpu: &dyn metrale_gpu_runtime::gpu::GpuBackend,
22 derived: &super::DerivedWeights,
23 fp8w: &crate::weight_map::Fp8Weight,
24 stream: u64,
25) -> anyhow::Result<u64> {
26 let cache_key = fp8w.weight.0;
27 if let Some(hit) = derived.get_ptr(super::Derivation::Bf16, cache_key) {
28 return Ok(hit);
29 }
30 let out = gpu.alloc(dequant_fp8_bf16_bytes(fp8w))?;
31 dequant_fp8_bf16_into(gpu, fp8w, out, stream)?;
32 derived.insert_ptr(super::Derivation::Bf16, cache_key, out.0);
33 Ok(out.0)
34}
35
36fn dequant_fp8_bf16_uncached(
39 gpu: &dyn metrale_gpu_runtime::gpu::GpuBackend,
40 fp8w: &crate::weight_map::Fp8Weight,
41 stream: u64,
42) -> anyhow::Result<metrale_gpu_runtime::gpu::DevicePtr> {
43 let out = gpu.alloc(dequant_fp8_bf16_bytes(fp8w))?;
44 dequant_fp8_bf16_into(gpu, fp8w, out, stream)?;
45 Ok(out)
46}
47
48#[allow(clippy::too_many_arguments)]
51pub fn cutlass_bf16_proj(
52 gpu: &dyn metrale_gpu_runtime::gpu::GpuBackend,
53 derived: &super::DerivedWeights,
54 act: metrale_gpu_runtime::gpu::DevicePtr,
55 fp8w: &crate::weight_map::Fp8Weight,
56 out: metrale_gpu_runtime::gpu::DevicePtr,
57 m: u32,
58 n: u32,
59 k: u32,
60 stream: u64,
61) -> anyhow::Result<()> {
62 let w_bf16 = dequant_fp8_bf16_cached(gpu, derived, fp8w, stream)?;
63 metrale_gpu_runtime::cutlass::bf16_gemm_act_weight_t(act.0, w_bf16, out.0, m, n, k, stream)
64}
65
66#[allow(clippy::too_many_arguments)]
67fn cutlass_nvfp4_weight_transposed_cached(
71 gpu: &dyn metrale_gpu_runtime::gpu::GpuBackend,
72 derived: &super::DerivedWeights,
73 weight_t: &crate::weight_map::QuantizedWeight,
74 n: u32,
75 k: u32,
76 stream: u64,
77) -> anyhow::Result<u64> {
78 let cache_key = weight_t.weight.0;
79 if let Some(hit) = derived.get_ptr(super::Derivation::CutlassNvfp4Transposed, cache_key) {
80 return Ok(hit);
81 }
82 let dst = gpu.alloc((n as usize) * (k as usize) / 2)?;
83 metrale_gpu_runtime::cutlass::transpose_nvfp4_packed_kton(
84 weight_t.weight.0,
85 dst.0,
86 n,
87 k,
88 stream,
89 )?;
90 gpu.synchronize(stream)?;
91 derived.insert_ptr(super::Derivation::CutlassNvfp4Transposed, cache_key, dst.0);
92 Ok(dst.0)
93}
94
95#[allow(clippy::too_many_arguments)]
96pub fn cutlass_nvfp4_proj(
100 ctx: &crate::layer::ForwardContext<'_>,
101 act: metrale_gpu_runtime::gpu::DevicePtr,
102 weight_t: &crate::weight_map::QuantizedWeight,
103 out: metrale_gpu_runtime::gpu::DevicePtr,
104 m: u32,
105 n: u32,
106 k: u32,
107 stream: u64,
108) -> anyhow::Result<()> {
109 let (gpu, derived) = (ctx.gpu, ctx.derived);
110 let packed = cutlass_nvfp4_weight_transposed_cached(gpu, derived, weight_t, n, k, stream)?;
111 metrale_gpu_runtime::cutlass::nvfp4_gemm_bf16_act_weight_t(
112 act.0,
113 packed,
114 weight_t.weight_scale.0,
115 weight_t.weight_scale_2,
116 out.0,
117 m,
118 n,
119 k,
120 stream,
121 )
122}
123
124fn cutlass_nvfp4_weight_from_fp8_cached(
125 gpu: &dyn metrale_gpu_runtime::gpu::GpuBackend,
126 derived: &super::DerivedWeights,
127 fp8w: &crate::weight_map::Fp8Weight,
128 stream: u64,
129) -> anyhow::Result<(u64, u64)> {
130 let cache_key = fp8w.weight.0;
131 if let Some(hit) = derived.get_pair(super::Derivation::CutlassNvfp4FromFp8, cache_key) {
132 return Ok(hit);
133 }
134
135 let n = fp8w.n as usize;
136 let k = fp8w.k as usize;
137 let w_bf16 = dequant_fp8_bf16_uncached(gpu, fp8w, stream)?;
138 let packed_t = gpu.alloc(n * k / 2)?;
139 let scale_t = gpu.alloc(n * k / 16)?;
140 metrale_gpu_runtime::cutlass::pack_bf16_weight_to_nvfp4_t(
141 w_bf16.0, packed_t.0, scale_t.0, fp8w.n, fp8w.k, stream,
142 )?;
143 gpu.synchronize(stream)?;
144 gpu.free(w_bf16)?;
145 derived.insert_pair(
146 super::Derivation::CutlassNvfp4FromFp8,
147 cache_key,
148 (packed_t.0, scale_t.0),
149 );
150 Ok((packed_t.0, scale_t.0))
151}
152
153#[allow(clippy::too_many_arguments)]
157pub fn cutlass_nvfp4_proj_from_fp8(
158 ctx: &crate::layer::ForwardContext<'_>,
159 act: metrale_gpu_runtime::gpu::DevicePtr,
160 fp8w: &crate::weight_map::Fp8Weight,
161 out: metrale_gpu_runtime::gpu::DevicePtr,
162 m: u32,
163 n: u32,
164 k: u32,
165 stream: u64,
166) -> anyhow::Result<()> {
167 let (gpu, derived) = (ctx.gpu, ctx.derived);
168 let (packed_t, scale_t) = cutlass_nvfp4_weight_from_fp8_cached(gpu, derived, fp8w, stream)?;
169 metrale_gpu_runtime::cutlass::nvfp4_gemm_bf16_act_weight_t(
170 act.0, packed_t, scale_t, 1.0, out.0, m, n, k, stream,
171 )
172}