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