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