pub fn decode_w8a8_quant_act(
gpu: &dyn GpuBackend,
scratch: &DecodeW8a8Scratch,
act_bf16: DevicePtr,
rows: u32,
k: u32,
stream: u64,
) -> Result<()>Expand description
Quantize act[rows, k] BF16 ONCE into the shared scratch: FP8 E4M3 bytes +
per-token 1×128 FP32 scales, the phantom rows rows..ceil16(rows) zeroed,
and the VEC128 scales re-laid-out K-major for cuBLASLt.
Split from the GEMM so a caller with several projections over the SAME
activation pays it once — the attention layer’s Q/K/V share normed, so
quantizing inside the GEMM helper would run the quantizer and the scale
transpose three times per layer per step. Exactly the split
dense_ffn_w8a8_prefill makes for gate/up.
A zero scale kills the phantom rows’ CONTRIBUTION, but the FP8 dot product
still runs over whatever bytes are there and NaN * 0.0 is NaN — hence
the memset of the FP8 bytes and not only of the scales.