pub fn w8a16_gemv_batch16(
gpu: &dyn GpuBackend,
kernel: KernelHandle,
input: DevicePtr,
weight: DevicePtr,
block_scale: DevicePtr,
output: DevicePtr,
m: u32,
n: u32,
k: u32,
stream: u64,
) -> Result<()>Expand description
MAX_M=16 sibling of w8a16_gemv_batch4, for decode concurrency 5..=16.
WHY (#927). On 1xH100 with Qwen/Qwen3.8-27B-FP8 the decode step measured 44 ms at 4 active rows and 224 ms at 16 — C=16 aggregate FELL from 76 to 62 tok/s when the batch cap went 4 -> 16, because every native-FP8 site stopped at the M<=4 GEMV and handed 5..16 rows to the transposed / pipelined tile GEMMs (5-12 TFLOP/s class, M padded to a 128-row MMA tile). This kernel streams the weight ONCE for up to 16 rows instead.
Same template body, same K-iteration order and the same per-row reduction
tree as w8a16_gemv_batch4, so each row is bit-identical to the scalar
w8a16_gemv (H100 receipt on #932: M=8/16 unequal_bf16=0). The wider
register array is the only difference.
Kernel: w8a16_gemv_batch16 (module w8a16_gemv_batch4).
Grid: (ceil(N/4), 1, 1) Block: (256, 1, 1)