From 8f28056009a842a5a2f5509fd8cf20bac3c76bab Mon Sep 17 00:00:00 2001 From: Xiaogang Chen Date: Sun, 22 Sep 2024 19:20:03 -0500 Subject: [PATCH] kfdtest: Convert KFDEventTest into multi-GPU test framework Signed-off-by: Xiaogang Chen Change-Id: Id1dc91f654686f159adb1bc70907e11558ee4be0 [ROCm/ROCR-Runtime commit: 0357e2e139677de0312f200c7ff2b756fd601957] --- .../tests/kfdtest/src/KFDEventTest.cpp | 204 ++++++++++++------ .../tests/kfdtest/src/KFDEventTest.hpp | 2 +- 2 files changed, 138 insertions(+), 68 deletions(-) diff --git a/projects/rocr-runtime/libhsakmt/tests/kfdtest/src/KFDEventTest.cpp b/projects/rocr-runtime/libhsakmt/tests/kfdtest/src/KFDEventTest.cpp index 65c7585953..2c008afcd2 100644 --- a/projects/rocr-runtime/libhsakmt/tests/kfdtest/src/KFDEventTest.cpp +++ b/projects/rocr-runtime/libhsakmt/tests/kfdtest/src/KFDEventTest.cpp @@ -33,7 +33,9 @@ void KFDEventTest::SetUp() { ROUTINE_START KFDBaseComponentTest::SetUp(); - m_pHsaEvent = NULL; + + for (int i = 0; i < MAX_GPU; i++) + m_pHsaEventGPU[i] = NULL; ROUTINE_END } @@ -42,9 +44,11 @@ void KFDEventTest::TearDown() { ROUTINE_START // Not all tests create an event, destroy only if there is one - if (m_pHsaEvent != NULL) { - // hsaKmtDestroyEvent moved to TearDown to make sure it is being called - EXPECT_SUCCESS(hsaKmtDestroyEvent(m_pHsaEvent)); + for (int i = 0; i < MAX_GPU; i++) { + if (m_pHsaEventGPU[i] != NULL) { + // hsaKmtDestroyEvent moved to TearDown to make sure it is being called + EXPECT_SUCCESS(hsaKmtDestroyEvent(m_pHsaEventGPU[i])); + } } KFDBaseComponentTest::TearDown(); @@ -52,18 +56,33 @@ void KFDEventTest::TearDown() { ROUTINE_END } +static void CreateDestroyEvent(KFDTEST_PARAMETERS* pTestParamters) { + + int gpuNode = pTestParamters->gpuNode; + KFDEventTest* pKFDEventTest = (KFDEventTest*)pTestParamters->pTestObject; + + int gpuIndex = pKFDEventTest->Get_NodeInfo()->HsaGPUindexFromGpuNode(gpuNode); + HsaEvent* m_pHsaEvent = pKFDEventTest->m_pHsaEventGPU[gpuIndex]; + + ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &m_pHsaEvent), gpuNode); + EXPECT_NE_GPU(0, m_pHsaEvent->EventData.HWData2, gpuNode); + +} + TEST_F(KFDEventTest, CreateDestroyEvent) { TEST_START(TESTPROFILE_RUNALL); - ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, m_NodeInfo.HsaDefaultGPUNode(), &m_pHsaEvent)); - EXPECT_NE(0, m_pHsaEvent->EventData.HWData2); + ASSERT_SUCCESS(KFDTest_Launch(CreateDestroyEvent)); // Destroy event is being called in test TearDown TEST_END; } -TEST_F(KFDEventTest, CreateMaxEvents) { - TEST_START(TESTPROFILE_RUNALL); + +static void CreateMaxEvents(KFDTEST_PARAMETERS* pTestParamters) { + + int gpuNode = pTestParamters->gpuNode; + KFDEventTest* pKFDEventTest = (KFDEventTest*)pTestParamters->pTestObject; static const unsigned int MAX_EVENT_NUMBER = 256; @@ -73,32 +92,41 @@ TEST_F(KFDEventTest, CreateMaxEvents) { for (i = 0; i < MAX_EVENT_NUMBER; i++) { pHsaEvent[i] = NULL; - ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, m_NodeInfo.HsaDefaultGPUNode(), &pHsaEvent[i])); + ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &pHsaEvent[i]), gpuNode); } for (i = 0; i < MAX_EVENT_NUMBER; i++) { - EXPECT_SUCCESS(hsaKmtDestroyEvent(pHsaEvent[i])); + EXPECT_SUCCESS_GPU(hsaKmtDestroyEvent(pHsaEvent[i]), gpuNode); } +} + +TEST_F(KFDEventTest, CreateMaxEvents) { + TEST_START(TESTPROFILE_RUNALL); + + ASSERT_SUCCESS(KFDTest_Launch(CreateMaxEvents)); TEST_END; } -TEST_F(KFDEventTest, SignalEvent) { - TEST_START(TESTPROFILE_RUNALL); +static void SignalEvent(KFDTEST_PARAMETERS* pTestParamters) { + + int gpuNode = pTestParamters->gpuNode; + KFDEventTest* pKFDEventTest = (KFDEventTest*)pTestParamters->pTestObject; + + int gpuIndex = pKFDEventTest->Get_NodeInfo()->HsaGPUindexFromGpuNode(gpuNode); + HsaEvent* m_pHsaEvent = pKFDEventTest->m_pHsaEventGPU[gpuIndex]; + HSAuint32 m_FamilyId = pKFDEventTest->GetFamilyIdFromNodeId(gpuNode); PM4Queue queue; HsaEvent *tmp_event; - int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode(); - ASSERT_GE(defaultGPUNode, 0) << "failed to get default GPU Node"; - - ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, defaultGPUNode, &tmp_event)); + ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, gpuNode, &tmp_event)); /* Intentionally let event id for m_pHsaEvent be non zero */ - ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, defaultGPUNode, &m_pHsaEvent)); + ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, gpuNode, &m_pHsaEvent)); ASSERT_NE(0, m_pHsaEvent->EventData.HWData2); - ASSERT_SUCCESS(queue.Create(defaultGPUNode)); + ASSERT_SUCCESS(queue.Create(gpuNode)); /* From gfx9 onward, m_pHsaEvent->EventId will also be passed to int_ctxid in * the Release Mem packet, which is used as context id in ISR. @@ -108,66 +136,75 @@ TEST_F(KFDEventTest, SignalEvent) { queue.Wait4PacketConsumption(); - EXPECT_SUCCESS(hsaKmtWaitOnEvent(m_pHsaEvent, g_TestTimeOut)); + EXPECT_SUCCESS_GPU(hsaKmtWaitOnEvent(m_pHsaEvent, g_TestTimeOut), gpuNode); - EXPECT_SUCCESS(hsaKmtDestroyEvent(tmp_event)); + EXPECT_SUCCESS_GPU(hsaKmtDestroyEvent(tmp_event), gpuNode); - EXPECT_SUCCESS(queue.Destroy()); + EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode); +} + +TEST_F(KFDEventTest, SignalEvent) { + TEST_START(TESTPROFILE_RUNALL); + + ASSERT_SUCCESS(KFDTest_Launch(SignalEvent)); TEST_END; } /* test event signaling with event age enabled wait */ -TEST_F(KFDEventTest, SignalEventExt) { - TEST_START(TESTPROFILE_RUNALL); +static void SignalEventExt(KFDTEST_PARAMETERS* pTestParamters) { + + int gpuNode = pTestParamters->gpuNode; + KFDEventTest* pKFDEventTest = (KFDEventTest*)pTestParamters->pTestObject; + + int gpuIndex = pKFDEventTest->Get_NodeInfo()->HsaGPUindexFromGpuNode(gpuNode); + HsaEvent* m_pHsaEvent = pKFDEventTest->m_pHsaEventGPU[gpuIndex]; + HSAuint32 m_FamilyId = pKFDEventTest->GetFamilyIdFromNodeId(gpuNode); PM4Queue queue; HsaEvent *tmp_event; uint64_t event_age; - if (m_VersionInfo.KernelInterfaceMajorVersion == 1 && - m_VersionInfo.KernelInterfaceMinorVersion < 14) { + if (pKFDEventTest->Get_Version()->KernelInterfaceMajorVersion == 1 && + pKFDEventTest->Get_Version()->KernelInterfaceMinorVersion < 14) { LOG() << "event age tracking isn't supported in KFD. Exiting." << std::endl; return; } - int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode(); - ASSERT_GE(defaultGPUNode, 0) << "failed to get default GPU Node"; - - ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, defaultGPUNode, &tmp_event)); + ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &tmp_event), gpuNode); /* Intentionally let event id for m_pHsaEvent be non zero */ - ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, defaultGPUNode, &m_pHsaEvent)); - ASSERT_NE(0, m_pHsaEvent->EventData.HWData2); + ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &m_pHsaEvent), gpuNode); + ASSERT_NE_GPU(0, m_pHsaEvent->EventData.HWData2, gpuNode); - ASSERT_SUCCESS(queue.Create(defaultGPUNode)); + ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode); /* 1. event_age gets incremented every time when the event signals */ event_age = 1; queue.PlaceAndSubmitPacket(PM4ReleaseMemoryPacket(m_FamilyId, false, m_pHsaEvent->EventData.HWData2, m_pHsaEvent->EventId)); - EXPECT_SUCCESS(hsaKmtWaitOnEvent_Ext(m_pHsaEvent, g_TestTimeOut, &event_age)); - ASSERT_EQ(event_age, 2); + EXPECT_SUCCESS_GPU(hsaKmtWaitOnEvent_Ext(m_pHsaEvent, g_TestTimeOut, &event_age), gpuNode); + ASSERT_EQ_GPU(event_age, 2, gpuNode); queue.PlaceAndSubmitPacket(PM4ReleaseMemoryPacket(m_FamilyId, false, m_pHsaEvent->EventData.HWData2, m_pHsaEvent->EventId)); - EXPECT_SUCCESS(hsaKmtWaitOnEvent_Ext(m_pHsaEvent, g_TestTimeOut, &event_age)); - ASSERT_EQ(event_age, 3); + EXPECT_SUCCESS_GPU(hsaKmtWaitOnEvent_Ext(m_pHsaEvent, g_TestTimeOut, &event_age), gpuNode); + ASSERT_EQ_GPU(event_age, 3, gpuNode); /* 2. event wait return without sleep after the event signals */ queue.PlaceAndSubmitPacket(PM4ReleaseMemoryPacket(m_FamilyId, false, m_pHsaEvent->EventData.HWData2, m_pHsaEvent->EventId)); sleep(1); /* wait for event signaling */ - EXPECT_SUCCESS(hsaKmtWaitOnEvent_Ext(m_pHsaEvent, g_TestTimeOut, &event_age)); - ASSERT_EQ(event_age, 4); + EXPECT_SUCCESS_GPU(hsaKmtWaitOnEvent_Ext(m_pHsaEvent, g_TestTimeOut, &event_age), gpuNode); + ASSERT_EQ_GPU(event_age, 4, gpuNode); /* 3. signaling from CPU */ hsaKmtSetEvent(m_pHsaEvent); - EXPECT_SUCCESS(hsaKmtWaitOnEvent_Ext(m_pHsaEvent, g_TestTimeOut, &event_age)); - ASSERT_EQ(event_age, 5); + EXPECT_SUCCESS_GPU(hsaKmtWaitOnEvent_Ext(m_pHsaEvent, g_TestTimeOut, &event_age), gpuNode); + ASSERT_EQ_GPU(event_age, 5, gpuNode); /* 4. when event_age is 0, hsaKmtWaitOnEvent_Ext always sleeps */ event_age = 0; - ASSERT_EQ(HSAKMT_STATUS_WAIT_TIMEOUT, hsaKmtWaitOnEvent_Ext(m_pHsaEvent, g_TestTimeOut, &event_age)); + ASSERT_EQ_GPU(HSAKMT_STATUS_WAIT_TIMEOUT, hsaKmtWaitOnEvent_Ext(m_pHsaEvent, g_TestTimeOut, &event_age), gpuNode); /* 5. when event_age is 0, it always stays 0 after the event signals */ queue.PlaceAndSubmitPacket(PM4ReleaseMemoryPacket(m_FamilyId, false, @@ -179,6 +216,13 @@ TEST_F(KFDEventTest, SignalEventExt) { EXPECT_SUCCESS(queue.Destroy()); +} + +TEST_F(KFDEventTest, SignalEventExt) { + TEST_START(TESTPROFILE_RUNALL); + + ASSERT_SUCCESS(KFDTest_Launch(SignalEventExt)); + TEST_END; } @@ -308,21 +352,34 @@ TEST_F(KFDEventTest, MeasureInterruptConsumption) { TEST_END; } -TEST_F(KFDEventTest, SignalMaxEvents) { - TEST_START(TESTPROFILE_RUNALL); +static void SignalMaxEvents(KFDTEST_PARAMETERS* pTestParamters) { + + int gpuNode = pTestParamters->gpuNode; + KFDEventTest* pKFDEventTest = (KFDEventTest*)pTestParamters->pTestObject; static const unsigned int MAX_EVENT_NUMBER = 4095; uint64_t time, latency; QueueAndSignalBenchmark maxEventTest(MAX_EVENT_NUMBER); - maxEventTest.queueAndSignalEvents(m_NodeInfo.HsaDefaultGPUNode(), MAX_EVENT_NUMBER, + maxEventTest.queueAndSignalEvents(gpuNode, MAX_EVENT_NUMBER, time, latency); +} + +TEST_F(KFDEventTest, SignalMaxEvents) { + TEST_START(TESTPROFILE_RUNALL); + + ASSERT_SUCCESS(KFDTest_Launch(SignalMaxEvents)); TEST_END; } -TEST_F(KFDEventTest, SignalMultipleEventsWaitForAll) { - TEST_START(TESTPROFILE_RUNALL); +static void SignalMultipleEventsWaitForAll(KFDTEST_PARAMETERS* pTestParamters) { + + int gpuNode = pTestParamters->gpuNode; + KFDEventTest* pKFDEventTest = (KFDEventTest*)pTestParamters->pTestObject; + + int gpuIndex = pKFDEventTest->Get_NodeInfo()->HsaGPUindexFromGpuNode(gpuNode); + HSAuint32 m_FamilyId = pKFDEventTest->GetFamilyIdFromNodeId(gpuNode); static const unsigned int EVENT_NUMBER = 64; // 64 is the maximum for hsaKmtWaitOnMultipleEvents static const unsigned int WAIT_BETWEEN_SUBMISSIONS_MS = 50; @@ -330,17 +387,14 @@ TEST_F(KFDEventTest, SignalMultipleEventsWaitForAll) { HsaEvent* pHsaEvent[EVENT_NUMBER]; unsigned int i = 0; - int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode(); - ASSERT_GE(defaultGPUNode, 0) << "failed to get default GPU Node"; - for (i = 0; i < EVENT_NUMBER; i++) { pHsaEvent[i] = NULL; - ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, defaultGPUNode, &pHsaEvent[i])); + ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &pHsaEvent[i]), gpuNode); } PM4Queue queue; - ASSERT_SUCCESS(queue.Create(defaultGPUNode)); + ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode); unsigned int pktSizeDwords = 0; for (i = 0; i < EVENT_NUMBER; i++) { @@ -351,12 +405,18 @@ TEST_F(KFDEventTest, SignalMultipleEventsWaitForAll) { Delay(WAIT_BETWEEN_SUBMISSIONS_MS); } - EXPECT_SUCCESS(hsaKmtWaitOnMultipleEvents(pHsaEvent, EVENT_NUMBER, true, g_TestTimeOut)); + EXPECT_SUCCESS_GPU(hsaKmtWaitOnMultipleEvents(pHsaEvent, EVENT_NUMBER, true, g_TestTimeOut), gpuNode); - EXPECT_SUCCESS(queue.Destroy()); + EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode); for (i = 0; i < EVENT_NUMBER; i++) - EXPECT_SUCCESS(hsaKmtDestroyEvent(pHsaEvent[i])); + EXPECT_SUCCESS_GPU(hsaKmtDestroyEvent(pHsaEvent[i]), gpuNode); +} + +TEST_F(KFDEventTest, SignalMultipleEventsWaitForAll) { + TEST_START(TESTPROFILE_RUNALL); + + ASSERT_SUCCESS(KFDTest_Launch(SignalMultipleEventsWaitForAll)); TEST_END; } @@ -365,26 +425,29 @@ TEST_F(KFDEventTest, SignalMultipleEventsWaitForAll) { * gracefully and with good performance. On current GPUs and firmware it * should be handled on a fast path. */ -TEST_F(KFDEventTest, SignalInvalidEvent) { - TEST_START(TESTPROFILE_RUNALL); +static void SignalInvalidEvent(KFDTEST_PARAMETERS* pTestParamters) { + + int gpuNode = pTestParamters->gpuNode; + KFDEventTest* pKFDEventTest = (KFDEventTest*)pTestParamters->pTestObject; + + int gpuIndex = pKFDEventTest->Get_NodeInfo()->HsaGPUindexFromGpuNode(gpuNode); + HsaEvent* m_pHsaEvent = pKFDEventTest->m_pHsaEventGPU[gpuIndex]; + HSAuint32 m_FamilyId = pKFDEventTest->GetFamilyIdFromNodeId(gpuNode); PM4Queue queue; - int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode(); - ASSERT_GE(defaultGPUNode, 0) << "failed to get default GPU Node"; - // Create some dummy events, to make the slow path a bit slower - static const unsigned int EVENT_NUMBER = 4094; + static const unsigned int EVENT_NUMBER = 64;//4094; HsaEvent* pHsaEvent[EVENT_NUMBER]; for (int i = 0; i < EVENT_NUMBER; i++) { pHsaEvent[i] = NULL; - ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, defaultGPUNode, &pHsaEvent[i])); + ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &pHsaEvent[i]), gpuNode); } - ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, defaultGPUNode, &m_pHsaEvent)); - ASSERT_NE(0, m_pHsaEvent->EventData.HWData2); + ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &m_pHsaEvent), gpuNode); + ASSERT_NE_GPU(0, m_pHsaEvent->EventData.HWData2, gpuNode); - ASSERT_SUCCESS(queue.Create(defaultGPUNode)); + ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode); static const unsigned int REPS = 2000; HSAuint64 duration[REPS]; @@ -399,7 +462,7 @@ TEST_F(KFDEventTest, SignalInvalidEvent) { HSAuint64 startTime = GetSystemTickCountInMicroSec(); queue.SubmitPacket(); - EXPECT_SUCCESS(hsaKmtWaitOnEvent(m_pHsaEvent, g_TestTimeOut)); + EXPECT_SUCCESS_GPU(hsaKmtWaitOnEvent(m_pHsaEvent, g_TestTimeOut), gpuNode); duration[i] = GetSystemTickCountInMicroSec() - startTime; total += duration[i]; @@ -435,10 +498,17 @@ TEST_F(KFDEventTest, SignalInvalidEvent) { LOG() << "Time for event handling (min/avg/max [std.dev] in us) " << std::dec << newMin << "/" << mean << "/" << newMax << " [" << stdDev << "]\n"; - EXPECT_SUCCESS(queue.Destroy()); + EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode); for (int i = 0; i < EVENT_NUMBER; i++) - EXPECT_SUCCESS(hsaKmtDestroyEvent(pHsaEvent[i])); + EXPECT_SUCCESS_GPU(hsaKmtDestroyEvent(pHsaEvent[i]), gpuNode); + +} + +TEST_F(KFDEventTest, SignalInvalidEvent) { + TEST_START(TESTPROFILE_RUNALL); + + ASSERT_SUCCESS(KFDTest_Launch(SignalInvalidEvent)); TEST_END; } diff --git a/projects/rocr-runtime/libhsakmt/tests/kfdtest/src/KFDEventTest.hpp b/projects/rocr-runtime/libhsakmt/tests/kfdtest/src/KFDEventTest.hpp index e0bca47288..cac1846a2f 100644 --- a/projects/rocr-runtime/libhsakmt/tests/kfdtest/src/KFDEventTest.hpp +++ b/projects/rocr-runtime/libhsakmt/tests/kfdtest/src/KFDEventTest.hpp @@ -36,9 +36,9 @@ class KFDEventTest : public KFDBaseComponentTest { // @brief Executed after every test in KFDEventTest. virtual void TearDown(); + HsaEvent* m_pHsaEventGPU[MAX_GPU]; protected: static const unsigned int EVENT_TIMEOUT = 5000; // 5 seconds - HsaEvent* m_pHsaEvent; }; #endif // __KFD_EVENT_TEST__H__