1use anyhow::{Result, bail};
6use std::ffi::c_void;
7
8use super::*;
9
10#[allow(clippy::too_many_arguments)]
17pub fn fp8_gemm_act_weight_t_rowwise(
18 act_fp8: u64,
19 act_scale: u64,
20 weight_fp8: u64,
21 weight_scale: u64,
22 out: u64,
23 m: u32,
24 n: u32,
25 k: u32,
26 stream: u64,
27) -> Result<()> {
28 let ctx = ctx()?;
29 unsafe {
30 let mut desc: cublasLtMatmulDesc_t = std::ptr::null_mut();
31 chk(
32 cublasLtMatmulDescCreate(&mut desc, CUBLAS_COMPUTE_32F, CUDA_R_32F),
33 "DescCreate",
34 )?;
35 let ta = CUBLAS_OP_T;
36 let tb = CUBLAS_OP_N;
37 let set = |attr: u32, val: *const c_void, sz: usize, what: &str| -> Result<()> {
38 chk(cublasLtMatmulDescSetAttribute(desc, attr, val, sz), what)
39 };
40 set(DESC_TRANSA, &ta as *const i32 as *const c_void, 4, "TRANSA")?;
41 set(DESC_TRANSB, &tb as *const i32 as *const c_void, 4, "TRANSB")?;
42 let mode = SCALE_MODE_OUTER_VEC_32F;
43 set(
44 DESC_A_SCALE_MODE,
45 &mode as *const i32 as *const c_void,
46 4,
47 "A_SCALE_MODE",
48 )?;
49 set(
50 DESC_B_SCALE_MODE,
51 &mode as *const i32 as *const c_void,
52 4,
53 "B_SCALE_MODE",
54 )?;
55 set(
56 DESC_A_SCALE_POINTER,
57 &weight_scale as *const u64 as *const c_void,
58 8,
59 "A_SCALE_POINTER",
60 )?;
61 set(
62 DESC_B_SCALE_POINTER,
63 &act_scale as *const u64 as *const c_void,
64 8,
65 "B_SCALE_POINTER",
66 )?;
67
68 let mut la: cublasLtMatrixLayout_t = std::ptr::null_mut();
69 let mut lb: cublasLtMatrixLayout_t = std::ptr::null_mut();
70 let mut ld_: cublasLtMatrixLayout_t = std::ptr::null_mut();
71 chk(
72 cublasLtMatrixLayoutCreate(&mut la, CUDA_R_8F_E4M3, k as u64, n as u64, k as i64),
73 "LayoutA",
74 )?;
75 chk(
76 cublasLtMatrixLayoutCreate(&mut lb, CUDA_R_8F_E4M3, k as u64, m as u64, k as i64),
77 "LayoutB",
78 )?;
79 chk(
80 cublasLtMatrixLayoutCreate(&mut ld_, CUDA_R_16BF, n as u64, m as u64, n as i64),
81 "LayoutD",
82 )?;
83 let mut pref: cublasLtMatmulPreference_t = std::ptr::null_mut();
84 chk(cublasLtMatmulPreferenceCreate(&mut pref), "PrefCreate")?;
85 let ws_size = ctx.ws_size;
86 chk(
87 cublasLtMatmulPreferenceSetAttribute(
88 pref,
89 PREF_MAX_WORKSPACE_BYTES,
90 &ws_size as *const usize as *const c_void,
91 std::mem::size_of::<usize>(),
92 ),
93 "PrefWorkspace",
94 )?;
95 let mut result = [0u8; 128];
96 let mut returned: i32 = 0;
97 chk(
98 cublasLtMatmulAlgoGetHeuristic(
99 ctx.handle,
100 desc,
101 la,
102 lb,
103 ld_,
104 ld_,
105 pref,
106 1,
107 result.as_mut_ptr() as *mut c_void,
108 &mut returned,
109 ),
110 "AlgoGetHeuristic",
111 )?;
112 if returned < 1 {
113 bail!("cuBLASLt fp8 rowwise: no algorithm for {m}x{n}x{k}");
114 }
115 let alpha: f32 = 1.0;
116 let beta: f32 = 0.0;
117 let status = cublasLtMatmul(
118 ctx.handle,
119 desc,
120 &alpha as *const f32 as *const c_void,
121 weight_fp8 as *const c_void,
122 la,
123 act_fp8 as *const c_void,
124 lb,
125 &beta as *const f32 as *const c_void,
126 out as *const c_void,
127 ld_,
128 out as *mut c_void,
129 ld_,
130 result.as_ptr() as *const c_void,
131 ctx.workspace as *mut c_void,
132 ctx.ws_size,
133 stream as *mut c_void,
134 );
135 cublasLtMatmulPreferenceDestroy(pref);
136 cublasLtMatrixLayoutDestroy(la);
137 cublasLtMatrixLayoutDestroy(lb);
138 cublasLtMatrixLayoutDestroy(ld_);
139 cublasLtMatmulDescDestroy(desc);
140 chk(status, "Matmul")?;
141 }
142 Ok(())
143}
144
145#[allow(clippy::too_many_arguments)]
169pub fn fp8_gemm_act_weight_t_blkscaled(
170 act_fp8: u64,
171 act_scale: u64,
172 weight_fp8: u64,
173 weight_block_scale: u64,
174 out: u64,
175 m: u32,
176 n: u32,
177 k: u32,
178 stream: u64,
179) -> Result<()> {
180 fp8_gemm_act_weight_t_blkscaled_ldc(
181 act_fp8,
182 act_scale,
183 weight_fp8,
184 weight_block_scale,
185 out,
186 m,
187 n,
188 k,
189 n,
190 stream,
191 )
192}
193
194#[allow(clippy::too_many_arguments)]
217pub fn fp8_gemm_act_weight_t_blkscaled_ldc(
218 act_fp8: u64,
219 act_scale: u64,
220 weight_fp8: u64,
221 weight_block_scale: u64,
222 out: u64,
223 m: u32,
224 n: u32,
225 k: u32,
226 ldc: u32,
227 stream: u64,
228) -> Result<()> {
229 if ldc < n {
230 bail!("cuBLASLt fp8: output row pitch ldc={ldc} is shorter than N={n}");
231 }
232 let ctx = ctx()?;
233 unsafe {
234 let mut desc: cublasLtMatmulDesc_t = std::ptr::null_mut();
235 chk(
236 cublasLtMatmulDescCreate(&mut desc, CUBLAS_COMPUTE_32F, CUDA_R_32F),
237 "DescCreate",
238 )?;
239 let ta = CUBLAS_OP_T;
240 let tb = CUBLAS_OP_N;
241 let set = |attr: u32, val: *const c_void, sz: usize, what: &str| -> Result<()> {
242 chk(cublasLtMatmulDescSetAttribute(desc, attr, val, sz), what)
243 };
244 set(DESC_TRANSA, &ta as *const i32 as *const c_void, 4, "TRANSA")?;
245 set(DESC_TRANSB, &tb as *const i32 as *const c_void, 4, "TRANSB")?;
246 let a_mode = SCALE_MODE_BLK128X128_32F;
250 let b_mode = SCALE_MODE_VEC128_32F;
251 set(
252 DESC_A_SCALE_MODE,
253 &a_mode as *const i32 as *const c_void,
254 4,
255 "A_SCALE_MODE",
256 )?;
257 set(
258 DESC_B_SCALE_MODE,
259 &b_mode as *const i32 as *const c_void,
260 4,
261 "B_SCALE_MODE",
262 )?;
263 set(
264 DESC_A_SCALE_POINTER,
265 &weight_block_scale as *const u64 as *const c_void,
266 8,
267 "A_SCALE_POINTER",
268 )?;
269 set(
270 DESC_B_SCALE_POINTER,
271 &act_scale as *const u64 as *const c_void,
272 8,
273 "B_SCALE_POINTER",
274 )?;
275
276 let mut la: cublasLtMatrixLayout_t = std::ptr::null_mut();
277 let mut lb: cublasLtMatrixLayout_t = std::ptr::null_mut();
278 let mut ld_: cublasLtMatrixLayout_t = std::ptr::null_mut();
279 chk(
280 cublasLtMatrixLayoutCreate(&mut la, CUDA_R_8F_E4M3, k as u64, n as u64, k as i64),
281 "LayoutA",
282 )?;
283 chk(
284 cublasLtMatrixLayoutCreate(&mut lb, CUDA_R_8F_E4M3, k as u64, m as u64, k as i64),
285 "LayoutB",
286 )?;
287 chk(
288 cublasLtMatrixLayoutCreate(&mut ld_, CUDA_R_16BF, n as u64, m as u64, ldc as i64),
289 "LayoutD",
290 )?;
291 let mut pref: cublasLtMatmulPreference_t = std::ptr::null_mut();
292 chk(cublasLtMatmulPreferenceCreate(&mut pref), "PrefCreate")?;
293 let ws_size = ctx.ws_size;
294 chk(
295 cublasLtMatmulPreferenceSetAttribute(
296 pref,
297 PREF_MAX_WORKSPACE_BYTES,
298 &ws_size as *const usize as *const c_void,
299 std::mem::size_of::<usize>(),
300 ),
301 "PrefWorkspace",
302 )?;
303 let mut result = [0u8; 128];
304 let mut returned: i32 = 0;
305 chk(
306 cublasLtMatmulAlgoGetHeuristic(
307 ctx.handle,
308 desc,
309 la,
310 lb,
311 ld_,
312 ld_,
313 pref,
314 1,
315 result.as_mut_ptr() as *mut c_void,
316 &mut returned,
317 ),
318 "AlgoGetHeuristic",
319 )?;
320 if returned < 1 {
321 bail!("cuBLASLt fp8: no algorithm for {m}x{n}x{k}");
322 }
323 let alpha: f32 = 1.0;
324 let beta: f32 = 0.0;
325 let status = cublasLtMatmul(
326 ctx.handle,
327 desc,
328 &alpha as *const f32 as *const c_void,
329 weight_fp8 as *const c_void,
330 la,
331 act_fp8 as *const c_void,
332 lb,
333 &beta as *const f32 as *const c_void,
334 out as *const c_void,
335 ld_,
336 out as *mut c_void,
337 ld_,
338 result.as_ptr() as *const c_void,
339 ctx.workspace as *mut c_void,
340 ctx.ws_size,
341 stream as *mut c_void,
342 );
343 cublasLtMatmulPreferenceDestroy(pref);
344 cublasLtMatrixLayoutDestroy(la);
345 cublasLtMatrixLayoutDestroy(lb);
346 cublasLtMatrixLayoutDestroy(ld_);
347 cublasLtMatmulDescDestroy(desc);
348 chk(status, "Matmul")?;
349 }
350 Ok(())
351}