Skip to content

[Common] More CuTeDSL MXFP8 specialized kernels - #3642

Open
kainzhong wants to merge 37 commits into
NVIDIA:mainfrom
kainzhong:more_cutedsl_mxfp8_specialized
Open

kainzhong wants to merge 37 commits into
NVIDIA:mainfrom
kainzhong:more_cutedsl_mxfp8_specialized

Conversation

@kainzhong

@kainzhong kainzhong commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Description

Add specialized MXFP8 CuTeDSL quantization kernels ported from #3459
And also some refactoring of the existing kernel -- so quantize_mxfp8.py becomes

  • quantize_mxfp8_common.py: kernel config, signature, dispatching and registeration
  • quantize_mxfp8_g2s_general.py: the same general MXFP8 kernel that handles all cases
  • quantize_mxfp8_g2r_rowwise_1lane.py: the same old rowwise specialized kernel
  • quantize_mxfp8_g2s_bidim.py: the same old bidim specialized kernel

g2s and g2r mean the kernel uses SMEM / RMEM to quantize

Note: CuTeDSL cannot exactly mirror CUDA's implementation due to a bug in cutlass: NVIDIA/cutlass#3726

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

  • Split the original MXFP8 CuTeDSL file into 3 different files (generic, bidim specialized, rowwise specialized)
  • Added new kernels

Difference with the CUDA path:

  • G2R bidim kernel also works with swizzled scale
  • G2R bidim kernel also handles colwise only quantization
  • G2R kernels also support ACT / DACT fusion
  • Due to CuTeDSL's G2R activation fusion uses different paths than CUDA, sometimes they disagree with +0 and -0. I think both should be legal so I relaxed bit-exact tests to tolerate +0 and -0

Benchmark result (full sweep on the tip of this branch including things that aren't changed by this PR):

https://claude.ai/artifact/GsCNMy9S4YTxHnR7W3b1Vo?sk=DtZFlcQxJpBxCOlmq-W8_A

Or download it as a static HTML:
Quantization Benchmark .html

To examine which kernel is dispatched, expand "Data table" and you can see kernel names

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 and others added 12 commits October 7, 2026 07:22
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>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
@kainzhong
kainzhong force-pushed the more_cutedsl_mxfp8_specialized branch from 4b9ef6b to ef9877d Compare October 12, 2026 18:45
pre-commit-ci Bot and others added 5 commits October 12, 2026 18:47
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>
@kainzhong
kainzhong marked this pull request as ready for review October 12, 2026 20:24
@greptile-apps

greptile-apps Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no new actionable issue was found.

Summary

Adds register-based BF16 MXFP8 kernels and splits the existing kernels into separate files.

  • Rowwise MXFP8 casts can use register-based kernels for more input layouts.
  • Bidimensional MXFP8 casts can quantize from a register-loaded tile.
  • MXFP8 calls now select specialized kernels when their inputs fit.

Previous-thread context:

  • The added BF16 cases address the missing launch-shape coverage.
  • kainzhong accepted the lack of exact kernel-selection assertions because these tests check correctness, not performance. Greptile withdrew that concern.
  • kainzhong explicitly accepts positive-zero versus negative-zero differences in the PR description. Both backend tests now allow that difference.
  • The coverage and signed-zero threads were manually resolved without explanatory replies.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[MXFP8 quantization call] --> B[Check configuration and shape]
  B --> C[Rowwise two-lane G2R]
  B --> D[Bidimensional G2R]
  B --> E[Rowwise one-lane G2R]
  B --> F[Bidimensional G2S]
  B --> G[General G2S fallback]
Loading

Reviews (18) · Last reviewed commit: "Merge branch 'main' into more_cutedsl_mx..." · Reviewed by Greptile

Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
@kainzhong
kainzhong force-pushed the more_cutedsl_mxfp8_specialized branch from 113f73a to cae94f5 Compare October 12, 2026 21:05
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
@kainzhong
kainzhong force-pushed the more_cutedsl_mxfp8_specialized branch from 0a9824e to f67b1e5 Compare October 12, 2026 21:11
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>
@kainzhong
kainzhong force-pushed the more_cutedsl_mxfp8_specialized branch from ba1f62d to 5c3465a Compare October 15, 2026 20:29
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>
@kainzhong
kainzhong force-pushed the more_cutedsl_mxfp8_specialized branch from 3a80e08 to dba8dbf Compare October 15, 2026 23:58
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
@kainzhong
kainzhong force-pushed the more_cutedsl_mxfp8_specialized branch from ff45b46 to 287505f Compare October 17, 2026 02:13
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Signed-off-by: Kaining Zhong <kainingz@nvidia.com>
Comment thread docs/envvars.rst Resolved
is_writer_thread = tidx % THREADS_X_PER_MX_BLOCK == 0
for row_idx in cutlass.range_constexpr(ELEMENTS_Y_PER_THREAD):
rX_row_i32 = cute.recast_tensor(rX[None, row_idx], Int32)
reciprocal = bf16_mx_scale_reciprocal(extract_mx_block_amax(rX_row_i32), MAX_EXPONENT)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

for the case of WITH_ACT/WITH_DACT, the scale computed by this CuteDSL function is different from how thee CUDA kernel fused case compute it. CUDA version ignores NaN and the scale = e8m0(fmaxf(amax * max_norm_rcp, 0)), so it scale will be 0 when there is NaN. However this function in cuteDSL will return 0xFF for the scale here.
I know that the cast-only version in CUDA also uses the same scale calculation, which returns 0xFF. And numerically this should not matter, but since you have the byte-for-byte test between CuteDSL and CUDA, thought I might call it out for the fused activation case.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I’d keep the new behavior and define all-NaN blocks to produce a NaN scale (0xFF), consistently with the cast-only path. The fused CUDA reduction currently loses the all-NaN condition by starting fmaxf from zero.
As we’re planning to transition to CuTeDSL kernels (and eventually retire the legacy CUDA implementations), we should probably prefer to standardize this behavior. And the remaining inconsistencies between backends can be fixed in a separate fix PR

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.

OK so... I'm just not gonna change anything?

@tdophung tdophung Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yeah you do not need to change anything then, per Oleg. I'll fix the inconsistencies in the CUDA sidee in the next PR. Keeping this thread open and not resolved so I remember it though

tdophung added a commit to tdophung/TransformerEngine that referenced this pull request Oct 28, 2026
…block scales

- SiLU is x * sigmoid(x), as util/math.h computes it; x / (1 + exp(-x))
  rounds differently, so FP32 SiLU differed from CUDA.
- The general kernel carries one dbias sum down the column across its stages,
  as the CUDA kernels do, instead of adding 32-row partial sums.
- With an activation fused, a block of only NaNs gets amax 0 and so scale 0,
  as in CUDA's generic kernel, in the register-resident, 2-lane rowwise and
  general kernels. Plain casts keep the NaN scale of CUDA's cast kernels.
- FP32 dbias+dGeLU takes the register-resident kernel, whose dbias matches
  CUDA (the general kernel's still differs in the last bit for FP32).

mxh2 parity against TE main (CUDA), tables off, 702 cases over BF16/FP16/FP32,
all modes, layouts and fills including special values: 678 match (PR NVIDIA#3642
alone: 464). The rest are FP32 dbias with rowwise-only output, where CUDA adds
row pairs (r, r + 32) before summing.

Signed-off-by: Teddy Do <tdophung@nvidia.com>
Oleg-Goncharov
Oleg-Goncharov previously approved these changes Oct 28, 2026

@Oleg-Goncharov Oleg-Goncharov left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

Signed-off-by: Kaining Zhong <kainingz@nvidia.com>

@tdophung tdophung left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approve pending CI (and #3743 + #3737 )

This branch has not been deployed

No deployments
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