Files
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

87 lines
3.1 KiB
Python

# Copyright Advanced Micro Devices, Inc., or its affiliates.
# SPDX-License-Identifier: MIT
"""Regression tests for cluster-barrier signal/wait pairing.
The cluster-scope barrier handshake is split into a ``signal`` half and a
``wait`` half so the cross-CU latency can hide behind intervening WMMAs. The
wait must nonetheless dominate every early-exit branch (``SkipToNLL``,
``SkipToNGLL``, ``SkipTailLoopL`` etc.) that follows the signal; otherwise a
taken branch leaves the barrier signalled but never waited, desyncing the
cluster handshake (FFM assertion / incorrect on hardware).
These tests exercise ``insertClusterBarrier`` directly with a mock writer so
they stay fast and hardware-free.
"""
from unittest.mock import MagicMock
from rocisa.code import Module
from rocisa.container import sgpr
from rocisa.instruction import SBarrier, SCBranchSCC1, SCmpEQU32
from Tensile.Components.Subtile.ClusterBarrier import insertClusterBarrier
def _mockWriter():
writer = MagicMock()
# ClusterBarrier requires the HasClusterBarrier asm capability.
writer.states.asmCaps.get.return_value = True
writer.labels.getUniqueNamePrefix.side_effect = lambda prefix: prefix + "_TEST"
return writer
def _kernel():
return {"ClusterBarrier": True}
def _isSignal(inst):
return isinstance(inst, SBarrier) and "cluster_barrier signal" in str(inst)
def _isClusterWait(inst):
return (isinstance(inst, SBarrier)
and "cluster_barrier wait" in str(inst)
and "workgroup" not in str(inst))
def _indices(items):
sig = next(i for i, x in enumerate(items) if _isSignal(x))
wait = next(i for i, x in enumerate(items) if _isClusterWait(x))
return sig, wait
def test_wait_dominates_early_exit_branch():
"""The cluster wait must sit after the signal but before the first exit."""
module = Module("section")
module.add(SCmpEQU32(sgpr("LoopCounterL"), 1, "LoopCounter LE 1?"))
module.add(SCBranchSCC1("label_SkipToNLL", "skip to NLL"))
module.add(SCmpEQU32(sgpr("LoopCounterL"), 2, "LoopCounter LE 2?"))
module.add(SCBranchSCC1("label_SkipToNGLL", "skip to NGLL"))
items = insertClusterBarrier(module, _mockWriter(), _kernel()).flatitems()
sig, wait = _indices(items)
firstExit = next(i for i, x in enumerate(items) if isinstance(x, SCBranchSCC1))
assert sig < wait < firstExit, (
"cluster wait must follow the signal and precede the first early-exit "
"branch so no taken branch can skip it"
)
def test_wait_never_placed_after_exit_branch():
"""Anti-regression: no early-exit branch may precede the cluster wait."""
module = Module("section")
module.add(SCmpEQU32(sgpr("LoopCounterL"), 32, "LoopCounter LE 32?"))
module.add(SCBranchSCC1("label_SkipTailLoopL", "early-exit tail"))
items = insertClusterBarrier(module, _mockWriter(), _kernel()).flatitems()
_, wait = _indices(items)
exitsBeforeWait = [i for i, x in enumerate(items)
if isinstance(x, SCBranchSCC1) and i < wait]
assert not exitsBeforeWait, (
"an early-exit branch precedes the cluster wait; the barrier can be "
"signalled but never waited on that path"
)