Files
TheRock/rocm-libraries/shared/tensile/Tensile/Tests/unit/test_KernelWriterAssembly.py
T
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

250 lines
11 KiB
Python

################################################################################
#
# Copyright (C) 2019-2022 Advanced Micro Devices, Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
################################################################################
from Tensile.KernelWriterAssembly import KernelWriterAssembly
from Tensile.AsmRegisterPool import RegisterPool
from Tensile.KernelWriter import KernelWriter
from Tensile.Common import globalParameters
import collections
import inspect
from types import SimpleNamespace
class KernelDict(dict):
def __getattr__(self, name):
return self[name]
def test_gfx12_compatibility_checks_do_not_apply_to_future_isa():
kw = KernelWriterAssembly("","")
kw.version = (13, 0, 0)
kw.bpeCinternal = 4
kw.bpr = 4
assert "s_barrier_signal" not in kw.defineBarrierMacros()
assert "s_cmpk_eq_u32" in kw.checkIsBetaZero({"ProblemType": {"UseBeta": True}}, "Label", 0)
assert "gfx12 buffer soffset must be SGPR" not in str(
kw.chooseGlobalRead(True, 4, 0, "v0", "s[0:3]", 0, 0, "", False))
assert "gfx12 buffer atomic soffset must be SGPR" not in kw.chooseAtomicCmpswap(
{"BufferStore": True}, SimpleNamespace(globalOffset=0, addrDVgpr=0), 0, 0, 1, "glc")
def test_gfx9_barrier_assembly_stays_plain_s_barrier():
kw = KernelWriterAssembly("","")
kw.version = (9, 0, 0)
assert kw.syncStr == "s_barrier"
assert kw.defineBarrierMacros() == ""
def test_gfx9_sync_threads_emits_plain_s_barrier():
isa = (9, 0, 0)
oldArchCaps = globalParameters.get("ArchCaps")
globalParameters["ArchCaps"] = {isa: {"SeparateVscnt": False, "Waitcnt0Disabled": False}}
kw = KernelWriterAssembly("","")
kw.version = isa
kw.kernel = {"WavefrontSize": 32}
kw.do = {"Sync": True}
kw.prefetchAcrossPersistent = False
kernel = KernelDict(
NumThreads=64,
ScheduleIterAlg=0,
PrefetchGlobalRead=0,
enabledSplitLDS=False,
)
try:
assert kw.syncThreads(kernel, "gfx9 sync") == "s_barrier //gfx9 sync\n"
finally:
if oldArchCaps is None:
del globalParameters["ArchCaps"]
else:
globalParameters["ArchCaps"] = oldArchCaps
def test_kernel_writer_direct_barrier_sites_use_syncstr():
source = inspect.getsource(KernelWriter)
assert source.count('barrier.addInst(self.syncStr,"")') == 2
assert "syncCode.addCode(self.syncStr + self.endLine)" in source
def test_gfx12_barrier_assembly_uses_macro():
kw = KernelWriterAssembly("","")
kw.version = (12, 0, 1)
barrierMacro = kw.defineBarrierMacros()
assert kw.syncStr == "_s_barrier"
assert "s_barrier_signal" in barrierMacro
assert "s_barrier_wait" in barrierMacro
def test_gfx12_atomic_cmpswap_modifier_preserves_extra_modifiers():
kw = KernelWriterAssembly("","")
kw.version = (12, 0, 1)
assert kw.gfx12AtomicCmpswapMemoryModifier("glc") == "th:TH_ATOMIC_RT_RETURN"
assert kw.gfx12AtomicCmpswapMemoryModifier("glc slc") == "th:TH_ATOMIC_RT_RETURN slc"
def test_gfx12_atomic_cmpswap_modifier_rejects_other_architectures():
kw = KernelWriterAssembly("","")
kw.version = (13, 0, 0)
try:
kw.gfx12AtomicCmpswapMemoryModifier("glc")
except RuntimeError:
return
assert False, "Expected gfx12 atomic modifier helper to reject gfx13"
def test_gfx12_b256_emulation_preserves_outer_module_setup():
kw = KernelWriterAssembly("","")
kw.version = (12, 0, 1)
kw.sgprPool = RegisterPool(8, "s", defaultPreventOverflow=False, printRP=0)
kw.sgprPool.add(0, 8, "tmp")
code = str(kw.chooseGlobalRead(True, 32, 0, "v0", "s[0:3]", 0, 0, "", False))
assert "gfx12 buffer soffset must be SGPR" in code
assert code.count("_buffer_load_b128") == 2
assert code.index("gfx12 buffer soffset must be SGPR") < code.index("_buffer_load_b128")
def test_workgroup2_hydration_uses_actual_sgpr_definition():
kw = KernelWriterAssembly("","")
kw.sgprs = collections.OrderedDict()
assert not kw.hasWorkGroup2()
kw.sgprs["WorkGroup2"] = 4
assert kw.hasWorkGroup2()
def test_occupancy():
kw = KernelWriterAssembly("","")
# numThreads = 256
assert kw.getOccupancy(256, 10, 65536, 0) == 1
assert kw.getOccupancy(256, 10, 16384, 128) == 2
assert kw.getOccupancy(256, 65, 8192, 64) == 3
assert kw.getOccupancy(256, 10, 65536) == 1
assert kw.getOccupancy(256, 10, 32768) == 2
assert kw.getOccupancy(256, 129, 32768) == 1
assert kw.getOccupancy(256, 10, 16384) == 4
assert kw.getOccupancy(256, 256, 32768) == 1
# numThreads = 512
assert kw.getOccupancy(512, 10, 65536, 0) == 1
assert kw.getOccupancy(512, 10, 16384, 128) == 1
assert kw.getOccupancy(512, 65, 8192, 64) == 1
assert kw.getOccupancy(512, 10, 65536) == 1
assert kw.getOccupancy(512, 10, 32768) == 2
assert kw.getOccupancy(512, 129, 32768) == 0
assert kw.getOccupancy(512, 10, 16384) == 4
assert kw.getOccupancy(512, 256, 32768) == 0
assert kw.getOccupancy(512, 13, 1024) == 5
#----------- unifiedVgprRegs = True ---------------
# numThreads = 256
assert kw.getOccupancy(256, 256, 32768, 128, True) == 1
assert kw.getOccupancy(256, 128, 65536, 128, True) == 1
assert kw.getOccupancy(256, 256, 32768, 0, True) == 2
assert kw.getOccupancy(256, 128, 32768, 128, True) == 2
assert kw.getOccupancy(256, 128, 1024, 128, True) == 2
assert kw.getOccupancy(256, 97, 8192, 0, True) == 4
assert kw.getOccupancy(256, 65, 8192, 32, True) == 4
assert kw.getOccupancy(256, 64, 8192, 32, True) == 5
assert kw.getOccupancy(256, 65, 8192, 0, True) == 7
assert kw.getOccupancy(256, 0, 8192, 64, True) == 8
assert kw.getOccupancy(256, 24, 8192, 24, True) == 8
assert kw.getOccupancy(256, 49, 1024, 0, True) == 9
assert kw.getOccupancy(256, 24, 1024, 24, True) == 10
assert kw.getOccupancy(256, 48, 1024, 0, True) == 10
assert kw.getOccupancy(256, 3, 1024, 16, True) == 10
# numThreads = 512
assert kw.getOccupancy(512, 256, 32768, 128, True) == 0
assert kw.getOccupancy(512, 128, 65536, 128, True) == 1
assert kw.getOccupancy(512, 256, 32768, 0, True) == 1
assert kw.getOccupancy(512, 128, 32768, 128, True) == 1
assert kw.getOccupancy(512, 128, 1024, 128, True) == 1
assert kw.getOccupancy(512, 97, 8192, 0, True) == 2
assert kw.getOccupancy(512, 65, 8192, 32, True) == 2
assert kw.getOccupancy(512, 64, 8192, 32, True) == 2
assert kw.getOccupancy(512, 65, 8192, 0, True) == 3
assert kw.getOccupancy(512, 0, 8192, 64, True) == 4
assert kw.getOccupancy(512, 49, 1024, 0, True) == 4
assert kw.getOccupancy(512, 24, 1024, 24, True) == 5
assert kw.getOccupancy(512, 48, 1024, 0, True) == 5
assert kw.getOccupancy(512, 3, 1024, 16, True) == 5
def test_max_regs():
kw = KernelWriterAssembly("","")
assert kw.getMaxRegsForOccupancy(256, 10, 65536, 0) == 256
assert kw.getMaxRegsForOccupancy(256, 10, 16384, 128) == 128
assert kw.getMaxRegsForOccupancy(256, 65, 8192, 64) == 84
assert kw.getMaxRegsForOccupancy(256, 10, 65536) == 256
assert kw.getMaxRegsForOccupancy(256, 10, 32768) == 128
assert kw.getMaxRegsForOccupancy(256, 129, 32768) == 256
assert kw.getMaxRegsForOccupancy(256, 10, 16384) == 64
assert kw.getMaxRegsForOccupancy(256, 256, 32768) == 256
# numThreads = 512
assert kw.getMaxRegsForOccupancy(512, 10, 65536, 0) == 128
assert kw.getMaxRegsForOccupancy(512, 10, 16384, 128) == 128
assert kw.getMaxRegsForOccupancy(512, 65, 8192, 64) == 128
assert kw.getMaxRegsForOccupancy(512, 10, 65536) == 128
assert kw.getMaxRegsForOccupancy(512, 10, 32768) == 64
assert kw.getMaxRegsForOccupancy(512, 129, 32768) == 129
assert kw.getMaxRegsForOccupancy(512, 10, 16384) == 32
assert kw.getMaxRegsForOccupancy(512, 256, 32768) == 256
assert kw.getMaxRegsForOccupancy(512, 13, 1024) == 24
#----------- unifiedVgprRegs = True ---------------
# numThreads = 256
assert kw.getMaxRegsForOccupancy(256, 256, 32768, 128, True) == 256
assert kw.getMaxRegsForOccupancy(256, 128, 65536, 128, True) == 256
assert kw.getMaxRegsForOccupancy(256, 256, 32768, 0, True) == 256
assert kw.getMaxRegsForOccupancy(256, 128, 32768, 128, True) == 128
assert kw.getMaxRegsForOccupancy(256, 128, 1024, 128, True) == 128
assert kw.getMaxRegsForOccupancy(256, 97, 8192, 0, True) == 128
assert kw.getMaxRegsForOccupancy(256, 65, 8192, 32, True) == 96
assert kw.getMaxRegsForOccupancy(256, 64, 8192, 32, True) == 64
assert kw.getMaxRegsForOccupancy(256, 65, 8192, 0, True) == 72
assert kw.getMaxRegsForOccupancy(256, 0, 8192, 64, True) == 0
assert kw.getMaxRegsForOccupancy(256, 24, 8192, 24, True) == 40
assert kw.getMaxRegsForOccupancy(256, 49, 1024, 0, True) == 56
assert kw.getMaxRegsForOccupancy(256, 24, 1024, 24, True) == 24
assert kw.getMaxRegsForOccupancy(256, 48, 1024, 0, True) == 48
assert kw.getMaxRegsForOccupancy(256, 3, 1024, 16, True) == 32
# numThreads = 512
assert kw.getMaxRegsForOccupancy(512, 256, 32768, 128, True) == 256
assert kw.getMaxRegsForOccupancy(512, 128, 65536, 128, True) == 128
assert kw.getMaxRegsForOccupancy(512, 256, 32768, 0, True) == 256
assert kw.getMaxRegsForOccupancy(512, 128, 32768, 128, True) == 128
assert kw.getMaxRegsForOccupancy(512, 128, 1024, 128, True) == 128
assert kw.getMaxRegsForOccupancy(512, 97, 8192, 0, True) == 128
assert kw.getMaxRegsForOccupancy(512, 65, 8192, 32, True) == 96
assert kw.getMaxRegsForOccupancy(512, 64, 8192, 32, True) == 96
assert kw.getMaxRegsForOccupancy(512, 65, 8192, 0, True) == 80
assert kw.getMaxRegsForOccupancy(512, 0, 8192, 64, True) == 0
assert kw.getMaxRegsForOccupancy(512, 49, 1024, 0, True) == 64
assert kw.getMaxRegsForOccupancy(512, 24, 1024, 24, True) == 24
assert kw.getMaxRegsForOccupancy(512, 48, 1024, 0, True) == 48
assert kw.getMaxRegsForOccupancy(512, 3, 1024, 16, True) == 32
# test_occupancy()
# test_max_regs()