diff --git a/tests/catch/hipTestMain/config/config_amd_linux_MI2xx.json b/tests/catch/hipTestMain/config/config_amd_linux_MI2xx.json index 05276e392b..da05aeb2e7 100644 --- a/tests/catch/hipTestMain/config/config_amd_linux_MI2xx.json +++ b/tests/catch/hipTestMain/config/config_amd_linux_MI2xx.json @@ -2,7 +2,8 @@ "DisabledTests": [ "Unit_hipStreamPerThread_DeviceReset_1", - "Unit_hipMallocManaged_OverSubscription" + "Unit_hipMallocManaged_OverSubscription", + "Unit_hipDeviceGetPCIBusId_Negative_PartialFill" ] } diff --git a/tests/catch/hipTestMain/config/config_amd_linux_common.json b/tests/catch/hipTestMain/config/config_amd_linux_common.json index 8b8c42fcd4..2a857c27d0 100644 --- a/tests/catch/hipTestMain/config/config_amd_linux_common.json +++ b/tests/catch/hipTestMain/config/config_amd_linux_common.json @@ -4,6 +4,9 @@ "Unit_hipStreamPerThread_DeviceReset_1", "Unit_hipMallocManaged_OverSubscription", "Unit_hipDeviceGetCacheConfig_Positive_Basic", - "Unit_hipDeviceGetCacheConfig_Positive_Threaded" + "Unit_hipDeviceGetCacheConfig_Positive_Threaded", + "Unit_hipGetDeviceFlags_Positive_Context", + "Unit_hipIpcCloseMemHandle_Negative_Close_In_Originating_Process", + "Unit_hipDeviceGetPCIBusId_Negative_PartialFill" ] } diff --git a/tests/catch/hipTestMain/config/config_amd_windows_MI2xx.json b/tests/catch/hipTestMain/config/config_amd_windows_MI2xx.json index 013f7c67d8..317bef4a9a 100644 --- a/tests/catch/hipTestMain/config/config_amd_windows_MI2xx.json +++ b/tests/catch/hipTestMain/config/config_amd_windows_MI2xx.json @@ -88,6 +88,7 @@ "Unit_hipStreamValue_Wait64_Blocking_NoMask_Gte", "Unit_hipStreamValue_Wait64_Blocking_NoMask_Eq", "Unit_hipStreamValue_Wait64_Blocking_NoMask_And", - "Unit_hipStreamValue_Wait64_Blocking_NoMask_Nor" + "Unit_hipStreamValue_Wait64_Blocking_NoMask_Nor", + "Unit_hipDeviceGetPCIBusId_Negative_PartialFill" ] } diff --git a/tests/catch/hipTestMain/config/config_amd_windows_common.json b/tests/catch/hipTestMain/config/config_amd_windows_common.json index 2094761dc2..3c8570f63d 100644 --- a/tests/catch/hipTestMain/config/config_amd_windows_common.json +++ b/tests/catch/hipTestMain/config/config_amd_windows_common.json @@ -97,6 +97,9 @@ "Unit_hipStreamValue_Wait64_Blocking_NoMask_Gte", "Unit_hipStreamValue_Wait64_Blocking_NoMask_Eq", "Unit_hipStreamValue_Wait64_Blocking_NoMask_And", - "Unit_hipStreamValue_Wait64_Blocking_NoMask_Nor" + "Unit_hipStreamValue_Wait64_Blocking_NoMask_Nor", + "Unit_hipGetDeviceFlags_Positive_Context", + "Unit_hipIpcCloseMemHandle_Negative_Close_In_Originating_Process", + "Unit_hipDeviceGetPCIBusId_Negative_PartialFill" ] } diff --git a/tests/catch/multiproc/hipIpcEventHandle.cc b/tests/catch/multiproc/hipIpcEventHandle.cc index 78b12bdff3..440b00f598 100644 --- a/tests/catch/multiproc/hipIpcEventHandle.cc +++ b/tests/catch/multiproc/hipIpcEventHandle.cc @@ -321,6 +321,10 @@ TEST_CASE("Unit_hipIpcEventHandle_ParameterValidation") { REQUIRE(ret == hipErrorInvalidValue); } + SECTION("Get event handle with handle == nullptr and event == nullptr") { + HIP_CHECK_ERROR(hipIpcGetEventHandle(nullptr, nullptr), hipErrorInvalidValue); + } + SECTION("Get event handle with invalid event object") { hipEvent_t eventUninit{}; ret = hipIpcGetEventHandle(&eventHandle, eventUninit); @@ -354,6 +358,27 @@ TEST_CASE("Unit_hipIpcEventHandle_ParameterValidation") { REQUIRE(false); } } + + SECTION("Open handle in process that created it") { + hipIpcEventHandle_t event_handle; + hipEvent_t event1, event2; + HIP_CHECK(hipEventCreateWithFlags(&event1, hipEventDisableTiming | hipEventInterprocess)); + HIP_CHECK(hipIpcGetEventHandle(&event_handle, event1)); + HIP_CHECK_ERROR(hipIpcOpenEventHandle(&event2, event_handle), hipErrorInvalidContext); + HIP_CHECK(hipEventDestroy(event1)); + } + +// Disabled on AMD because of return value mismatch - EXSWHTEC-41 +#if HT_NVIDIA + SECTION("Event created with no flags") { + hipEvent_t event; + hipIpcEventHandle_t event_handle; + + HIP_CHECK(hipEventCreate(&event)); + HIP_CHECK_ERROR(hipIpcGetEventHandle(&event_handle, event), hipErrorInvalidResourceHandle); + HIP_CHECK(hipEventDestroy(event)); + } +#endif } #endif diff --git a/tests/catch/unit/device/CMakeLists.txt b/tests/catch/unit/device/CMakeLists.txt index ce00c290e5..4b98e35fb0 100644 --- a/tests/catch/unit/device/CMakeLists.txt +++ b/tests/catch/unit/device/CMakeLists.txt @@ -25,6 +25,11 @@ set(TEST_SRC hipDeviceSetGetMemPool.cc ) +if(UNIX) + set(TEST_SRC ${TEST_SRC} + hipIpcCloseMemHandle.cc) +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) diff --git a/tests/catch/unit/device/hipDeviceComputeCapability.cc b/tests/catch/unit/device/hipDeviceComputeCapability.cc index d925594988..a44bfeae1b 100644 --- a/tests/catch/unit/device/hipDeviceComputeCapability.cc +++ b/tests/catch/unit/device/hipDeviceComputeCapability.cc @@ -16,6 +16,12 @@ LIABILITY, WHETHER INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/* +Testcase Scenarios : +Unit_hipDeviceComputeCapability_ValidateVersion - Check if hipDeviceComputeCapability api returns valid Major and Minor versions +Unit_hipDeviceComputeCapability_Negative - Test unsuccessful execution of hipDeviceComputeCapability when nullptr + or invalid device is set as input parameter +*/ /* * Conformance test for checking functionality of @@ -24,14 +30,13 @@ THE SOFTWARE. #include /** - * hipDeviceComputeCapability tests + * hipDeviceComputeCapability negative tests * Scenario1: Validates if &major = nullptr returns error code * Scenario2: Validates if &minor = nullptr returns error code - * Scenario3: Check if Major and Minor Versions are valid + * Scenario3: Validates if device is -1 + * Scenario4: Validates if device is out of bounds */ - -// Scenario 1 and 2 -TEST_CASE("Unit_hipDeviceComputeCapability_NegTst") { +TEST_CASE("Unit_hipDeviceComputeCapability_Negative") { int major, minor, numDevices; hipDevice_t device; @@ -51,12 +56,22 @@ TEST_CASE("Unit_hipDeviceComputeCapability_NegTst") { REQUIRE_FALSE(hipDeviceComputeCapability(&major, nullptr, device) == hipSuccess); } + // Scenario3 + SECTION("device is -1") { + REQUIRE_FALSE(hipDeviceComputeCapability(&major, &minor, -1) + == hipSuccess); + } + // Scenario4 + SECTION("device is out of bounds") { + REQUIRE_FALSE(hipDeviceComputeCapability(&major, &minor, numDevices) + == hipSuccess); + } } else { WARN("Test skipped as no gpu devices available"); } } -// Scenario 3 : Check whether major and minor version value is valid. +// Scenario 5 : Check whether major and minor version value is valid. TEST_CASE("Unit_hipDeviceComputeCapability_ValidateVersion") { int major, minor; hipDevice_t device; diff --git a/tests/catch/unit/device/hipDeviceGetP2PAttribute.cc b/tests/catch/unit/device/hipDeviceGetP2PAttribute.cc index 805eb117ff..584257e616 100644 --- a/tests/catch/unit/device/hipDeviceGetP2PAttribute.cc +++ b/tests/catch/unit/device/hipDeviceGetP2PAttribute.cc @@ -96,7 +96,7 @@ TEST_CASE("Unit_hipDeviceGetP2PAttribute_Negative") { hipErrorInvalidValue); } - SECTION("Invalid device") { + SECTION("Device is -1") { int invalidDevice = -1; HIP_CHECK_ERROR(hipDeviceGetP2PAttribute(&value, validAttr, invalidDevice, validDstDevice), hipErrorInvalidDevice); @@ -104,6 +104,22 @@ TEST_CASE("Unit_hipDeviceGetP2PAttribute_Negative") { hipErrorInvalidDevice); } + SECTION("Device is out of bounds") { + int deviceCount = 0; + 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); + } + + SECTION("Source and destination devices are the same") { + HIP_CHECK_ERROR(hipDeviceGetP2PAttribute(&value, validAttr, validSrcDevice, validSrcDevice), + hipErrorInvalidDevice); + } + /* https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#env-vars */ SECTION("Hidden devices using environment variables") { REQUIRE(hip::SpawnProc("hipDeviceGetP2PAttribute").run("") == hipSuccess); diff --git a/tests/catch/unit/device/hipDeviceGetPCIBusId.cc b/tests/catch/unit/device/hipDeviceGetPCIBusId.cc index d070f8654b..4f82a59b0e 100644 --- a/tests/catch/unit/device/hipDeviceGetPCIBusId.cc +++ b/tests/catch/unit/device/hipDeviceGetPCIBusId.cc @@ -71,6 +71,30 @@ TEST_CASE("Unit_hipDeviceGetPCIBusId_Check_PciBusID_WithAttr") { " hipDeviceGetAttribute matched for all gpus\n"); } +TEST_CASE("Unit_hipDeviceGetPCIBusId_Negative_PartialFill") { + std::array busID; + + const int device = GENERATE(range(0, HipTest::getDeviceCount())); + + HIP_CHECK(hipDeviceGetPCIBusId(busID.data(), busID.size(), device)); + + auto start = std::begin(busID); + auto end = std::end(busID); + const auto len = std::distance(start, std::find(start, end, 0)); + + // fill up only half of the length + const auto fillLen = len / 2; + constexpr char fillValue = 1; + std::fill(start, end, fillValue); + + REQUIRE_FALSE(hipDeviceGetPCIBusId(busID.data(), fillLen, device) == hipSuccess); + + const auto strEnd = start + fillLen - 1; + REQUIRE(std::all_of(start, strEnd, [](char& c) { return c != 0; })); + REQUIRE(*strEnd == 0); + REQUIRE(std::all_of(strEnd+1, end, [](char& c) { return c == fillValue; })); +} + /** * Validates negative scenarios for hipDeviceGetPCIBusId @@ -107,7 +131,7 @@ TEST_CASE("Unit_hipDeviceGetPCIBusId_NegTst") { == hipSuccess); } // device = Non Existing Device - SECTION("device is -1") { + SECTION("device is out of bounds") { int deviceCount = 0; HIP_CHECK(hipGetDeviceCount(&deviceCount)); REQUIRE_FALSE(deviceCount == 0); diff --git a/tests/catch/unit/device/hipDeviceGetUuid.cc b/tests/catch/unit/device/hipDeviceGetUuid.cc index 512ddb6a2b..47a9bd2c4f 100644 --- a/tests/catch/unit/device/hipDeviceGetUuid.cc +++ b/tests/catch/unit/device/hipDeviceGetUuid.cc @@ -16,7 +16,12 @@ LIABILITY, WHETHER INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - +/* +Testcase Scenarios : +Unit_hipDeviceGetUuid_Positive - Check if hipDeviceGetUuid api returns valid UUID +Unit_hipDeviceGetUuid_Negative - Test unsuccessful execution of hipDeviceGetUuid when nullptr + or invalid device is set as input parameter +*/ /* * Conformance test for checking functionality of * hipError_t hipDeviceGetUuid(hipUUID* uuid, hipDevice_t device); @@ -26,26 +31,40 @@ THE SOFTWARE. #include /** - * hipDeviceGetUuid tests + * hipDeviceGetUuid positive test * Scenario1: Validates the returned UUID - * Scenario2: Validates returned error code for UUID = nullptr - * Scenario3 & 4: Validates returned error code for invalid device */ -TEST_CASE("Unit_hipDeviceGetUuid") { +TEST_CASE("Unit_hipDeviceGetUuid_Positive") { + hipDevice_t device; + hipUUID uuid; + + const int deviceId = GENERATE(range(0, HipTest::getDeviceCount())); + HIP_CHECK(hipDeviceGet(&device, deviceId)); + + // Scenario 1 + HIP_CHECK(hipDeviceGetUuid(&uuid, device)); + REQUIRE(strcmp(uuid.bytes, "") != 0); +} + +/** + * hipDeviceGetUuid negative tests + * Scenario2: Validates returned error code for UUID = nullptr + * Scenario3: Validates returned error code if device is -1 + * Scenario4: Validates returned error code if device is out of bounds + */ +TEST_CASE("Unit_hipDeviceGetUuid_Negative") { int numDevices = 0; hipDevice_t device; hipUUID uuid; HIP_CHECK(hipGetDeviceCount(&numDevices)); - for (int i = 0; i < numDevices; i++) { - HIP_CHECK(hipDeviceGet(&device, i)); - // Scenario 1 - HIP_CHECK(hipDeviceGetUuid(&uuid, device)); - REQUIRE_FALSE(!strcmp(uuid.bytes, "")); + + if (numDevices > 0) { + HIP_CHECK(hipDeviceGet(&device, 0)); // Scenario 2 REQUIRE_FALSE(hipSuccess == hipDeviceGetUuid(nullptr, device)); + // Scenario 3 + REQUIRE_FALSE(hipSuccess == hipDeviceGetUuid(&uuid, -1)); + // Scenario 4 + REQUIRE_FALSE(hipSuccess == hipDeviceGetUuid(&uuid, numDevices)); } - // Scenario 3 - REQUIRE_FALSE(hipSuccess == hipDeviceGetUuid(&uuid, -1)); - // Scenario 4 - REQUIRE_FALSE(hipSuccess == hipDeviceGetUuid(&uuid, numDevices)); } diff --git a/tests/catch/unit/device/hipDeviceTotalMem.cc b/tests/catch/unit/device/hipDeviceTotalMem.cc index 6812b37873..0a236d2feb 100644 --- a/tests/catch/unit/device/hipDeviceTotalMem.cc +++ b/tests/catch/unit/device/hipDeviceTotalMem.cc @@ -35,22 +35,21 @@ TEST_CASE("Unit_hipDeviceTotalMem_NegTst") { #if HT_NVIDIA HIP_CHECK(hipInit(0)); #endif + size_t totMem; // Scenario 1 SECTION("bytes is nullptr") { HIP_CHECK_ERROR(hipDeviceTotalMem(nullptr, 0), hipErrorInvalidValue); } - size_t totMem; // Scenario 2 SECTION("device is -1") { HIP_CHECK_ERROR(hipDeviceTotalMem(&totMem, -1), hipErrorInvalidDevice); } // Scenario 3 - SECTION("pi is nullptr") { + SECTION("device is out of bounds") { int numDevices; HIP_CHECK(hipGetDeviceCount(&numDevices)); - size_t totMem; HIP_CHECK_ERROR(hipDeviceTotalMem(&totMem, numDevices), hipErrorInvalidDevice); } } diff --git a/tests/catch/unit/device/hipGetSetDeviceFlags.cc b/tests/catch/unit/device/hipGetSetDeviceFlags.cc index c134a21ad0..c661f4e7ba 100644 --- a/tests/catch/unit/device/hipGetSetDeviceFlags.cc +++ b/tests/catch/unit/device/hipGetSetDeviceFlags.cc @@ -145,3 +145,22 @@ TEST_CASE("Unit_hipGetSetDeviceFlags_Threaded") { test_thread.join(); HIP_CHECK_THREAD_FINALIZE(); } + +TEST_CASE("Unit_hipGetDeviceFlags_Positive_Context") { + auto validFlags = getValidFlags(); + const unsigned int flags = + GENERATE_COPY(from_range(std::begin(validFlags), std::end(validFlags))); + + HIP_CHECK(hipInit(0)); + + hipCtx_t ctx; + HIP_CHECK(hipCtxCreate(&ctx, flags, 0)); + + unsigned int actual_flags; + HIP_CHECK(hipGetDeviceFlags(&actual_flags)); + + REQUIRE(actual_flags == flags); + + HIP_CHECK(hipCtxPopCurrent(&ctx)); + HIP_CHECK(hipCtxDestroy(ctx)); +} \ No newline at end of file diff --git a/tests/catch/unit/device/hipIpcCloseMemHandle.cc b/tests/catch/unit/device/hipIpcCloseMemHandle.cc new file mode 100644 index 0000000000..138ef15e5d --- /dev/null +++ b/tests/catch/unit/device/hipIpcCloseMemHandle.cc @@ -0,0 +1,91 @@ +/* +Copyright (c) 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. +*/ + +#include +#include +#include + +#include +#include + +TEST_CASE("Unit_hipIpcCloseMemHandle_Positive_Reference_Counting") { + int fd[2]; + REQUIRE(pipe(fd) == 0); + + // The fork must be performed before the runtime is initialized(so before any API that implicitly + // initializes it). The pipe in conjunction with wait is then used to impose total ordering + // between parent and child process. Because total ordering is imposed regular CATCH assertions + // should be safe to use + auto pid = fork(); + REQUIRE(pid >= 0); + if (pid == 0) { // child + REQUIRE(close(fd[1]) == 0); + + hipIpcMemHandle_t handle; + REQUIRE(read(fd[0], &handle, sizeof(handle)) >= 0); + REQUIRE(close(fd[0]) == 0); + + void *child_ptr1, *child_ptr2; + HIP_CHECK(hipIpcOpenMemHandle(&child_ptr1, handle, hipIpcMemLazyEnablePeerAccess)); + HIP_CHECK(hipIpcOpenMemHandle(&child_ptr2, handle, hipIpcMemLazyEnablePeerAccess)); + + REQUIRE(child_ptr1 == child_ptr2); + + HIP_CHECK(hipIpcCloseMemHandle(child_ptr1)); + hipPointerAttribute_t attributes; + HIP_CHECK(hipPointerGetAttributes(&attributes, child_ptr1)); + HIP_CHECK(hipPointerGetAttributes(&attributes, child_ptr2)); + + HIP_CHECK(hipIpcCloseMemHandle(child_ptr2)); + HIP_CHECK_ERROR(hipPointerGetAttributes(&attributes, child_ptr1), hipErrorInvalidValue); + HIP_CHECK_ERROR(hipPointerGetAttributes(&attributes, child_ptr2), hipErrorInvalidValue); + + exit(0); + } else { // parent + REQUIRE(close(fd[0]) == 0); + + void* ptr; + hipIpcMemHandle_t handle; + HIP_CHECK(hipMalloc(&ptr, 1024)); + HIP_CHECK(hipIpcGetMemHandle(&handle, ptr)); + + REQUIRE(write(fd[1], &handle, sizeof(handle)) >= 0); + REQUIRE(close(fd[1]) == 0); + + REQUIRE(wait(NULL) >= 0); + + hipPointerAttribute_t attributes; + HIP_CHECK(hipPointerGetAttributes(&attributes, ptr)); + + HIP_CHECK(hipFree(ptr)); + } +} + +TEST_CASE("Unit_hipIpcCloseMemHandle_Negative_Close_In_Originating_Process") { + void* ptr; + hipIpcMemHandle_t handle; + HIP_CHECK(hipMalloc(&ptr, 1024)); + HIP_CHECK(hipIpcGetMemHandle(&handle, ptr)); + + HIP_CHECK_ERROR(hipIpcCloseMemHandle(ptr), hipErrorInvalidValue); + HIP_CHECK(hipFree(ptr)); +} \ No newline at end of file diff --git a/tests/catch/unit/device/hipRuntimeGetVersion.cc b/tests/catch/unit/device/hipRuntimeGetVersion.cc index 3420316e0d..6e0def63b7 100644 --- a/tests/catch/unit/device/hipRuntimeGetVersion.cc +++ b/tests/catch/unit/device/hipRuntimeGetVersion.cc @@ -16,6 +16,11 @@ LIABILITY, WHETHER INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/* +Testcase Scenarios : +Unit_hipRuntimeGetVersion_Positive - Test simple reading of HIP runtime version with hipRuntimeGetVersion api +Unit_hipRuntimeGetVersion_Negative - Test unsuccessful execution of hipRuntimeGetVersion when nullptr is set as input parameter +*/ /* * Conformance test for checking functionality of @@ -26,9 +31,14 @@ THE SOFTWARE. */ #include -TEST_CASE("Unit_hipRuntimeGetVersion_NegAndValTst") { +TEST_CASE("Unit_hipRuntimeGetVersion_Positive") { int runtimeVersion = -1; - CHECK_FALSE(hipRuntimeGetVersion(nullptr) == hipSuccess); HIP_CHECK(hipRuntimeGetVersion(&runtimeVersion)); - CHECK_FALSE(runtimeVersion <= 0); + REQUIRE(runtimeVersion > 0); + INFO("Runtime version " << runtimeVersion); +} + +TEST_CASE("Unit_hipRuntimeGetVersion_Negative") { + // If initialization is attempted with nullptr, error shall be reported + CHECK_FALSE(hipRuntimeGetVersion(nullptr) == hipSuccess); }