From ea4476770ad3dc8b986e00e9a01e31444cd085e0 Mon Sep 17 00:00:00 2001 From: vinay birur Date: Tue, 11 Apr 2023 17:16:22 +0530 Subject: [PATCH] SWDEV-388833 - [catch2][dtest] p2p tests migrated from dtests to catch2 Recreation of github PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/319, Change-Id: I6024fd5172a9765756938601a30ed0469b5f1d5b --- catch/include/hip_test_defgroups.hh | 6 + catch/unit/CMakeLists.txt | 1 + catch/unit/device/CMakeLists.txt | 4 - catch/unit/p2p/CMakeLists.txt | 24 ++ .../hipDeviceGetP2PAttribute.cc | 83 +++-- .../hipDeviceGetP2PAttribute_exe.cc | 0 catch/unit/p2p/hipP2pLinkTypeAndHopFunc.cc | 351 ++++++++++++++++++ catch/unit/p2p/hipP2pLinkTypeAndHopFunc.h | 110 ++++++ 8 files changed, 543 insertions(+), 36 deletions(-) create mode 100644 catch/unit/p2p/CMakeLists.txt rename catch/unit/{device => p2p}/hipDeviceGetP2PAttribute.cc (70%) rename catch/unit/{device => p2p}/hipDeviceGetP2PAttribute_exe.cc (100%) create mode 100644 catch/unit/p2p/hipP2pLinkTypeAndHopFunc.cc create mode 100644 catch/unit/p2p/hipP2pLinkTypeAndHopFunc.h diff --git a/catch/include/hip_test_defgroups.hh b/catch/include/hip_test_defgroups.hh index 1cbab2f7f6..d16c5a0d4a 100644 --- a/catch/include/hip_test_defgroups.hh +++ b/catch/include/hip_test_defgroups.hh @@ -119,6 +119,12 @@ THE SOFTWARE. * @defgroup ShflTest warp shuffle function Management * @{ * This section describes the warp shuffle types & functions of HIP runtime API. + */ + +/** + * @defgroup p2pTest P2P Management + * @{ + * This section describes the P2P management types & functions of HIP runtime API. * @} */ diff --git a/catch/unit/CMakeLists.txt b/catch/unit/CMakeLists.txt index 135d3a12ab..de70022a06 100644 --- a/catch/unit/CMakeLists.txt +++ b/catch/unit/CMakeLists.txt @@ -41,6 +41,7 @@ add_subdirectory(g++) add_subdirectory(module) add_subdirectory(channelDescriptor) add_subdirectory(executionControl) +add_subdirectory(p2p) if(HIP_PLATFORM STREQUAL "amd") add_subdirectory(callback) diff --git a/catch/unit/device/CMakeLists.txt b/catch/unit/device/CMakeLists.txt index a876d86694..087588e059 100644 --- a/catch/unit/device/CMakeLists.txt +++ b/catch/unit/device/CMakeLists.txt @@ -16,7 +16,6 @@ set(TEST_SRC hipGetSetDeviceFlags.cc hipSetGetDevice.cc hipDeviceGetUuid.cc - hipDeviceGetP2PAttribute.cc hipDeviceGetDefaultMemPool.cc hipDeviceCanAccessPeer.cc hipDeviceEnableDisablePeerAccess.cc @@ -38,10 +37,8 @@ if(UNIX) endif() set_source_files_properties(hipGetDeviceCount.cc PROPERTIES COMPILE_FLAGS -std=c++17) -set_source_files_properties(hipDeviceGetP2PAttribute.cc PROPERTIES COMPILE_FLAGS -std=c++17) add_executable(getDeviceCount EXCLUDE_FROM_ALL getDeviceCount_exe.cc) -add_executable(hipDeviceGetP2PAttribute_exe EXCLUDE_FROM_ALL hipDeviceGetP2PAttribute_exe.cc) hip_add_exe_to_target(NAME DeviceTest TEST_SRC ${TEST_SRC} @@ -49,4 +46,3 @@ hip_add_exe_to_target(NAME DeviceTest COMPILE_OPTIONS -std=c++17) add_dependencies(build_tests getDeviceCount) -add_dependencies(build_tests hipDeviceGetP2PAttribute_exe) diff --git a/catch/unit/p2p/CMakeLists.txt b/catch/unit/p2p/CMakeLists.txt new file mode 100644 index 0000000000..d24910daf2 --- /dev/null +++ b/catch/unit/p2p/CMakeLists.txt @@ -0,0 +1,24 @@ +# Common Tests - Test independent of all platforms +# moved hipDeviceGetP2PAttribute.cc from /catch/unit/device to +# /catch/unit/p2p folder and its dependent files. +set(TEST_SRC + hipDeviceGetP2PAttribute.cc +) + +# only for AMD +if(HIP_PLATFORM MATCHES "amd") + set(AMD_SRC + hipP2pLinkTypeAndHopFunc.cc + ) + set(TEST_SRC ${TEST_SRC} ${AMD_SRC}) +endif() + +set_source_files_properties(hipDeviceGetP2PAttribute.cc PROPERTIES COMPILE_FLAGS -std=c++17) + +add_executable(hipDeviceGetP2PAttribute_exe EXCLUDE_FROM_ALL hipDeviceGetP2PAttribute_exe.cc) + +hip_add_exe_to_target(NAME p2pTests + TEST_SRC ${TEST_SRC} + TEST_TARGET_NAME build_tests) + +add_dependencies(build_tests hipDeviceGetP2PAttribute_exe) diff --git a/catch/unit/device/hipDeviceGetP2PAttribute.cc b/catch/unit/p2p/hipDeviceGetP2PAttribute.cc similarity index 70% rename from catch/unit/device/hipDeviceGetP2PAttribute.cc rename to catch/unit/p2p/hipDeviceGetP2PAttribute.cc index dd1ac34c3d..89207fee7f 100644 --- a/catch/unit/device/hipDeviceGetP2PAttribute.cc +++ b/catch/unit/p2p/hipDeviceGetP2PAttribute.cc @@ -1,5 +1,5 @@ /* -Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +Copyright (c) 2022 - 2023 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 @@ -23,6 +23,7 @@ THE SOFTWARE. #include "hip/hip_runtime_api.h" #include #include +#include /** * @addtogroup hipDeviceGetP2PAttribute hipDeviceGetP2PAttribute @@ -44,6 +45,21 @@ THE SOFTWARE. * ------------------------ * - HIP_VERSION >= 5.2 */ + +/** + * Test Description + * ------------------------ + * - Test all possible combination of attributes and devices for hipDeviceGetP2PAttribute + * Verify that the output is within the range of acceptable values. + + * Test source + * ------------------------ + * - catch/unit/p2p/hipDeviceGetP2PAttribute.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.5 + */ + TEST_CASE("Unit_hipDeviceGetP2PAttribute_Basic") { #if HT_AMD HipTest::HIP_SKIP_TEST("EXSWCPHIPT-119"); @@ -57,17 +73,19 @@ TEST_CASE("Unit_hipDeviceGetP2PAttribute_Basic") { } hipDeviceP2PAttr attribute = - GENERATE(hipDevP2PAttrPerformanceRank, hipDevP2PAttrAccessSupported, - hipDevP2PAttrNativeAtomicSupported, hipDevP2PAttrHipArrayAccessSupported); + GENERATE(hipDevP2PAttrPerformanceRank, hipDevP2PAttrAccessSupported, + hipDevP2PAttrNativeAtomicSupported, hipDevP2PAttrHipArrayAccessSupported); /* Test all combinations of devices in the system */ for (int srcDevice = 0; srcDevice < deviceCount; ++srcDevice) { for (int dstDevice = 0; dstDevice < deviceCount; ++dstDevice) { if (srcDevice != dstDevice) { int value{-1}; - HIP_CHECK(hipDeviceGetP2PAttribute(&value, attribute, srcDevice, dstDevice)); + HIP_CHECK(hipDeviceGetP2PAttribute(&value, attribute, + srcDevice, dstDevice)); INFO("hipDeviceP2PAttr: " << attribute << "\nsrcDevice: " << srcDevice - << "\ndstDevice: " << dstDevice << "\nValue: " << value); + << "\ndstDevice: " << dstDevice + << "\nValue: " << value); if (attribute == hipDevP2PAttrPerformanceRank) { REQUIRE(value >= 0); } else { @@ -103,6 +121,7 @@ TEST_CASE("Unit_hipDeviceGetP2PAttribute_Basic") { * - Platform specific (NVIDIA) * - HIP_VERSION >= 5.2 */ + TEST_CASE("Unit_hipDeviceGetP2PAttribute_Negative") { #if HT_AMD HipTest::HIP_SKIP_TEST("EXSWCPHIPT-122"); @@ -121,22 +140,22 @@ TEST_CASE("Unit_hipDeviceGetP2PAttribute_Negative") { hipDeviceP2PAttr validAttr = hipDevP2PAttrAccessSupported; SECTION("Nullptr value") { - HIP_CHECK_ERROR(hipDeviceGetP2PAttribute(nullptr, validAttr, validSrcDevice, validDstDevice), - hipErrorInvalidValue); + HIP_CHECK_ERROR(hipDeviceGetP2PAttribute(nullptr, validAttr, + validSrcDevice, validDstDevice), hipErrorInvalidValue); } SECTION("Invalid attribute") { hipDeviceP2PAttr invalidAttr = static_cast(10); - HIP_CHECK_ERROR(hipDeviceGetP2PAttribute(&value, invalidAttr, validSrcDevice, validDstDevice), - hipErrorInvalidValue); + HIP_CHECK_ERROR(hipDeviceGetP2PAttribute(&value, invalidAttr, + validSrcDevice, validDstDevice), hipErrorInvalidValue); } SECTION("Device is -1") { int invalidDevice = -1; - HIP_CHECK_ERROR(hipDeviceGetP2PAttribute(&value, validAttr, invalidDevice, validDstDevice), - hipErrorInvalidDevice); - HIP_CHECK_ERROR(hipDeviceGetP2PAttribute(&value, validAttr, validSrcDevice, invalidDevice), - hipErrorInvalidDevice); + HIP_CHECK_ERROR(hipDeviceGetP2PAttribute(&value, validAttr, + invalidDevice, validDstDevice), hipErrorInvalidDevice); + HIP_CHECK_ERROR(hipDeviceGetP2PAttribute(&value, validAttr, + validSrcDevice, invalidDevice), hipErrorInvalidDevice); } SECTION("Device is out of bounds") { @@ -144,34 +163,34 @@ TEST_CASE("Unit_hipDeviceGetP2PAttribute_Negative") { HIP_CHECK(hipGetDeviceCount(&deviceCount)); REQUIRE_FALSE(deviceCount == 0); - HIP_CHECK_ERROR(hipDeviceGetP2PAttribute(&value, validAttr, deviceCount, validDstDevice), - hipErrorInvalidDevice); - HIP_CHECK_ERROR(hipDeviceGetP2PAttribute(&value, validAttr, validSrcDevice, deviceCount), - hipErrorInvalidDevice); + HIP_CHECK_ERROR(hipDeviceGetP2PAttribute(&value, validAttr, + deviceCount, validDstDevice), hipErrorInvalidDevice); + HIP_CHECK_ERROR(hipDeviceGetP2PAttribute(&value, validAttr, + validSrcDevice, deviceCount), hipErrorInvalidDevice); } SECTION("Source and destination devices are the same") { - HIP_CHECK_ERROR(hipDeviceGetP2PAttribute(&value, validAttr, validSrcDevice, validSrcDevice), - hipErrorInvalidDevice); + HIP_CHECK_ERROR(hipDeviceGetP2PAttribute(&value, validAttr, + validSrcDevice, validSrcDevice), hipErrorInvalidDevice); } - /* https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#env-vars */ + // https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#env-vars SECTION("Hidden devices using environment variables") { - REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("") == hipSuccess); - REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("0") == hipErrorInvalidDevice); - REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("1") == hipErrorInvalidDevice); - REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("0,1") == hipSuccess); - REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("-1,0") == hipErrorNoDevice); - REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("0,-1") == hipErrorInvalidDevice); - REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("0,1,-1") == hipSuccess); - REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("0,-1,1") == hipErrorInvalidDevice); + REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("") == hipSuccess); // NOLINT + REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("0") == hipErrorInvalidDevice); // NOLINT + REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("1") == hipErrorInvalidDevice); // NOLINT + REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("0,1") == hipSuccess); // NOLINT + REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("-1,0") == hipErrorNoDevice); // NOLINT + REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("0,-1") == hipErrorInvalidDevice); // NOLINT + REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("0,1,-1") == hipSuccess); // NOLINT + REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("0,-1,1") == hipErrorInvalidDevice); // NOLINT if (deviceCount > 2) { - REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("2,1") == hipSuccess); - REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("2") == hipErrorInvalidDevice); + REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("2,1") == hipSuccess); // NOLINT + REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("2") == hipErrorInvalidDevice); // NOLINT } else { - REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("2,1") == hipErrorNoDevice); + REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute_exe").run("2,1") == hipErrorNoDevice); // NOLINT } } #endif -} \ No newline at end of file +} diff --git a/catch/unit/device/hipDeviceGetP2PAttribute_exe.cc b/catch/unit/p2p/hipDeviceGetP2PAttribute_exe.cc similarity index 100% rename from catch/unit/device/hipDeviceGetP2PAttribute_exe.cc rename to catch/unit/p2p/hipDeviceGetP2PAttribute_exe.cc diff --git a/catch/unit/p2p/hipP2pLinkTypeAndHopFunc.cc b/catch/unit/p2p/hipP2pLinkTypeAndHopFunc.cc new file mode 100644 index 0000000000..2aade21ad3 --- /dev/null +++ b/catch/unit/p2p/hipP2pLinkTypeAndHopFunc.cc @@ -0,0 +1,351 @@ +/* +Copyright (c) 2023 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. +*/ + +#include "hipP2pLinkTypeAndHopFunc.h" +#include +#include +#include +#include +#ifdef __linux__ +#include +#include +#include +#endif +#include +#define MAX_SIZE 30 +#define VISIBLE_DEVICE 0 + +/** + * Fetches Gpu device count + */ +#ifdef __linux__ +void getDeviceCount(int *pdevCnt) { + int fd[2], val = 0; + pid_t childpid; + // create pipe descriptors + pipe(fd); + // disable visible_devices env from shell + unsetenv("ROCR_VISIBLE_DEVICES"); + unsetenv("HIP_VISIBLE_DEVICES"); + + childpid = fork(); + if (childpid > 0) { // Parent + close(fd[1]); + // parent will wait to read the device cnt + read(fd[0], &val, sizeof(val)); + // close the read-descriptor + close(fd[0]); + // wait for child exit + wait(NULL); + *pdevCnt = val; + } else if (!childpid) { // Child + int devCnt = 1; + // writing only, no need for read-descriptor + close(fd[0]); + HIP_CHECK(hipGetDeviceCount(&devCnt)); + // send the value on the write-descriptor: + write(fd[1], &devCnt, sizeof(devCnt)); + // close the write descriptor: + close(fd[1]); + exit(0); + } else { // failure + *pdevCnt = 1; + return; + } +} + +bool testMaskedDevice(int actualNumGPUs) { + bool testResult = true; + int fd[2]; + pipe(fd); + + pid_t cPid; + cPid = fork(); + if (cPid == 0) { // child + hipError_t err; + char visibleDeviceString[MAX_SIZE] = {}; + snprintf(visibleDeviceString, MAX_SIZE, "%d", VISIBLE_DEVICE); + // disable visible_devices env from shell + unsetenv("ROCR_VISIBLE_DEVICES"); + unsetenv("HIP_VISIBLE_DEVICES"); + setenv("ROCR_VISIBLE_DEVICES", visibleDeviceString, 1); + setenv("HIP_VISIBLE_DEVICES", visibleDeviceString, 1); + uint32_t linktype; + uint32_t hopcount; + for (int count = 1; + count < actualNumGPUs; count++) { + err = hipExtGetLinkTypeAndHopCount(VISIBLE_DEVICE, + VISIBLE_DEVICE+count, &linktype, &hopcount); + REQUIRE(err == hipSuccess); + } + close(fd[0]); + write(fd[1], &testResult, sizeof(testResult)); + close(fd[1]); + exit(0); + + } else if (cPid > 0) { // parent + close(fd[1]); + read(fd[0], &testResult, sizeof(testResult)); + close(fd[0]); + wait(NULL); + + } else { + printf("Info:fork() failed\n"); + testResult = false; + } + return testResult; +} +#endif + +bool testhipInvalidDevice(int numDevices) { + hipError_t ret; + uint32_t linktype; + uint32_t hopcount; + SECTION("Invalid device number case 1") { + ret = hipExtGetLinkTypeAndHopCount(-1, 0, &linktype, &hopcount); + REQUIRE(ret != hipSuccess); + } + SECTION("Invalid device number case 2") { + ret = hipExtGetLinkTypeAndHopCount(numDevices, 0, &linktype, &hopcount); + REQUIRE(ret != hipSuccess); + } + SECTION("Invalid device number case 3") { + ret = hipExtGetLinkTypeAndHopCount(0, -1, &linktype, &hopcount); + REQUIRE(ret != hipSuccess); + } + SECTION("Invalid device number case 4") { + ret = hipExtGetLinkTypeAndHopCount(0, numDevices, &linktype, &hopcount); + REQUIRE(ret != hipSuccess); + } + SECTION("Invalid device number case 5") { + ret = hipExtGetLinkTypeAndHopCount(-1, numDevices, &linktype, &hopcount); + REQUIRE(ret != hipSuccess); + } + return true; +} + +#ifdef __linux__ +bool testhipInvalidLinkType() { + uint32_t hopcount; + REQUIRE(hipSuccess != hipExtGetLinkTypeAndHopCount(0, 1, nullptr, + &hopcount)); + return true; +} + +bool testhipInvalidHopcount() { + uint32_t linktype; + REQUIRE(hipSuccess != hipExtGetLinkTypeAndHopCount(0, 1, &linktype, nullptr)); + return true; +} + +bool testhipSameDevice(int numGPUs) { + hipError_t ret; + uint32_t linktype = 0; + uint32_t hopcount = 0; + for (int gpuId = 0; gpuId < numGPUs; gpuId++) { + ret = hipExtGetLinkTypeAndHopCount(gpuId, gpuId, &linktype, &hopcount); + REQUIRE(ret != hipSuccess); + } + return true; +} + +bool testhipLinkTypeHopcountDeviceOrderRev(int numDevices) { + bool TestPassed = true; + // Get the unique pair of devices + for (int x = 0; x < numDevices; x++) { + for (int y = x+1; y < numDevices; y++) { + uint32_t linktype1 = 0, linktype2 = 0; + uint32_t hopcount1 = 0, hopcount2 = 0; + HIP_CHECK(hipExtGetLinkTypeAndHopCount(x, y, + &linktype1, &hopcount1)); + HIP_CHECK(hipExtGetLinkTypeAndHopCount(y, x, + &linktype2, &hopcount2)); + if (hopcount1 != hopcount2) { + TestPassed = false; + break; + } + } + } + return TestPassed; +} + +/** + * Internal Function + */ +bool validateLinkType(uint32_t linktype_Hip, + RSMI_IO_LINK_TYPE linktype_RocmSmi) { + bool TestPassed = false; + + if ((linktype_Hip == HSA_AMD_LINK_INFO_TYPE_PCIE) && + (linktype_RocmSmi == RSMI_IOLINK_TYPE_PCIEXPRESS)) { + TestPassed = true; + } else if ((linktype_Hip == HSA_AMD_LINK_INFO_TYPE_XGMI) && + (linktype_RocmSmi == RSMI_IOLINK_TYPE_XGMI)) { + TestPassed = true; + } else { + printf("linktype Hip = %u, linktype RocmSmi = %u\n", + linktype_Hip, linktype_RocmSmi); + TestPassed = false; + } + return TestPassed; +} + +bool testhipLinkTypeHopcountDevice(int numDevices) { + bool TestPassed = true; + // Opening and initializing rocm-smi library + void *lib_rocm_smi_hdl; + rsmi_status_t (*fntopo_get_link_type)(uint32_t, uint32_t, uint64_t*, + RSMI_IO_LINK_TYPE*); + rsmi_status_t (*fntopo_init)(uint64_t); + rsmi_status_t (*fntopo_shut_down)(); + + lib_rocm_smi_hdl = dlopen("/opt/rocm/rocm_smi/lib/librocm_smi64.so", + RTLD_LAZY); + REQUIRE(lib_rocm_smi_hdl); + + void* fnsym = dlsym(lib_rocm_smi_hdl, "rsmi_topo_get_link_type"); + REQUIRE(fnsym); + + fntopo_get_link_type = reinterpret_cast(fnsym); + + fnsym = dlsym(lib_rocm_smi_hdl, "rsmi_init"); + REQUIRE(fnsym); + fntopo_init = reinterpret_cast(fnsym); + + fnsym = dlsym(lib_rocm_smi_hdl, "rsmi_shut_down"); + REQUIRE(fnsym); + fntopo_shut_down = reinterpret_cast(fnsym); + + uint64_t init_flags = 0; + rsmi_status_t retsmi_init; + retsmi_init = fntopo_init(init_flags); + REQUIRE(RSMI_STATUS_SUCCESS == retsmi_init); + + // Use rocm-smi API rsmi_topo_get_link_type() to validate + struct devicePair { + int device1; + int device2; + }; + std::vector devicePairList; + // Get the unique pair of devices + for (int x = 0; x < numDevices; x++) { + for (int y = x+1; y < numDevices; y++) { + devicePairList.push_back({x, y}); + } + } + for (auto pos=devicePairList.begin(); + pos != devicePairList.end(); pos++) { + uint32_t linktype1 = 0; + uint32_t hopcount1 = 0; + RSMI_IO_LINK_TYPE linktype2 = RSMI_IOLINK_TYPE_UNDEFINED; + uint64_t hopcount2 = 0; + rsmi_status_t retsmi; + HIPCHECK(hipExtGetLinkTypeAndHopCount((*pos).device1, + (*pos).device2, &linktype1, &hopcount1)); + retsmi = fntopo_get_link_type((*pos).device1, + (*pos).device2, &hopcount2, &linktype2); + REQUIRE(RSMI_STATUS_SUCCESS == retsmi); + + // Validate linktype + TestPassed = validateLinkType(linktype1, linktype2); + } + fntopo_shut_down(); + dlclose(lib_rocm_smi_hdl); + return TestPassed; +} +#endif + +/** + * @addtogroup hipExtGetLinkTypeAndHopCount hipExtGetLinkTypeAndHopCount + * @{ + * @ingroup p2pTest + * `hipError_t hipExtGetLinkTypeAndHopCount(int device1, int device2, uint32_t* linktype, uint32_t* hopcount)` - + * Returns the link type and hop count between two devices + * @} + */ + +/** + * Test Description + * ------------------------ + * - Validates negative scenarios for hipExtGetLinkTypeAndHopCount + * 1)Test Scenario to verify when device1 is visible and device2 is masked + * 2)Test Scenario to verify Invalid Device Number(s) + * 3)Test Scenario to verify when linktype = NULL + * 4)Test Scenario to verify when hopcount = NULL + * 5)Test Scenario to verify when device1 = device2 + * 6)Test Scenario: Verify (hopcount, linktype) values for (src= device1, dest = device2) + * and (src = device2, dest = device1), where device1 and device2 are valid device numbers. + * 7)Test Scenario: Verify (hopcount, linktype) values for all combination of + * GPUs with the output of rocm_smi tool. + + * Test source + * ------------------------ + * - catch/unit/p2p/hipExtGetLinkTypeAndHopCount.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.5 + */ + +TEST_CASE("Unit_hipP2pLinkTypeAndHopFunc") { + int numDevices = 0; + bool TestPassed = true; + HIP_CHECK(hipGetDeviceCount(&numDevices)); + if (numDevices < 2) { + HipTest::HIP_SKIP_TEST("Skipping because devices < 2"); + return; + } + SECTION("Test running for testhipInvalidDevice") { + TestPassed = testhipInvalidDevice(numDevices); + REQUIRE(TestPassed == true); + } +#ifdef __linux__ + getDeviceCount(&numDevices); + if (numDevices < 2) { + HipTest::HIP_SKIP_TEST("Skipping because devices < 2"); + return; + } + SECTION("Test running for testMaskedDevice") { + TestPassed = testMaskedDevice(numDevices); + REQUIRE(TestPassed == true); + } + SECTION("Test running for testhipInvalidLinkType") { + TestPassed = testhipInvalidLinkType(); + REQUIRE(TestPassed == true); + } + SECTION("Test running for testhipInvalidHopcount") { + TestPassed = testhipInvalidHopcount(); + REQUIRE(TestPassed == true); + } + SECTION("Test running for testhipSameDevice") { + TestPassed = testhipSameDevice(numDevices); + REQUIRE(TestPassed == true); + } + SECTION("Test running for testhipLinkTypeHopcountDeviceOrderRev") { + TestPassed = testhipLinkTypeHopcountDeviceOrderRev(numDevices); + REQUIRE(TestPassed == true); + } + SECTION("Test running for testhipLinkTypeHopcountDevice") { + TestPassed = testhipLinkTypeHopcountDevice(numDevices); + REQUIRE(TestPassed == true); + } +#else + printf("This test is skipped due to non linux environment.\n"); +#endif +} diff --git a/catch/unit/p2p/hipP2pLinkTypeAndHopFunc.h b/catch/unit/p2p/hipP2pLinkTypeAndHopFunc.h new file mode 100644 index 0000000000..755743c328 --- /dev/null +++ b/catch/unit/p2p/hipP2pLinkTypeAndHopFunc.h @@ -0,0 +1,110 @@ +/* +Copyright (c) 2023 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. +*/ + +#ifndef _HIP_DIRTEST_P2PLINKTYPEHOP_H_ +#define _HIP_DIRTEST_P2PLINKTYPEHOP_H_ +/** + * rocm_smi.h enums + */ +typedef enum { + RSMI_STATUS_SUCCESS = 0x0, //!< Operation was successful + RSMI_STATUS_INVALID_ARGS, //!< Passed in arguments are not valid + RSMI_STATUS_NOT_SUPPORTED, //!< The requested information or + //!< action is not available for the + //!< given input, on the given system + RSMI_STATUS_FILE_ERROR, //!< Problem accessing a file. This + //!< may because the operation is not + //!< supported by the Linux kernel + //!< version running on the executing + //!< machine + RSMI_STATUS_PERMISSION, //!< Permission denied/EACCESS file + //!< error. Many functions require + //!< root access to run. + RSMI_STATUS_OUT_OF_RESOURCES, //!< Unable to acquire memory or other + //!< resource + RSMI_STATUS_INTERNAL_EXCEPTION, //!< An internal exception was caught + RSMI_STATUS_INPUT_OUT_OF_BOUNDS, //!< The provided input is out of + //!< allowable or safe range + RSMI_STATUS_INIT_ERROR, //!< An error occurred when rsmi + //!< initializing internal data + //!< structures + RSMI_INITIALIZATION_ERROR = RSMI_STATUS_INIT_ERROR, + RSMI_STATUS_NOT_YET_IMPLEMENTED, //!< The requested function has not + //!< yet been implemented in the + //!< current system for the current + //!< devices + RSMI_STATUS_NOT_FOUND, //!< An item was searched for but not + //!< found + RSMI_STATUS_INSUFFICIENT_SIZE, //!< Not enough resources were + //!< available for the operation + RSMI_STATUS_INTERRUPT, //!< An interrupt occurred during + //!< execution of function + RSMI_STATUS_UNEXPECTED_SIZE, //!< An unexpected amount of data + //!< was read + RSMI_STATUS_NO_DATA, //!< No data was found for a given + //!< input + RSMI_STATUS_UNEXPECTED_DATA, //!< The data read or provided to + //!< function is not what was expected + RSMI_STATUS_BUSY, //!< A resource or mutex could not be + //!< acquired because it is already + //!< being used + RSMI_STATUS_REFCOUNT_OVERFLOW, //!< An internal reference counter + //!< exceeded INT32_MAX + + RSMI_STATUS_UNKNOWN_ERROR = 0xFFFFFFFF, //!< An unknown error occurred +} rsmi_status_t; + +/** + * Types for IO Link returned from rocm_smi + */ +typedef enum _RSMI_IO_LINK_TYPE { + RSMI_IOLINK_TYPE_UNDEFINED = 0, //!< unknown type. + RSMI_IOLINK_TYPE_PCIEXPRESS = 1, //!< PCI Express + RSMI_IOLINK_TYPE_XGMI = 2, //!< XGMI + RSMI_IOLINK_TYPE_NUMIOLINKTYPES, //!< Number of IO Link types + RSMI_IOLINK_TYPE_SIZE = 0xFFFFFFFF //!< Max of IO Link types +} RSMI_IO_LINK_TYPE; + +/** + * Types for IO Link returned from rocm runtime + */ +typedef enum { + /** + * Hyper-transport bus type. + */ + HSA_AMD_LINK_INFO_TYPE_HYPERTRANSPORT = 0, + /** + * QPI bus type. + */ + HSA_AMD_LINK_INFO_TYPE_QPI = 1, + /** + * PCIe bus type. + */ + HSA_AMD_LINK_INFO_TYPE_PCIE = 2, + /** + * Infiniband bus type. + */ + HSA_AMD_LINK_INFO_TYPE_INFINBAND = 3, + /** + * xGMI link type. + */ + HSA_AMD_LINK_INFO_TYPE_XGMI = 4 +} hsa_amd_link_info_type_t; + +#endif // _HIP_DIRTEST_P2PLINKTYPEHOP_H_