Skip to content

fix: inference norm missing threadsPerGroup==32 dispatch + ROCm 7.2.2 bf16 ABI - #8906

Open
umechand-amd wants to merge 2 commits into
deepspeedai:masterfrom
umechand-amd:fix/inference-norm-dispatch-and-rocm-bf16-abi
Open

umechand-amd wants to merge 2 commits into
deepspeedai:masterfrom
umechand-amd:fix/inference-norm-dispatch-and-rocm-bf16-abi

Conversation

@umechand-amd

Copy link
Copy Markdown
Collaborator

What

Two independent fixes to the v1 inference norm kernels.

1. Missing threadsPerGroup==32 dispatch (layer_norm.cu, rms_norm.cu)

launch_fused_ln, launch_fused_residual_ln, launch_fused_residual_ln_store_pre_ln_res, and launch_rms_norm all dispatch on threadsPerGroup with branches for {1, 2, 4, 8, 16} only. For float32 inputs with elems_per_row in [65, 128], T_per_load=4 gives threadsPerGroup=32, which falls through every branch — no kernel is launched and the output tensor holds uninitialized memory (silent numerical corruption).

Reproduced on MI350X (gfx950, ROCm 7.2.2): errors of 3–8 units for H=80–128 with dtype=float32.
Fix: add else if (threadsPerGroup == 32) to all four dispatch tables.

Real-world trigger: per-head Q/K RMSNorm in EXAONE 4/4.5 with head_size 64 or 128 (related to #8886).

2. ROCm 7.2.2 bf16 ABI build failure (conversion_utils.h)

conversion_utils.h includes cuda_bf16.h guarded only by BF16_AVAILABLE. Hipify translates this to hip_bf16.h in conversion_utils_hip.h. When op_builder compiles .cpp files with plain g++ and -DBF16_AVAILABLE -D__HIP_PLATFORM_AMD__, it pulls in amd_hip_bf16.h, which on ROCm 7.2.2 requires Clang-only builtins (__builtin_elementwise_fma, __builtin_elementwise_ceil, etc.) and a __bf16 vector ABI not available under g++, causing the entire inference_core_ops extension to fail to build.

Fix: add && !defined(__HIP_PLATFORM_AMD__) to match the identical pattern already in ds_kernel_utils.h (which has a comment explaining exactly this problem). Hipify will propagate the guard correctly to the generated _hip.h file.

Test

Repro script for fix 1: verified H=80–128 (float32) produce zero error after the fix on gfx950.

🤖 Generated with Claude Code

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-25T21:49:21.235847Z c83fe56 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c83fe5684a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

LAUNCH_FUSED_LN(1, 8, maxThreads);
} else if (threadsPerGroup == 16) {
LAUNCH_FUSED_LN(1, 16, maxThreads);
} else if (threadsPerGroup == 32) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Mirror the 32-thread dispatch into inference v2

For supported float32 widths such as 80 or 128 through inference v2, InferenceCoreBuilder compiles the separate deepspeed/inference/v2/kernels/core_ops/cuda_layer_norm/layer_norm_cuda.cu and cuda_rms_norm/rms_norm_cuda.cu copies, whose corresponding four subblock dispatches still stop at 16. Those APIs therefore still take the 32-thread case without launching a kernel and return untouched output; mirror this branch into the v2 copies rather than fixing only InferenceBuilder.

AGENTS.md reference: AGENTS.md:L19-L19

Useful? React with 👍 / 👎.

Comment thread csrc/includes/conversion_utils.h Outdated
#include <stdint.h>

#ifdef BF16_AVAILABLE
#if defined(BF16_AVAILABLE) && !defined(__HIP_PLATFORM_AMD__)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep bfloat definitions available to HIP device compilation

On a ROCm build of an op that leaves enable_bf16 enabled, such as QuantizerBuilder or FPQuantizerBuilder, hipcc itself defines __HIP_PLATFORM_AMD__, so this condition removes the bfloat header from device translation units too. conversion_utils.h nevertheless compiles its BF16_AVAILABLE specializations using __nv_bfloat16, __nv_bfloat162, and their intrinsics; ds_kernel_utils.h only forward-declares the scalar type, and these builders include conversion/reduction before any bfloat definition, so they now fail to compile. Distinguish host-only g++ from hipcc or provide the definition before this header.

AGENTS.md reference: AGENTS.md:L19-L19

Useful? React with 👍 / 👎.

Comment thread csrc/includes/conversion_utils.h Outdated
#include <stdint.h>

#ifdef BF16_AVAILABLE
#if defined(BF16_AVAILABLE) && !defined(__HIP_PLATFORM_AMD__)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Guard the headers that InferenceCore actually includes

On the stated ROCm 7.2.2 InferenceCoreBuilder build, this edit is not on the include path: op_builder/inference_core_ops.py selects deepspeed/inference/v2/kernels/includes, where both ds_kernel_utils.h and conversion_utils.h still include cuda_bf16.h whenever BF16_AVAILABLE is set. The host .cpp files therefore still expose g++ to amd_hip_bf16.h and the extension continues to fail; apply the guard and forward declaration to the v2 headers actually used by this builder.

AGENTS.md reference: AGENTS.md:L19-L19

Useful? React with 👍 / 👎.

… bf16 ABI

Three dispatch tables in layer_norm.cu and one in rms_norm.cu handle
threadsPerGroup in {1,2,4,8,16} only. For float32 with elems_per_row
in [65,128], T_per_load=4 gives threadsPerGroup=32, which falls through
every branch -- no kernel launches and output holds uninitialized memory.

Also guards cuda_bf16.h in conversion_utils.h with !defined(__HIP_PLATFORM_AMD__)
to match the existing pattern in ds_kernel_utils.h. Without the guard,
plain c++ compiled with -DBF16_AVAILABLE -D__HIP_PLATFORM_AMD__ pulls in
amd_hip_bf16.h which requires Clang-only builtins (__builtin_elementwise_fma
etc.) unavailable under g++, breaking inference_core_ops on ROCm 7.2.2.

Signed-off-by: Umesh Chand <Umesh.Chand@amd.com>
…6 guard, add fp32 small-hidden tests

Signed-off-by: Umesh Chand <Umesh.Chand@amd.com>
@umechand-amd
umechand-amd force-pushed the fix/inference-norm-dispatch-and-rocm-bf16-abi branch from f27105e to ac23d4c Compare October 28, 2026 23:47

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.

1 participant