// Copyright Advanced Micro Devices, Inc., or its affiliates. // SPDX-License-Identifier: MIT #ifdef ROCROLLER_USE_HIP #include #include #endif /* ROCROLLER_USE_HIP */ #include "GEMMTestBase.hpp" namespace GEMMTests { using namespace rocRoller; namespace SolutionParams = rocRoller::Parameters::Solution; // ======================================================================== // GEMMJammedTestSuite // ======================================================================== class GEMMJammedTestSuite : public BaseGEMMContextFixture<> { }; TEST_P(GEMMJammedTestSuite, GPU_GEMM_Jammed_2x2) { REQUIRE_ARCH_CAP(GPUCapability::HasMFMA); GEMMProblem gemm; gemm.m = 256; gemm.n = 512; gemm.k = 64; gemm.macM = 128; gemm.macN = 256; gemm.macK = 16; gemm.waveK = 8; gemm.workgroupSizeX = 2 * gemm.wavefrontSize; gemm.workgroupSizeY = 4; gemm.loadPathA = SolutionParams::LoadPath::BufferToVGPR; gemm.storePath = SolutionParams::StorePath::VGPRToGlobalMemoryWithBuffer; gemm.fuseLoops = false; basicGEMM(gemm); } TEST_P(GEMMJammedTestSuite, GPU_GEMM_Jammed_2x1) { REQUIRE_ARCH_CAP(GPUCapability::HasMFMA); GEMMProblem gemm; gemm.m = 256; gemm.n = 512; gemm.k = 64; gemm.macM = 128; gemm.macN = 128; gemm.macK = 16; gemm.waveK = 8; gemm.workgroupSizeX = 2 * gemm.wavefrontSize; gemm.workgroupSizeY = 4; gemm.betaInFma = false; gemm.transA = "T"; gemm.transB = "N"; basicGEMM(gemm); std::string generatedCode = m_context->instructions()->toString(); EXPECT_EQ(countSubstring(generatedCode, "ds_write_b64"), 18); EXPECT_EQ(countSubstring(generatedCode, "ds_read_b128"), 8); EXPECT_EQ(countSubstring(generatedCode, "buffer_store_dwordx4"), 8); } TEST_P(GEMMJammedTestSuite, GPU_GEMM_Jammed_2x1_UnrollK) { REQUIRE_ARCH_CAP(GPUCapability::HasMFMA); GEMMProblem gemm; gemm.m = 256; gemm.n = 512; gemm.k = 64; gemm.macM = 128; gemm.macN = 128; gemm.macK = 16; gemm.unrollK = 2; gemm.waveK = 8; gemm.workgroupSizeX = 2 * gemm.wavefrontSize; gemm.workgroupSizeY = 4; gemm.transA = "T"; gemm.transB = "N"; basicGEMM(gemm); std::string generatedCode = m_context->instructions()->toString(); EXPECT_EQ(countSubstring(generatedCode, "ds_write_b64"), 22); EXPECT_EQ(countSubstring(generatedCode, "ds_read_b128"), 8); EXPECT_EQ(countSubstring(generatedCode, "buffer_store_dwordx4"), 8); } TEST_P(GEMMJammedTestSuite, GPU_GEMM_Jammed_1x2) { REQUIRE_ARCH_CAP(GPUCapability::HasMFMA); GEMMProblem gemm; gemm.m = 256; gemm.n = 512; gemm.k = 64; gemm.macM = 128; gemm.macN = 128; gemm.macK = 16; gemm.waveK = 8; gemm.workgroupSizeX = 4 * gemm.wavefrontSize; gemm.workgroupSizeY = 2; gemm.transA = "T"; basicGEMM(gemm); std::string generatedCode = m_context->instructions()->toString(); EXPECT_EQ(countSubstring(generatedCode, "ds_write_b64"), 18); EXPECT_EQ(countSubstring(generatedCode, "ds_read_b128"), 8); EXPECT_EQ(countSubstring(generatedCode, "buffer_store_dwordx4"), 8); } TEST_P(GEMMJammedTestSuite, GPU_GEMM_Jammed_1x2_UnrollK) { REQUIRE_ARCH_CAP(GPUCapability::HasMFMA); GEMMProblem gemm; gemm.m = 256; gemm.n = 512; gemm.k = 64; gemm.macM = 128; gemm.macN = 128; gemm.macK = 16; gemm.unrollK = 4; gemm.waveK = 8; gemm.workgroupSizeX = 4 * gemm.wavefrontSize; gemm.workgroupSizeY = 2; gemm.transA = "T"; basicGEMM(gemm); std::string generatedCode = m_context->instructions()->toString(); EXPECT_EQ(countSubstring(generatedCode, "ds_write_b64"), 26); EXPECT_EQ(countSubstring(generatedCode, "ds_read_b128"), 8); EXPECT_EQ(countSubstring(generatedCode, "buffer_store_dwordx4"), 8); } TEST_P(GEMMJammedTestSuite, GPU_GEMM_Jammed_1x8) { REQUIRE_ARCH_CAP(GPUCapability::HasMFMA); GEMMProblem gemm; gemm.m = 256; gemm.n = 512; gemm.k = 64; gemm.macM = 128; gemm.macN = 256; gemm.macK = 16; gemm.waveK = 8; gemm.workgroupSizeX = 4 * gemm.wavefrontSize; gemm.workgroupSizeY = 1; gemm.storePath = SolutionParams::StorePath::VGPRToGlobalMemoryWithBuffer; basicGEMM(gemm); } TEST_P(GEMMJammedTestSuite, GPU_GEMM_Jammed_1x8_UnrollK) { REQUIRE_ARCH_CAP(GPUCapability::HasMFMA); GEMMProblem gemm; gemm.m = 256; gemm.n = 512; gemm.k = 64; gemm.macM = 128; gemm.macN = 256; gemm.macK = 16; gemm.unrollK = 2; gemm.waveK = 8; gemm.workgroupSizeX = 4 * gemm.wavefrontSize; gemm.workgroupSizeY = 1; gemm.storePath = SolutionParams::StorePath::VGPRToGlobalMemoryWithBuffer; basicGEMM(gemm); } TEST_P(GEMMJammedTestSuite, GPU_GEMM_Jammed_2x4) { REQUIRE_ARCH_CAP(GPUCapability::HasMFMA); GEMMProblem gemm; gemm.m = 256; gemm.n = 512; gemm.k = 64; gemm.macM = 128; gemm.macN = 256; gemm.macK = 16; gemm.waveK = 8; gemm.workgroupSizeX = 2 * gemm.wavefrontSize; gemm.workgroupSizeY = 2; gemm.storePath = SolutionParams::StorePath::VGPRToGlobalMemoryWithBuffer; basicGEMM(gemm); std::string generatedCode = m_context->instructions()->toString(); EXPECT_EQ(countSubstring(generatedCode, "ds_write_b128"), 3); EXPECT_EQ(countSubstring(generatedCode, "v_pack_b32_f16"), 152); } TEST_P(GEMMJammedTestSuite, GPU_GEMM_Jammed_2x4_UnrollK) { REQUIRE_ARCH_CAP(GPUCapability::HasMFMA); GEMMProblem gemm; gemm.m = 256; gemm.n = 512; gemm.k = 64; gemm.macM = 128; gemm.macN = 256; gemm.macK = 16; gemm.unrollK = 2; gemm.prefetchInFlight = 2; gemm.prefetchLDSFactor = 2; gemm.prefetchMixMemOps = true; gemm.waveK = 8; gemm.workgroupSizeX = 2 * gemm.wavefrontSize; gemm.workgroupSizeY = 2; gemm.storePath = SolutionParams::StorePath::VGPRToGlobalMemoryWithBuffer; basicGEMM(gemm); std::string generatedCode = m_context->instructions()->toString(); EXPECT_EQ(countSubstring(generatedCode, "ds_write_b128"), 9); } TEST_P(GEMMJammedTestSuite, GPU_GEMM_Jammed_4x2) { REQUIRE_ARCH_CAP(GPUCapability::HasMFMA); GEMMProblem gemm; gemm.m = 256; gemm.n = 512; gemm.k = 64; gemm.macM = 128; gemm.macN = 256; gemm.macK = 16; gemm.waveK = 8; gemm.workgroupSizeX = 1 * gemm.wavefrontSize; gemm.workgroupSizeY = 4; gemm.storePath = SolutionParams::StorePath::VGPRToGlobalMemoryWithBuffer; gemm.transB = "N"; basicGEMM(gemm); std::string generatedCode = m_context->instructions()->toString(); EXPECT_EQ(countSubstring(generatedCode, "ds_write_b128"), 3); } TEST_P(GEMMJammedTestSuite, GPU_GEMM_Jammed_4x2_UnrollK) { REQUIRE_ARCH_CAP(GPUCapability::HasMFMA); GEMMProblem gemm; gemm.m = 256; gemm.n = 512; gemm.k = 64; gemm.macM = 128; gemm.macN = 256; gemm.macK = 16; gemm.unrollK = 4; gemm.waveK = 8; gemm.workgroupSizeX = 1 * gemm.wavefrontSize; gemm.workgroupSizeY = 4; gemm.storePath = SolutionParams::StorePath::VGPRToGlobalMemoryWithBuffer; gemm.transB = "N"; basicGEMM(gemm); std::string generatedCode = m_context->instructions()->toString(); EXPECT_EQ(countSubstring(generatedCode, "ds_write_b128"), 15); } INSTANTIATE_TEST_SUITE_P(GEMMJammedTest, GEMMJammedTestSuite, currentGPUISA()); } // namespace GEMMTests