Skip to content

[CI] Skip amdgpu repo during manylinux image dnf install - #1014

Merged
coderfeli merged 1 commit into
mainfrom
fix/ci-manylinux-dnf-amdgpu-timeout
Aug 17, 2026
Merged

coderfeli merged 1 commit into
mainfrom
fix/ci-manylinux-dnf-amdgpu-timeout

Conversation

@coderfeli

Copy link
Copy Markdown
Collaborator

Summary

  • Fix scheduled FlyDSL CI build failure when the prebuilt manylinux image is missing from GHCR.
  • dnf install in .github/workflows/Dockerfile.manylinux_2_28 now uses --disablerepo=amdgpu so CI does not depend on flaky repo.radeon.com metadata fetches.
  • ROCm is already present in rocm/dev-almalinux-8:*-complete; the packages installed here (gcc, git, ninja-build, etc.) come from AlmaLinux repos.

Root cause (verified from run 31988204507)

  1. docker pull ghcr.io/rocm/flydsl-manylinux_2_28:rocm7.2-cp310-cp314 failed: image not found
  2. CI fell back to local docker build
  3. Build failed at Dockerfile step 5/7 because dnf install timed out refreshing the amdgpu repo metadata from repo.radeon.com

Test plan

  • CI build / build job passes on this PR (should rebuild the manylinux image and get past the dnf install step)
  • Built image still contains expected build tools (gcc, git, ninja-build, cmake via pip)

Made with Cursor

When the prebuilt GHCR image is missing, CI builds the manylinux image
locally and dnf fails on flaky repo.radeon.com metadata fetches. The
build deps come from AlmaLinux repos and ROCm is already in the base image.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderfeli
coderfeli merged commit 96af91b into main Aug 17, 2026
15 checks passed
@coderfeli
coderfeli deleted the fix/ci-manylinux-dnf-amdgpu-timeout branch August 17, 2026 06:15
JohnQin-llm added a commit that referenced this pull request Aug 19, 2026
#919 made `_init_dualwave_thread_mapping` re-derive (head, q_block) from the
linear workgroup id with the head as the slow axis, so a head's blocks stay on
one XCD and its K/V stays resident in that XCD's L2 across the concurrent
wavefronts. It applied to every qualifying dualwave dense shape, bf16 included,
gated only on `not SPLITK and not CAUSAL and NUM_HEADS_Q % NUM_XCD_GFX950 == 0`.

#950 put a trait in front of that condition:

    -    if const_expr(not traits.SPLITK and not traits.CAUSAL and ...):
    +    if const_expr(traits.XCD_SWIZZLE and not traits.SPLITK and ...):

`XCD_SWIZZLE` defaults to False and only the fp8 builder passes it. That PR
measured and described fp8 only, and never touched the bf16 builder -- the
string `xcd` does not appear in flash_attn_gfx950.py at all -- so the remap
silently stopped applying to bf16. No test covered the mapping, so nothing
caught it.

Bisecting upstream on MI355X, B=2 H=32 D=128 bf16 non-causal, TFLOP/s at
S = 61,380 / 180,180 / 239,580, aiter measured in the same process as control:

    cf1db2f  7/31  #919     1273.2  1287.0  1287.4
    772f070  8/6   #974     1253.7  1074.5  1053.4
    494b2cb  8/9   #945     1251.9  1073.3  1052.6
    f6d0a41  8/14  #991     1247.2  1076.2  1061.2
    47009a3  8/14  #1004    1248.2  1076.2  1061.3
    daee90e  8/17  #930     1249.0  1076.4  1060.6
    96af91b  8/17  #1014    1247.2  1076.6  1064.5
    4521c8c  8/18  #960     1247.8  1074.8  1061.2
    aiter                   ~1250   ~1253   ~1252

One step, between 7/31 and 8/6, and #950 (8/3) is the only commit in that
window that touches the mapping. Everything after it is flat to within noise.

This plumbs `xcd_swizzle` through the bf16 builder and reuses the existing
dispatch condition (non-causal, `H % NUM_XCD_GFX950 == 0`, `num_q_blocks >=
MIN_Q_BLOCKS_XCD_SWIZZLE`). Split-K is excluded structurally: it takes the
`_build_splitk` branch above this dispatch site.

The remap is bijective, so output is bit-identical. Two tests assert that over
H=8/16/32/64 and cover the `H % 8 != 0` fallback both forced and auto -- the
guard #919 shipped without.

One loose end: the restored figure is still ~1.4% below the 7/31 measurement
(1268.8 against 1287.4 at S=239,580). The candidates are the
`MIN_Q_BLOCKS_XCD_SWIZZLE` threshold #950 introduced for fp8, which #919 did
not have, and the LLVM bump in #945.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
JohnQin-llm added a commit that referenced this pull request Aug 19, 2026
#919 made `_init_dualwave_thread_mapping` re-derive (head, q_block) from the
linear workgroup id with the head as the slow axis, so a head's blocks stay on
one XCD and its K/V stays resident in that XCD's L2 across the concurrent
wavefronts. It applied to every qualifying dualwave dense shape, bf16 included,
gated only on `not SPLITK and not CAUSAL and NUM_HEADS_Q % NUM_XCD_GFX950 == 0`.

#950 put a trait in front of that condition:

    -    if const_expr(not traits.SPLITK and not traits.CAUSAL and ...):
    +    if const_expr(traits.XCD_SWIZZLE and not traits.SPLITK and ...):

`XCD_SWIZZLE` defaults to False and only the fp8 builder passes it. That PR
measured and described fp8 only, and never touched the bf16 builder -- the
string `xcd` does not appear in flash_attn_gfx950.py at all -- so the remap
silently stopped applying to bf16. No test covered the mapping, so nothing
caught it.

Bisecting upstream on MI355X, B=2 H=32 D=128 bf16 non-causal, cache cold, TFLOP/s
at S = 61,380 / 180,180 / 239,580, aiter in the same process as control:

    cf1db2f  7/31  #919     1284.6  1288.2  1286.8
    772f070  8/6   #974     1256.7  1188.1  1184.3
    494b2cb  8/9   #945     1255.6  1187.9  1187.2
    f6d0a41  8/14  #991     1256.0  1182.8  1183.6
    47009a3  8/14  #1004    1260.5  1188.6  1183.4
    daee90e  8/17  #930     1254.1  1077.0  1060.9
    96af91b  8/17  #1014    1251.8  1074.9  1060.6
    4521c8c  8/18  #960     1249.3  1073.9  1059.0
    aiter                   ~1252   ~1255   ~1255

Two independent steps. The first, between 7/31 and 8/6 (-8.0%), is #950 and is
what this commit fixes. The second, between 47009a3 and daee90e (-10.4%), is
#930 dropping the fastmath flag when it moved these kernels onto fx.maxnumf,
which reaches the raw MLIR builder without passing through resolve_fastmath;
that is a separate fix, filed separately.

This plumbs `xcd_swizzle` through the bf16 builder and reuses the existing
dispatch condition (non-causal, `H % NUM_XCD_GFX950 == 0`, `num_q_blocks >=
MIN_Q_BLOCKS_XCD_SWIZZLE`). Split-K is excluded structurally: it takes the
`_build_splitk` branch above this dispatch site.

The remap is bijective, so output is bit-identical. Two tests assert that over
H=8/16/32/64 and cover the `H % 8 != 0` fallback both forced and auto -- the
guard #919 shipped without.

One loose end: the restored figure is 1268.3 against cf1db2f's 1286.8, a 1.4%
gap. That is #930's dropped fastmath, which costs 10.4% with the remap off but
only 1.4% with it on -- the two interact. Fixing #930 separately closes it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
JohnQin-llm added a commit that referenced this pull request Aug 20, 2026
#919 made `_init_dualwave_thread_mapping` re-derive (head, q_block) from the
linear workgroup id with the head as the slow axis, so a head's blocks stay on
one XCD and its K/V stays resident in that XCD's L2 across the concurrent
wavefronts. It applied to every qualifying dualwave dense shape, bf16 included,
gated only on `not SPLITK and not CAUSAL and NUM_HEADS_Q % NUM_XCD_GFX950 == 0`.

#950 put a trait in front of that condition:

    -    if const_expr(not traits.SPLITK and not traits.CAUSAL and ...):
    +    if const_expr(traits.XCD_SWIZZLE and not traits.SPLITK and ...):

`XCD_SWIZZLE` defaults to False and only the fp8 builder passes it. That PR
measured and described fp8 only, and never touched the bf16 builder -- the
string `xcd` does not appear in flash_attn_gfx950.py at all -- so the remap
silently stopped applying to bf16. No test covered the mapping, so nothing
caught it.

Bisecting upstream on MI355X, B=2 H=32 D=128 bf16 non-causal, cache cold, TFLOP/s
at S = 61,380 / 180,180 / 239,580, aiter in the same process as control:

    cf1db2f  7/31  #919     1284.6  1288.2  1286.8
    772f070  8/6   #974     1256.7  1188.1  1184.3
    494b2cb  8/9   #945     1255.6  1187.9  1187.2
    f6d0a41  8/14  #991     1256.0  1182.8  1183.6
    47009a3  8/14  #1004    1260.5  1188.6  1183.4
    daee90e  8/17  #930     1254.1  1077.0  1060.9
    96af91b  8/17  #1014    1251.8  1074.9  1060.6
    4521c8c  8/18  #960     1249.3  1073.9  1059.0
    aiter                   ~1252   ~1255   ~1255

Two independent steps. The first, between 7/31 and 8/6 (-8.0%), is #950 and is
what this commit fixes. The second, between 47009a3 and daee90e (-10.4%), is
#930 dropping the fastmath flag when it moved these kernels onto fx.maxnumf,
which reaches the raw MLIR builder without passing through resolve_fastmath;
that is a separate fix, filed separately.

This plumbs `xcd_swizzle` through the bf16 builder and reuses the existing
dispatch condition (non-causal, `H % NUM_XCD_GFX950 == 0`, `num_q_blocks >=
MIN_Q_BLOCKS_XCD_SWIZZLE`). Split-K is excluded structurally: it takes the
`_build_splitk` branch above this dispatch site.

The remap is bijective, so output is bit-identical. Two tests assert that over
H=8/16/32/64 and cover the `H % 8 != 0` fallback both forced and auto -- the
guard #919 shipped without.

One loose end: the restored figure is 1268.3 against cf1db2f's 1286.8, a 1.4%
gap. That is #930's dropped fastmath, which costs 10.4% with the remap off but
only 1.4% with it on -- the two interact. Fixing #930 separately closes it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
coderfeli pushed a commit that referenced this pull request Aug 20, 2026
#919 made `_init_dualwave_thread_mapping` re-derive (head, q_block) from the
linear workgroup id with the head as the slow axis, so a head's blocks stay on
one XCD and its K/V stays resident in that XCD's L2 across the concurrent
wavefronts. It applied to every qualifying dualwave dense shape, bf16 included,
gated only on `not SPLITK and not CAUSAL and NUM_HEADS_Q % NUM_XCD_GFX950 == 0`.

#950 put a trait in front of that condition:

    -    if const_expr(not traits.SPLITK and not traits.CAUSAL and ...):
    +    if const_expr(traits.XCD_SWIZZLE and not traits.SPLITK and ...):

`XCD_SWIZZLE` defaults to False and only the fp8 builder passes it. That PR
measured and described fp8 only, and never touched the bf16 builder -- the
string `xcd` does not appear in flash_attn_gfx950.py at all -- so the remap
silently stopped applying to bf16. No test covered the mapping, so nothing
caught it.

Bisecting upstream on MI355X, B=2 H=32 D=128 bf16 non-causal, cache cold, TFLOP/s
at S = 61,380 / 180,180 / 239,580, aiter in the same process as control:

    cf1db2f  7/31  #919     1284.6  1288.2  1286.8
    772f070  8/6   #974     1256.7  1188.1  1184.3
    494b2cb  8/9   #945     1255.6  1187.9  1187.2
    f6d0a41  8/14  #991     1256.0  1182.8  1183.6
    47009a3  8/14  #1004    1260.5  1188.6  1183.4
    daee90e  8/17  #930     1254.1  1077.0  1060.9
    96af91b  8/17  #1014    1251.8  1074.9  1060.6
    4521c8c  8/18  #960     1249.3  1073.9  1059.0
    aiter                   ~1252   ~1255   ~1255

Two independent steps. The first, between 7/31 and 8/6 (-8.0%), is #950 and is
what this commit fixes. The second, between 47009a3 and daee90e (-10.4%), is
#930 dropping the fastmath flag when it moved these kernels onto fx.maxnumf,
which reaches the raw MLIR builder without passing through resolve_fastmath;
that is a separate fix, filed separately.

This plumbs `xcd_swizzle` through the bf16 builder and reuses the existing
dispatch condition (non-causal, `H % NUM_XCD_GFX950 == 0`, `num_q_blocks >=
MIN_Q_BLOCKS_XCD_SWIZZLE`). Split-K is excluded structurally: it takes the
`_build_splitk` branch above this dispatch site.

The remap is bijective, so output is bit-identical. Two tests assert that over
H=8/16/32/64 and cover the `H % 8 != 0` fallback both forced and auto -- the
guard #919 shipped without.

One loose end: the restored figure is 1268.3 against cf1db2f's 1286.8, a 1.4%
gap. That is #930's dropped fastmath, which costs 10.4% with the remap off but
only 1.4% with it on -- the two interact. Fixing #930 separately closes it.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.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.

1 participant