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
250 lines
11 KiB
Python
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()
|