|
4 | 4 |
|
5 | 5 | #pragma once |
6 | 6 |
|
| 7 | +#include <cstdio> |
| 8 | + |
7 | 9 | #include "cute/tensor.hpp" |
8 | 10 |
|
9 | 11 | #include "cutlass/cutlass.h" |
@@ -41,7 +43,23 @@ void run_flash_fwd_combine(Flash_fwd_params ¶ms, cudaStream_t stream, bool e |
41 | 43 |
|
42 | 44 | typename CombineKernel::Params kernel_params = CombineKernel::to_underlying_arguments(args); |
43 | 45 | int num_blocks_k = cute::ceil_div(params.dv, kBlockK); |
44 | | - int num_blocks_m = cute::ceil_div(params.seqlen_q * params.h, kBlockM); |
| 46 | + // [FIX] For varlen, size the combine grid from the actual total query extent |
| 47 | + // (params.total_q) instead of the per-request max seqlen_q, which under a |
| 48 | + // uniform-decode-captured CUDA graph is baked stale (=1), leaving the extra |
| 49 | + // query rows of a mixed/prefill replay uncombined -> uninitialized/NaN. |
| 50 | + int num_blocks_m = cute::ceil_div( |
| 51 | + (Varlen ? params.total_q : params.seqlen_q) * params.h, kBlockM); |
| 52 | + // [BUILD-VERIFY] one-time host print so we can confirm the rebuilt .so is loaded. |
| 53 | + static bool _fa3_combine_fix_printed = false; |
| 54 | + if (!_fa3_combine_fix_printed) { |
| 55 | + _fa3_combine_fix_printed = true; |
| 56 | + fprintf(stderr, |
| 57 | + "[FA3-COMBINE-FIX ACTIVE] Varlen=%d seqlen_q=%d total_q=%d h=%d " |
| 58 | + "kBlockM=%d -> num_blocks_m=%d\n", |
| 59 | + (int)Varlen, (int)params.seqlen_q, (int)params.total_q, |
| 60 | + (int)params.h, (int)kBlockM, num_blocks_m); |
| 61 | + fflush(stderr); |
| 62 | + } |
45 | 63 | dim3 grid_m(num_blocks_m, num_blocks_k, params.b); |
46 | 64 | auto kernel = cutlass::device_kernel<CombineKernel>; |
47 | 65 | int smem_size = CombineKernel::SharedStorageSize; |
|
0 commit comments