2.5 KiB
2.5 KiB
NVFP4-1.1 Approach Update (2026-05-28)
CuTeDSL Float-to-Int Limitation
CuTeDSL CANNOT convert Float32 to Int32. Both cutlass.Int32(float_val) and float_val.to(cutlass.Int32) fail with "LLVM ERROR: unsupported operation" during PTX lowering. The MLIR arith.FloatToSIOp is generated but the LLVM backend cannot lower it.
This blocks in-kernel FP4 pack, which requires:
- FP8 E4M3 bit pattern computation (exponent + mantissa as integers)
- E2M1 nibble index computation (half_step → index as integer)
- Nibble packing into bytes (bit shifts and OR on integers)
What works in CuTeDSL
cute.arch.fmax,cute.arch.fmin— float min/max ✅cute.floor— floor function ✅cute.absf— float abs ✅cute.arch.load/cute.arch.store— scalar GMEM I/O ✅cute.arch.cvt_i8_bf16— int8 → BF16 (one-way) ✅cute.arch.cvt_f4e2m1_f16— FP4 → BF16 (one-way) ✅- Float arithmetic (+, -, *, /) ✅
- Type casts: Float32 ↔ BFloat16 ✅
- Int32 arithmetic (shifts, OR, AND) ✅ (but can't create Int32 from Float32!)
What does NOT work
- Float32 → Int32 conversion (any method)
- Inline PTX / inline assembly
- BF16 → Int8 (reverse of cvt_i8_bf16)
- BF16 → FP4 (reverse of cvt_f4e2m1_f16)
Revised approach: Compact SwiGLU output
Since in-kernel FP4 pack is blocked, the best optimization within CuTeDSL's capabilities is:
Modify the SwiGLU epilogue to skip writing gate subtiles to GMEM.
Current flow:
L1 GEMM → BF16 interleaved [gate*8, swiglu*8, ...] → 2*intermediate BF16
→ deinterleave_quantize_nvfp4_cuda → FP4 + SF
Target flow:
L1 GEMM → BF16 compact [swiglu, swiglu, ...] → intermediate BF16 (HALF the write!)
→ quantize_nvfp4_gpu → FP4 + SF (simpler kernel, no deinterleave)
Wins:
- 50% less BF16 GMEM written (skip gate columns)
- Simpler quantization kernel (no deinterleave needed)
- quantize_nvfp4_gpu is already tested and proven
The full FP4 fusion can be revisited when CuTeDSL adds float-to-int support or when the attention final-epilogue is rewritten in CUTLASS C++ (ROADMAP Priority 2).
Implementation plan
- Add
compact_outputtensor parameter to kernel (shape: (tokens, intermediate) BF16) - In epilogue: gate subtiles → skip SMEM write + TMA store
- Up subtiles → write to compact_output via TMA store (not the interleaved C tensor)
- This requires a new TMA atom and descriptor for the compact output
- Update runner and MoE layer to use quantize_nvfp4_gpu instead of deinterleave_quantize_nvfp4_cuda