Skip to content

[Common] Experimental CuTeDSL MXFP8 backends in C++ via TVM-FFI - #3137

Open
kainzhong wants to merge 55 commits into
NVIDIA:mainfrom
kainzhong:cutedsl_mxfp8_common
Open

[Common] Experimental CuTeDSL MXFP8 backends in C++ via TVM-FFI#3137
kainzhong wants to merge 55 commits into
NVIDIA:mainfrom
kainzhong:cutedsl_mxfp8_common

Conversation

@kainzhong

@kainzhong kainzhong commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator

Description

Adds an experimental, opt-in CuTeDSL backend for MXFP8 quantization. MXFP8 nvte_quantize calls can be routed to JIT-compiled CuTeDSL (CUTLASS Python DSL) kernels instead of the existing CUDA C++ kernels, bridged into the C++ dispatcher via apache-tvm-ffi (https://github.com/apache/tvm-ffi).

It's off by default (use NVTE_ENABLE_CUTEDSL_QUANT_BACKEND=1 to enable) and transparently falls back to the CUDA kernels for any unsupported config or shape (use NVTE_WARN_IF_CUTEDSL_BACKEND_NOT_CHOSEN=1 to enable warning for unsupported cases).

How it works

  • Python CuTeDSL kernels (transformer_engine/common/CuTeDSL/) register a factory as a TVM-FFI global.
  • On a matching MXFP8 quantize, the C++ dispatcher builds a config key, asks Python to JIT-compile + register a kernel for that config (cached), then invokes it with DLTensor views of the TE tensors.
  • Any miss (backend disabled, unsupported config, non-32-aligned shape) returns false → existing mxfp8::quantize CUDA path runs unchanged.

Type of change

  • Documentation change (change only to the documentation, either a fix or a new content)
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Infra/Build change
  • Code refactoring

Changes

  • Added utility classes and functions to retrieve TVM-FFI global functions using strings
  • Ported MXFP8 CUDA C++ quantization code to CuTeDSL

Breaking changes:

  • Building TE now requires apache-tvm-ffi package installed
  • TE uses now need to install apache-tvm-ffi and nvidia-cutlass-dsl packages if they set NVTE_ENABLE_CUTEDSL_QUANT_BACKEND=1. Otherwise they should be fine (pythonwouldn't load tvm-ffi library to make it available in C++ and register CuTeDSL kernels, and C++ wouldn't be able to use dlopen to load libtvm_ffi.so loaded from python so it will fall back to CUDA kernels)

Checklist:

  • I have read and followed the contributing guidelines
  • The functionality is complete
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@kainzhong
kainzhong force-pushed the cutedsl_mxfp8_common branch from daee750 to 218cd24 Compare June 27, 2026 08:27
@kainzhong
kainzhong force-pushed the cutedsl_mxfp8_common branch 4 times, most recently from 2f8c8da to 8448930 Compare July 8, 2026 21:44
@kainzhong

kainzhong commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator Author

Benchmark on ptyche (B200 GPU, ARM CPU):
The benchmark scripts can be found in https://github.com/kainzhong/TransformerEngine/blob/cutedsl_mxfp8_common_bench/tests/pytorch/mxfp8/run_mxfp8_benchmark.py

                         tag        shape   dir   GPU_cpp_us   GPU_dsl_us   GPU_x   cpp_GB/s   dsl_GB/s   CPU_cpp_us   CPU_dsl_us   CPU_x
-----------------------------------------------------------------------------------------------------------------------------------------
          dbias_bf16_e4m3_sw   4096x14336  both        57.75        47.05    1.23     4130.8     5070.4        19.77        23.02    0.86
          dbias_bf16_e4m3_sw   4096x14336   col        39.31        37.20    1.06     4527.9     4785.3        16.89        20.73    0.81
          dbias_bf16_e4m3_sw   4096x14336   row        46.60        43.50    1.07     3820.0     4092.0        17.55        20.32    0.86
          dbias_bf16_e4m3_sw    4096x4096  both        23.87        20.74    1.15     2854.9     3285.8        20.93        22.20    0.94
          dbias_bf16_e4m3_sw    4096x4096   col        17.62        16.27    1.08     2886.7     3126.5        16.55        19.64    0.84
          dbias_bf16_e4m3_sw    4096x4096   row        19.54        19.14    1.02     2602.1     2657.5        16.55        20.25    0.82
          dbias_bf16_e4m3_sw    4096x8192  both        37.81        31.37    1.21     3605.0     4345.0        19.95        22.01    0.91
          dbias_bf16_e4m3_sw    4096x8192   col        26.70        25.56    1.04     3809.4     3979.9        17.23        20.80    0.83
          dbias_bf16_e4m3_sw    4096x8192   row        31.01        28.86    1.07     3279.5     3524.1        17.34        20.11    0.86
          dbias_bf16_e4m3_sw    8192x8192  both        70.53        59.30    1.19     3865.3     4597.6        19.70        23.57    0.84
          dbias_bf16_e4m3_sw    8192x8192   col        49.02        47.63    1.03     4150.0     4271.3        17.35        20.26    0.86
          dbias_bf16_e4m3_sw    8192x8192   row        57.26        54.08    1.06     3552.7     3761.6        17.71        20.02    0.88
             dbias_bf16_e4m3   4096x14336  both        56.96        48.11    1.18     4188.0     4958.7        20.00        23.56    0.85
             dbias_bf16_e4m3   4096x14336   col        39.12        36.81    1.06     4549.9     4835.0        16.74        19.95    0.84
             dbias_bf16_e4m3   4096x14336   row        51.61        43.53    1.19     3448.6     4088.6        16.73        20.37    0.82
             dbias_bf16_e4m3    4096x4096  both        23.45        20.51    1.14     2906.8     3323.9        19.88        22.98    0.87
             dbias_bf16_e4m3    4096x4096   col        17.55        16.20    1.08     2897.9     3139.1        16.59        19.27    0.86
             dbias_bf16_e4m3    4096x4096   row        21.50        19.23    1.12     2365.6     2644.9        16.92        19.80    0.85
             dbias_bf16_e4m3    4096x8192  both        37.33        31.24    1.19     3651.2     4363.0        19.78        23.39    0.85
             dbias_bf16_e4m3    4096x8192   col        26.74        25.20    1.06     3803.8     4035.9        16.39        19.72    0.83
             dbias_bf16_e4m3    4096x8192   row        34.06        29.10    1.17     2986.4     3495.0        17.27        20.58    0.84
             dbias_bf16_e4m3    8192x8192  both        69.48        59.39    1.17     3924.0     4590.9        19.50        23.61    0.83
             dbias_bf16_e4m3    8192x8192   col        49.12        47.46    1.03     4141.7     4286.5        16.99        19.98    0.85
             dbias_bf16_e4m3    8192x8192   row        63.04        54.15    1.16     3226.9     3756.7        16.86        20.39    0.83
          dgelu_bf16_e4m3_sw   4096x14336  both       145.47        94.98    1.53     2447.2     3748.0        13.40        16.82    0.80
          dgelu_bf16_e4m3_sw   4096x14336   col        91.89        76.65    1.20     3215.2     3854.2        10.51        13.22    0.79
          dgelu_bf16_e4m3_sw   4096x14336   row        93.62        76.58    1.22     3155.7     3857.9        10.50        14.35    0.73
          dgelu_bf16_e4m3_sw    4096x4096  both        45.90        31.29    1.47     2216.0     3250.5        13.06        16.04    0.81
          dgelu_bf16_e4m3_sw    4096x4096   col        30.34        25.68    1.18     2781.8     3287.5        10.09        13.34    0.76
          dgelu_bf16_e4m3_sw    4096x4096   row        31.47        25.69    1.22     2682.5     3285.8        10.22        13.96    0.73
          dgelu_bf16_e4m3_sw    4096x8192  both        85.39        56.75    1.50     2382.4     3584.7        13.10        16.46    0.80
          dgelu_bf16_e4m3_sw    4096x8192   col        54.98        46.14    1.19     3070.5     3659.2        10.18        13.55    0.75
          dgelu_bf16_e4m3_sw    4096x8192   row        56.86        46.11    1.23     2969.2     3661.6        10.04        14.69    0.68
          dgelu_bf16_e4m3_sw    8192x8192  both       166.02       107.60    1.54     2450.6     3781.2        13.44        16.56    0.81
          dgelu_bf16_e4m3_sw    8192x8192   col       104.29        86.54    1.21     3237.4     3901.5        10.20        13.42    0.76
          dgelu_bf16_e4m3_sw    8192x8192   row       105.63        86.63    1.22     3196.3     3897.7        10.33        14.30    0.72
             dgelu_bf16_e4m3   4096x14336  both       142.52        94.93    1.50     2497.8     3750.0        13.46        17.52    0.77
             dgelu_bf16_e4m3   4096x14336   col        90.69        76.78    1.18     3257.7     3847.7        10.51        14.02    0.75
             dgelu_bf16_e4m3   4096x14336   row        92.58        76.40    1.21     3191.2     3866.9        10.72        14.03    0.76
             dgelu_bf16_e4m3    4096x4096  both        45.08        31.17    1.45     2256.3     3263.0        13.36        16.63    0.80
             dgelu_bf16_e4m3    4096x4096   col        30.26        25.79    1.17     2789.8     3273.5        10.14        13.61    0.75
             dgelu_bf16_e4m3    4096x4096   row        31.02        25.42    1.22     2721.4     3321.1        10.52        13.89    0.76
             dgelu_bf16_e4m3    4096x8192  both        83.77        56.75    1.48     2428.4     3584.6        12.93        17.22    0.75
             dgelu_bf16_e4m3    4096x8192   col        54.39        46.25    1.18     3104.0     3650.5        10.18        13.78    0.74
             dgelu_bf16_e4m3    4096x8192   row        56.26        45.84    1.23     3000.8     3682.4        10.22        13.88    0.74
             dgelu_bf16_e4m3    8192x8192  both       162.62       107.35    1.51     2501.8     3789.8        13.02        17.42    0.75
             dgelu_bf16_e4m3    8192x8192   col       103.14        86.69    1.19     3273.6     3894.9        10.33        13.56    0.76
             dgelu_bf16_e4m3    8192x8192   row       104.59        86.24    1.21     3228.3     3915.2        10.48        13.50    0.78
           gelu_bf16_e4m3_sw   4096x14336  both       102.85        75.15    1.37     2319.4     3174.2        13.37        16.20    0.83
           gelu_bf16_e4m3_sw   4096x14336   col        66.47        58.58    1.13     2677.9     3038.7        10.22        12.98    0.79
           gelu_bf16_e4m3_sw   4096x14336   row        70.06        58.84    1.19     2540.6     3025.0        10.00        14.69    0.68
           gelu_bf16_e4m3_sw    4096x4096  both        30.98        24.85    1.25     2199.9     2743.0        13.07        15.30    0.85
           gelu_bf16_e4m3_sw    4096x4096   col        22.69        20.13    1.13     2241.4     2526.0         9.89        13.09    0.76
           gelu_bf16_e4m3_sw    4096x4096   row        23.10        20.17    1.15     2201.9     2521.3        10.20        14.37    0.71
           gelu_bf16_e4m3_sw    4096x8192  both        60.52        45.05    1.34     2252.4     3025.7        12.48        15.62    0.80
           gelu_bf16_e4m3_sw    4096x8192   col        40.29        35.49    1.14     2524.4     2866.1         9.85        13.00    0.76
           gelu_bf16_e4m3_sw    4096x8192   row        42.03        35.59    1.18     2420.1     2857.6        10.14        14.00    0.72
           gelu_bf16_e4m3_sw    8192x8192  both       117.61        84.98    1.38     2318.1     3208.1        13.30        15.88    0.84
           gelu_bf16_e4m3_sw    8192x8192   col        75.08        66.11    1.14     2709.4     3076.9         9.98        13.07    0.76
           gelu_bf16_e4m3_sw    8192x8192   row        78.25        66.35    1.18     2599.7     3065.8         9.96        13.84    0.72
              gelu_bf16_e4m3   4096x14336  both       101.10        76.18    1.33     2359.5     3131.4        13.31        16.64    0.80
              gelu_bf16_e4m3   4096x14336   col        65.20        58.74    1.11     2730.1     3030.0         9.77        13.46    0.73
              gelu_bf16_e4m3   4096x14336   row        68.84        58.89    1.17     2585.8     3022.3        10.18        13.01    0.78
              gelu_bf16_e4m3    4096x4096  both        30.60        25.22    1.21     2227.1     2702.2        12.81        15.29    0.84
              gelu_bf16_e4m3    4096x4096   col        22.29        20.20    1.10     2281.1     2517.2         9.66        12.91    0.75
              gelu_bf16_e4m3    4096x4096   row        22.91        19.69    1.16     2219.6     2583.3        10.22        13.91    0.73
              gelu_bf16_e4m3    4096x8192  both        59.19        45.71    1.29     2303.1     2981.8        12.07        15.37    0.79
              gelu_bf16_e4m3    4096x8192   col        39.62        35.56    1.11     2567.2     2859.9         9.76        13.40    0.73
              gelu_bf16_e4m3    4096x8192   row        41.53        35.37    1.17     2449.0     2875.6         9.78        13.79    0.71
              gelu_bf16_e4m3    8192x8192  both       115.28        86.14    1.34     2365.0     3165.0        12.92        15.31    0.84
              gelu_bf16_e4m3    8192x8192   col        73.23        66.20    1.11     2777.9     3072.9         9.86        13.08    0.75
              gelu_bf16_e4m3    8192x8192   row        78.11        66.50    1.17     2604.4     3058.9         9.96        13.50    0.74
          plain_bf16_e4m3_sw   4096x14336  both        42.08        39.30    1.07     5668.9     6070.0        15.96        16.41    0.97
          plain_bf16_e4m3_sw   4096x14336   col        31.21        30.01    1.04     5702.4     5931.2        13.66        14.51    0.94
          plain_bf16_e4m3_sw   4096x14336   row        30.25        29.86    1.01     5883.5     5961.5        13.32        13.88    0.96
          plain_bf16_e4m3_sw    4096x4096  both        14.88        14.60    1.02     4579.4     4668.7        16.81        15.65    1.07
          plain_bf16_e4m3_sw    4096x4096   col        11.74        11.34    1.03     4333.4     4484.3        13.90        13.26    1.05
          plain_bf16_e4m3_sw    4096x4096   row        11.14        11.14    1.00     4565.2     4565.1        13.95        13.86    1.01
          plain_bf16_e4m3_sw    4096x8192  both        25.59        24.35    1.05     5326.8     5597.4        16.56        15.41    1.07
          plain_bf16_e4m3_sw    4096x8192   col        19.76        18.78    1.05     5146.3     5416.4        13.47        14.17    0.95
          plain_bf16_e4m3_sw    4096x8192   row        19.18        18.57    1.03     5303.1     5475.8        13.30        13.91    0.96
          plain_bf16_e4m3_sw    8192x8192  both        47.63        44.45    1.07     5724.2     6132.9        15.76        15.56    1.01
          plain_bf16_e4m3_sw    8192x8192   col        35.16        33.22    1.06     5786.3     6123.5        13.29        13.41    0.99
          plain_bf16_e4m3_sw    8192x8192   row        33.97        33.50    1.01     5987.9     6071.6        14.33        13.38    1.07
             plain_bf16_e4m3   4096x14336  both        41.91        42.19    0.99     5691.5     5654.6        16.54        16.84    0.98
             plain_bf16_e4m3   4096x14336   col        30.83        29.16    1.06     5773.2     6104.0        12.77        13.39    0.95
             plain_bf16_e4m3   4096x14336   row        28.29        28.03    1.01     6292.4     6351.0        11.91        13.92    0.86
             plain_bf16_e4m3    4096x4096  both        16.46        15.72    1.05     4140.2     4335.2        16.70        16.17    1.03
             plain_bf16_e4m3    4096x4096   col        11.59        11.23    1.03     4389.6     4528.9        13.10        13.98    0.94
             plain_bf16_e4m3    4096x4096   row        10.05        10.12    0.99     5059.4     5023.9        12.27        13.21    0.93
             plain_bf16_e4m3    4096x8192  both        26.72        25.95    1.03     5102.0     5253.9        15.80        15.45    1.02
             plain_bf16_e4m3    4096x8192   col        19.20        18.13    1.06     5298.5     5609.1        13.40        14.04    0.96
             plain_bf16_e4m3    4096x8192   row        17.44        16.90    1.03     5831.2     6016.8        11.87        12.82    0.93
             plain_bf16_e4m3    8192x8192  both        46.70        46.56    1.00     5837.4     5854.9        16.19        16.35    0.99
             plain_bf16_e4m3    8192x8192   col        34.80        32.76    1.06     5844.9     6209.4        12.66        13.93    0.91
             plain_bf16_e4m3    8192x8192   row        31.84        31.33    1.02     6389.5     6493.7        12.02        13.37    0.90

@kainzhong
kainzhong marked this pull request as ready for review July 8, 2026 23:25
@greptile-apps

greptile-apps Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds an experimental, opt-in CuTeDSL (CUTLASS Python DSL) backend for MXFP8 quantization, bridged into the C++ dispatcher via Apache TVM-FFI. When NVTE_ENABLE_CUTEDSL_QUANT_BACKEND=1 is set, JIT-compiled CuTeDSL kernels replace the CUDA C++ path; any miss (unsupported config, non-32-aligned shape, or compilation failure) transparently falls back.

  • New CuTeDSL kernel (quantize_mxfp8.py, ~2500 lines): ports the MXFP8 quantize CUDA kernel to CuTeDSL, covering rowwise/colwise/bidimensional scaling, fused activations (GeLU, ReLU, SiLU, QGeLU, SReLU), dbias, dact, and noop support, with a matching tile layout for bit-exact parity with the CUDA path.
  • C++ dispatch shim (tvm_ffi_bridge.h, quantize_mxfp8_cutedsl.cuh, quantize.cuh): TVMFFICentral singleton manages library loading and env-var gating; TVMFFIConfigCache provides per-config caching with a shared mutex; the dispatch shim tries CuTeDSL first and falls back to the existing mxfp8::quantize CUDA kernel on false.
  • Breaking dependency changes: apache-tvm-ffi and nvidia-cutlass-dsl are promoted to mandatory install_requires / build-system.requires, and CMake hard-fails without apache-tvm-ffi at build time — all without an opt-out flag — making them unconditional requirements for every TE user regardless of CuTeDSL usage.

Confidence Score: 3/5

The core fallback to existing CUDA kernels is safe, but the new CuTeDSL dispatch path has multiple behavioral issues — including unconditional reduce_dbias after a nooped kernel and swizzled-scale zeroing logic — that have been flagged across several review rounds without confirmed fixes in the current diff. The mandatory promotion of apache-tvm-ffi and nvidia-cutlass-dsl as hard install requirements is a significant breaking change for all TE users.

Several issues flagged in prior rounds appear unaddressed in the current diff: the noop+dbias divergence from the CUDA path, the double-compilation race under concurrent first calls, and the no-opt-out mandatory dependency on tvm-ffi at both build and install time. The workspace-size query committing to a layout before confirming compilability is a new fragility. The CUDA fallback path itself is unchanged and sound, so production workloads not opting into the env var are unaffected.

Files Needing Attention: quantize_mxfp8_cutedsl.cuh (noop+dbias semantics, workspace-size query ordering), tvm_ffi_bridge.h (concurrent compilation, permanent failure caching), setup.py and pyproject.toml (mandatory dependency promotion), CMakeLists.txt (no opt-out build flag)

Important Files Changed

Filename Overview
transformer_engine/common/tvm_ffi_bridge.h New header bridging TE tensors into TVM-FFI DLTensors; implements TVMFFICentral singleton, TVMFFIConfigCache with shared_mutex, and TypeTraits specialization for DLTensorWrapper. Cache stores nullopt permanently on JIT failure (no retry), and double-compilation under concurrent first calls for the same config is possible (flagged in prior review).
transformer_engine/common/cast/mxfp8/quantize_mxfp8_cutedsl.cuh New C++ dispatch shim routing MXFP8 quantize calls to CuTeDSL kernels via TVM-FFI. Several issues flagged across reviews: workspace-size query answers before verifying compilability; reduce_dbias runs unconditionally even when the kernel was nooped; swizzled-scale padding zeroing logic previously flagged.
transformer_engine/common/CuTeDSL/cast/mxfp8/quantize_mxfp8.py 2484-line CuTeDSL port of the MXFP8 CUDA kernel. device_compute_capability() always queries device 0 (multi-GPU issue). Both compile and register_global_func are wrapped in the same try/except. The workspace layout matches the CUDA path.
transformer_engine/common/init.py Adds opt-in CuTeDSL setup: loads libtvm_ffi.so and registers backends only when NVTE_ENABLE_CUTEDSL_QUANT_BACKEND!=0, before loading the core library. Correctly guarded by env var.
transformer_engine/common/CMakeLists.txt Adds unconditional tvm_ffi include-path detection at build time with FATAL_ERROR if absent — no CMake option to skip it (flagged in prior review).
pyproject.toml Adds apache-tvm-ffi>=0.1.12 as a mandatory build-system requirement for all TE builds regardless of CuTeDSL usage (flagged in prior review).
setup.py Promotes apache-tvm-ffi and nvidia-cutlass-dsl to mandatory install_requires for every TE user regardless of CuTeDSL usage (flagged in prior review).
tests/pytorch/mxfp8/test_mxfp8_cutedsl_backend.py New cross-backend bit-exactness test comparing CuTeDSL vs CUDA. Correctly guarded by cutedsl_enabled env-var check and recipe_available. get_cfg_key hardcodes with_amax=False which may not match the actual C++ key (flagged in prior review).
transformer_engine/common/CuTeDSL/utils.py Utility helpers for CuTeDSL. device_compute_capability always queries device 0 (flagged in prior review). Operator-precedence bug in the empty-string guard also previously flagged.
transformer_engine/common/cast/dispatch/quantize.cuh Adds CuTeDSL try-first dispatch for MXFP8 quantize in both forward and backward paths; falls back to CUDA on false return.

Sequence Diagram

sequenceDiagram
    participant Py as Python (import TE)
    participant Init as common/__init__.py
    participant Cpp as C++ quantize()
    participant Central as TVMFFICentral
    participant Cache as TVMFFIConfigCache
    participant PyKernel as Python get_mxfp8_quantization_function
    participant CUDA as mxfp8::quantize (CUDA)

    Py->>Init: import transformer_engine
    Init->>Init: _load_tvm_ffi_library() [if env var set]
    Init->>Init: _register_cutedsl_backends()

    Py->>Cpp: nvte_quantize(input, output)
    Cpp->>Central: getInstance() [lazy init: dlopen libtvm_ffi.so]
    Cpp->>Cache: get_or_load(MXFP8QuantConfig)
    Cache->>Cache: check map_ (cache miss)
    Cache->>Central: load_tvm_ffi_function(cfg)
    Central->>PyKernel: entrypoint(fn_name, dtype, ...) via TVM-FFI
    PyKernel->>PyKernel: compile_cutedsl_function_from_cfg(cfg)
    PyKernel->>PyKernel: tvm_ffi.register_global_func(fn_name, compiled)
    PyKernel-->>Central: True
    Central->>Central: GetGlobal(key)
    Central-->>Cache: optional Function
    Cache->>Cache: map_.emplace(id, fn)
    Cache-->>Cpp: optional Function

    alt CuTeDSL kernel found
        Cpp->>Cpp: invoke mxfp8_quant_func
        Cpp->>Cpp: reduce_dbias (if with_dbias)
    else CuTeDSL not available
        Cpp->>CUDA: mxfp8::quantize(...)
    end
Loading

Reviews (29): Last reviewed commit: "fix" | Re-trigger Greptile

Comment thread build_tools/pytorch.py
Comment thread transformer_engine/common/CuTeDSL/cast/mxfp8/quantize_mxfp8.py Outdated
Comment thread build_tools/pytorch.py Outdated
Comment thread build_tools/pytorch.py Outdated
Comment thread setup.py Outdated
"importlib-metadata>=1.0",
"packaging",
"apache-tvm-ffi>=0.1.12",
"nvidia-cutlass-dsl>=4.2.0",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to other things (like cudnn frontend CuTeDSL kernels), I'm pretty sure we need a later version
of that package (4.4.2 I think?). Adding @ksivaman to comment.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll change this to 4.4.2

Comment on lines +21 to +22
GTEST_SKIPs the mismatched half), non-32-divisible shapes are omitted (the
dispatcher can never route them to CuTeDSL), and a missing kernel registration

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are the non-32-divisible shapes omitted? Is this a limitation of the cutedsl implementation?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because my CuTeDSL kernels are compiled with

sym_M = cute.sym_int32(divisibility=MXFP8_BLOCK_SCALING_SIZE)
sym_N = cute.sym_int32(divisibility=MXFP8_BLOCK_SCALING_SIZE)

So it assumes 32-divisible shape. Maybe non-32-divisible can be supported as well. I'll run some benchmarks and see if it hurts performance but I think normally people wouldn't use these weird shapes?

#
# See LICENSE for license information.

"""Cross-backend bit-exactness tests for the CuTeDSL MXFP8 quantize kernels.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense in this initial stage, but I would explicitly mark this file as temporary, since
ultimately we will want to standardize on this backend.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could port the CUDA C++ tests to python and make this a standalone test instead of comparing with CUDA kernel's output, but then I thought since we already validated CUDA implementation it would be easier to just make that the reference and compare the result instead.
If we want to standardize on this then should this be python MXFP8 reference implementation on its own?

Comment thread transformer_engine/common/CuTeDSL/__init__.py Outdated
Comment thread transformer_engine/common/CuTeDSL/activations.py Outdated
Comment thread transformer_engine/common/CuTeDSL/activations.py Outdated
Comment thread transformer_engine/common/CuTeDSL/activations.py Outdated
Comment on lines +44 to +70
std::string to_key() const {
std::string key;
key.reserve(56);
key.append("cutedsl_mxfp8_")
.append(te_dtype_to_str(dtype))
.append("_")
.append(te_dtype_to_str(fp8_dtype))
.append("_")
.append(rowwise ? "1" : "0")
.append("_")
.append(colwise ? "1" : "0")
.append("_")
.append(swizzled ? "1" : "0")
.append("_")
.append(with_amax ? "1" : "0")
.append("_")
.append(with_dbias ? "1" : "0")
.append("_")
.append(with_dact ? "1" : "0")
.append("_")
.append(with_act ? "1" : "0")
.append("_")
.append(with_noop ? "1" : "0")
.append("_")
.append(activation_to_str(activation));
return key;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of random, but this function is quite slow. You could do the same much faster with raw char*
manipulation.

@kainzhong kainzhong Jul 9, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Emmmm but I reserved 56 chars before I do append. I don't know if char* will be faster than this since they both don't require resizing the string?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You still need to create those additional 1-letter strings in this version. At the very least you could make a "1_" and "0_" strings upfront and use those instead (also, you don't even need the underscore there between those 1s and 0s).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah OK I just made some changes. Now every quantization config owns their cache and the cache key is uint32 now. This to_key is now only used to build the function name used when registering the function to TVM-FFI registry and it happens only once when you request a not yet ready kernel. Later we will fetch it from C++ cache with uint32 cache key which is more efficient.

Comment thread transformer_engine/common/cast/mxfp8/quantize_mxfp8_cutedsl.cuh
Comment thread transformer_engine/common/cast/mxfp8/quantize_mxfp8_cutedsl.cuh
Comment on lines +113 to +121
if(NOT TVM_FFI_CMAKE_QUERY EQUAL 0)
message(FATAL_ERROR
"Could not import the tvm_ffi Python package (with '${Python_EXECUTABLE}'), "
"which Transformer Engine requires to build the CuTeDSL quantize backend "
"bridge (common/tvm_ffi_bridge.h). Install it into this Python environment: "
"`pip install apache-tvm-ffi`.")
endif()
find_package(tvm_ffi CONFIG REQUIRED PATHS "${TVM_FFI_CMAKE_DIR}")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 No opt-out CMake option for tvm_ffi dependency

The tvm_ffi detection is unconditional: if the package is absent the build hard-fails with FATAL_ERROR, with no NVTE_ENABLE_CUTEDSL CMake option to disable it. Every other optional feature in this file that has a build-time cost (NVTE_ENABLE_NVSHMEM, NVTE_WITH_CUBLASMP, etc.) is guarded by an option() flag. Without an analogous guard here, any environment where apache-tvm-ffi is not installed — CI images, embedded build systems, custom wheels — cannot build Transformer Engine at all, even if the CuTeDSL backend is never used at runtime.

@kainzhong
kainzhong force-pushed the cutedsl_mxfp8_common branch from 948fab5 to 2930b1b Compare July 10, 2026 00:34
Comment thread transformer_engine/common/CuTeDSL/utils_fp8.py
Comment thread transformer_engine/common/CuTeDSL/utils.py Outdated
Comment thread transformer_engine/common/__init__.py Outdated
Comment thread transformer_engine/common/CuTeDSL/utils.py
Comment thread transformer_engine/common/cast/mxfp8/quantize_mxfp8_cutedsl.cuh Outdated
Comment thread tests/pytorch/mxfp8/test_mxfp8_cutedsl_backend.py Outdated
Comment on lines +1 to +10
# Copyright (c) 2022-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# See LICENSE for license information.

"""Cross-backend bit-exactness tests for the CuTeDSL MXFP8 quantize kernels."""

import ctypes
import os
from typing import Callable, NamedTuple, Optional

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Unconditional top-level import tvm_ffi raises ImportError for users without the package

The test file imports tvm_ffi at module level before the pytestmark skip guard is evaluated. Pytest collects all test modules regardless of environment; users without apache-tvm-ffi installed will see a collection error instead of a clean skip. The import should be moved inside the test body or placed under a try/except ImportError guard that sets tvm_ffi_available = False, similar to how the test already conditionally sets cutedsl_enabled.

@kainzhong
kainzhong force-pushed the cutedsl_mxfp8_common branch from 6e55eef to c47fc5c Compare July 27, 2026 20:09
kainzhong and others added 4 commits July 27, 2026 20:09
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
for more information, see https://pre-commit.ci

Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
kainzhong and others added 20 commits July 27, 2026 20:10
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
for more information, see https://pre-commit.ci

Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
for more information, see https://pre-commit.ci

Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Perform noop tensor check on device

Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
@kainzhong
kainzhong force-pushed the cutedsl_mxfp8_common branch from c47fc5c to 4815598 Compare July 27, 2026 20:10
kainzhong and others added 7 commits July 28, 2026 00:57
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
…ot dispatched

Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Comment on lines +2477 to +2485
except Exception as e: # pylint: disable=broad-exception-caught
logger.error(
"CuTeDSL MXFP8 kernel compilation failed, falling back to the CUDA C++ kernel: %s",
e,
)
return False
tvm_ffi.register_global_func(fn_name, compiled, override=True)

return True

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 register_global_func uncaught exception crashes quantize instead of falling back

compile_cutedsl_function_from_cfg is correctly wrapped in a try/except Exception, but tvm_ffi.register_global_func(fn_name, compiled, override=True) is called outside that block. If it raises (e.g., a TVM-FFI internal error, an invalid function handle, or a name-space conflict), the Python exception propagates through TVM-FFI's (*entrypoint)(...) invocation in C++ (retrieve_func_from_python), which is not guarded there either. The exception travels up through load_tvm_ffi_functionget_or_loadget_kernelmxfp8_quantize_cutedsl and crashes the quantize operation instead of gracefully returning false to let the CUDA kernel handle the call. Moving the register_global_func call inside the existing try block (or wrapping it in its own) preserves the established fallback contract.

Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants