spark_model/layers/ops/
fp8_gemv_batch.rs1use anyhow::{Result, ensure};
14use spark_runtime::gpu::{DevicePtr, GpuBackend, KernelHandle};
15use spark_runtime::kernel_args::{KernelLaunch, div_ceil};
16
17use crate::weight_map::Fp8DenseWeight;
18
19#[allow(clippy::too_many_arguments)]
29pub fn fp8_gemv_rowscale_batch8_rt2(
30 gpu: &dyn GpuBackend,
31 kernel: KernelHandle,
32 input: DevicePtr,
33 weight: &Fp8DenseWeight,
34 output: DevicePtr,
35 m: u32,
36 n: u32,
37 k: u32,
38 stream: u64,
39) -> Result<()> {
40 ensure!(
41 (1..=8).contains(&m),
42 "fp8_gemv_rowscale_batch8_rt2: m={m} outside 1..=8 (kernel MAX_M)"
43 );
44 ensure!(
45 k.is_multiple_of(16),
46 "fp8_gemv_rowscale_batch8_rt2: K={k} not a multiple of 16"
47 );
48 KernelLaunch::new(gpu, kernel)
49 .grid([div_ceil(n, 8), 1, 1])
50 .block([256, 1, 1])
51 .arg_ptr(input)
52 .arg_ptr(weight.weight)
53 .arg_ptr(weight.row_scale)
54 .arg_ptr(output)
55 .arg_u32(m)
56 .arg_u32(n)
57 .arg_u32(k)
58 .launch(stream)
59}
60
61#[allow(clippy::too_many_arguments)]
67pub fn fp8_gemv_rowscale_batch16_rt2(
68 gpu: &dyn GpuBackend,
69 kernel: KernelHandle,
70 input: DevicePtr,
71 weight: &Fp8DenseWeight,
72 output: DevicePtr,
73 m: u32,
74 n: u32,
75 k: u32,
76 stream: u64,
77) -> Result<()> {
78 ensure!(
79 (1..=16).contains(&m),
80 "fp8_gemv_rowscale_batch16_rt2: m={m} outside 1..=16 (kernel MAX_M)"
81 );
82 ensure!(
83 k.is_multiple_of(16),
84 "fp8_gemv_rowscale_batch16_rt2: K={k} not a multiple of 16"
85 );
86 KernelLaunch::new(gpu, kernel)
87 .grid([div_ceil(n, 8), 1, 1])
88 .block([256, 1, 1])
89 .arg_ptr(input)
90 .arg_ptr(weight.weight)
91 .arg_ptr(weight.row_scale)
92 .arg_ptr(output)
93 .arg_u32(m)
94 .arg_u32(n)
95 .arg_u32(k)
96 .launch(stream)
97}
98
99pub fn dense_gemv_fp8w_batch2(
102 gpu: &dyn GpuBackend,
103 kernel: KernelHandle,
104 input: DevicePtr,
105 weight: &Fp8DenseWeight,
106 output: DevicePtr,
107 n: u32,
108 k: u32,
109 stream: u64,
110) -> Result<()> {
111 KernelLaunch::new(gpu, kernel)
112 .grid([div_ceil(n, 4), 1, 1])
113 .block([256, 1, 1])
114 .arg_ptr(input)
115 .arg_ptr(weight.weight)
116 .arg_ptr(weight.row_scale)
117 .arg_ptr(output)
118 .arg_u32(n)
119 .arg_u32(k)
120 .launch(stream)
121}
122
123#[allow(clippy::too_many_arguments)]
130pub fn w8a16_gemv_batch4(
131 gpu: &dyn GpuBackend,
132 kernel: KernelHandle,
133 input: DevicePtr,
134 weight: DevicePtr,
135 block_scale: DevicePtr,
136 output: DevicePtr,
137 m: u32,
138 n: u32,
139 k: u32,
140 stream: u64,
141) -> Result<()> {
142 KernelLaunch::new(gpu, kernel)
143 .grid([div_ceil(n, 4), 1, 1])
144 .block([256, 1, 1])
145 .arg_ptr(input)
146 .arg_ptr(weight)
147 .arg_ptr(block_scale)
148 .arg_ptr(output)
149 .arg_u32(m)
150 .arg_u32(n)
151 .arg_u32(k)
152 .launch(stream)
153}
154
155#[allow(clippy::too_many_arguments)]
159pub fn w8a16_gemv_batch2(
160 gpu: &dyn GpuBackend,
161 kernel: KernelHandle,
162 input: DevicePtr,
163 weight: DevicePtr,
164 block_scale: DevicePtr,
165 output: DevicePtr,
166 n: u32,
167 k: u32,
168 stream: u64,
169) -> Result<()> {
170 KernelLaunch::new(gpu, kernel)
171 .grid([div_ceil(n, 4), 1, 1])
172 .block([256, 1, 1])
173 .arg_ptr(input)
174 .arg_ptr(weight)
175 .arg_ptr(block_scale)
176 .arg_ptr(output)
177 .arg_u32(n)
178 .arg_u32(k)
179 .launch(stream)
180}