From 1bb4348c3b67c4b21982c4d963cc8659a99129bb Mon Sep 17 00:00:00 2001 From: milos-mozetic <118800401+milos-mozetic@users.noreply.github.com> Date: Sat, 8 Jul 2023 17:20:41 +0200 Subject: [PATCH 01/25] EXSWHTEC-224 - Test cases ID clean up and documentation for Execution Control (#85) - Test cases ID clean up and documentation for Execution Control - Update config_nvidia_linux_common.json - Disable test which failed on external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/85 [ROCm/hip-tests commit: e103027f81ba8923b4bf8d0c9f06e08d551953e2] --- .../config/config_amd_linux_common.json | 13 + .../config/config_amd_windows_common.json | 13 + .../config/config_nvidia_linux_common.json | 11 + .../config/config_nvidia_windows_common.json | 9 + .../catch/include/hip_test_defgroups.hh | 7 + projects/hip-tests/catch/unit/CMakeLists.txt | 1 + .../unit/executionControl/CMakeLists.txt | 11 + .../execution_control_common.cc | 27 ++ .../execution_control_common.hh | 25 ++ .../executionControl/hipFuncSetAttribute.cc | 260 ++++++++++++++++++ .../executionControl/hipFuncSetCacheConfig.cc | 105 +++++++ .../hipFuncSetSharedMemConfig.cc | 106 +++++++ 12 files changed, 588 insertions(+) create mode 100644 projects/hip-tests/catch/hipTestMain/config/config_nvidia_linux_common.json create mode 100644 projects/hip-tests/catch/hipTestMain/config/config_nvidia_windows_common.json create mode 100644 projects/hip-tests/catch/unit/executionControl/CMakeLists.txt create mode 100644 projects/hip-tests/catch/unit/executionControl/execution_control_common.cc create mode 100644 projects/hip-tests/catch/unit/executionControl/execution_control_common.hh create mode 100644 projects/hip-tests/catch/unit/executionControl/hipFuncSetAttribute.cc create mode 100644 projects/hip-tests/catch/unit/executionControl/hipFuncSetCacheConfig.cc create mode 100644 projects/hip-tests/catch/unit/executionControl/hipFuncSetSharedMemConfig.cc diff --git a/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json b/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json index b9c0e7c79f..9704e80d49 100644 --- a/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json +++ b/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json @@ -13,6 +13,19 @@ "Unit_hipInit_Negative", "Unit_hipDeviceReset_Positive_Basic", "Unit_hipDeviceReset_Positive_Threaded", + "Unit_hipFuncSetCacheConfig_Positive_Basic", + "Unit_hipFuncSetCacheConfig_Negative_Parameters", + "Unit_hipFuncSetSharedMemConfig_Positive_Basic", + "Unit_hipFuncSetSharedMemConfig_Negative_Parameters", + "Unit_hipFuncSetAttribute_Positive_MaxDynamicSharedMemorySize", + "Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout", + "Unit_hipFuncSetAttribute_Positive_Parameters", + "Unit_hipFuncSetAttribute_Negative_Parameters", + "NOTE: The following 4 tests are disabled due to defect - EXSWHTEC-240", + "Unit_hipFuncSetCacheConfig_Negative_Not_Supported", + "Unit_hipFuncSetSharedMemConfig_Negative_Not_Supported", + "Unit_hipFuncSetAttribute_Positive_MaxDynamicSharedMemorySize_Not_Supported", + "Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout_Not_Supported", "Unit_hipOccupancyMaxActiveBlocksPerMultiprocessor_Negative_Parameters", "Unit_hipGraphMemcpyNodeSetParamsToSymbol_Positive_Basic", "Unit_hipGraphExecMemcpyNodeSetParamsToSymbol_Positive_Basic", diff --git a/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json b/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json index 6b7c976792..2d050a9ca4 100644 --- a/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json +++ b/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json @@ -95,6 +95,19 @@ "Unit_hipStreamSynchronize_NullStreamAndStreamPerThread", "Note: intermittent Seg fault failure ", "Unit_hipGraphAddEventRecordNode_Functional_WithoutFlags", + "Unit_hipFuncSetCacheConfig_Positive_Basic", + "Unit_hipFuncSetCacheConfig_Negative_Parameters", + "Unit_hipFuncSetSharedMemConfig_Positive_Basic", + "Unit_hipFuncSetSharedMemConfig_Negative_Parameters", + "Unit_hipFuncSetAttribute_Positive_MaxDynamicSharedMemorySize", + "Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout", + "Unit_hipFuncSetAttribute_Positive_Parameters", + "Unit_hipFuncSetAttribute_Negative_Parameters", + "NOTE: The following 4 tests are disabled due to defect - EXSWHTEC-240", + "Unit_hipFuncSetCacheConfig_Negative_Not_Supported", + "Unit_hipFuncSetSharedMemConfig_Negative_Not_Supported", + "Unit_hipFuncSetAttribute_Positive_MaxDynamicSharedMemorySize_Not_Supported", + "Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout_Not_Supported", "Unit_hipOccupancyMaxActiveBlocksPerMultiprocessor_Negative_Parameters", "Unit_hipGraphMemcpyNodeSetParamsToSymbol_Positive_Basic", "Unit_hipGraphExecMemcpyNodeSetParamsToSymbol_Positive_Basic", diff --git a/projects/hip-tests/catch/hipTestMain/config/config_nvidia_linux_common.json b/projects/hip-tests/catch/hipTestMain/config/config_nvidia_linux_common.json new file mode 100644 index 0000000000..7766cbe28d --- /dev/null +++ b/projects/hip-tests/catch/hipTestMain/config/config_nvidia_linux_common.json @@ -0,0 +1,11 @@ +{ + "DisabledTests": + [ + "Unit_hipFuncSetCacheConfig_Negative_Not_Supported", + "Unit_hipFuncSetSharedMemConfig_Negative_Not_Supported", + "Unit_hipFuncSetAttribute_Positive_MaxDynamicSharedMemorySize_Not_Supported", + "Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout_Not_Supported", + "=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/85 ===", + "Unit_hipFuncSetAttribute_Negative_Parameters" + ] +} diff --git a/projects/hip-tests/catch/hipTestMain/config/config_nvidia_windows_common.json b/projects/hip-tests/catch/hipTestMain/config/config_nvidia_windows_common.json new file mode 100644 index 0000000000..8247b49e3a --- /dev/null +++ b/projects/hip-tests/catch/hipTestMain/config/config_nvidia_windows_common.json @@ -0,0 +1,9 @@ +{ + "DisabledTests": + [ + "Unit_hipFuncSetCacheConfig_Negative_Not_Supported", + "Unit_hipFuncSetSharedMemConfig_Negative_Not_Supported", + "Unit_hipFuncSetAttribute_Positive_MaxDynamicSharedMemorySize_Not_Supported", + "Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout_Not_Supported" + ] +} diff --git a/projects/hip-tests/catch/include/hip_test_defgroups.hh b/projects/hip-tests/catch/include/hip_test_defgroups.hh index ce6158a72d..172f228f84 100644 --- a/projects/hip-tests/catch/include/hip_test_defgroups.hh +++ b/projects/hip-tests/catch/include/hip_test_defgroups.hh @@ -72,6 +72,13 @@ THE SOFTWARE. * @} */ +/** + * @defgroup ExecutionTest Execution Control + * @{ + * This section describes tests for the execution control functions of HIP runtime API. + * @} + */ + /** * @defgroup ShflTest warp shuffle function Management * @{ diff --git a/projects/hip-tests/catch/unit/CMakeLists.txt b/projects/hip-tests/catch/unit/CMakeLists.txt index c26af21b02..06739c623a 100644 --- a/projects/hip-tests/catch/unit/CMakeLists.txt +++ b/projects/hip-tests/catch/unit/CMakeLists.txt @@ -42,3 +42,4 @@ add_subdirectory(callback) # Vulkan interop APIs currently undefined for Nvidia add_subdirectory(vulkan_interop) endif() +add_subdirectory(executionControl) diff --git a/projects/hip-tests/catch/unit/executionControl/CMakeLists.txt b/projects/hip-tests/catch/unit/executionControl/CMakeLists.txt new file mode 100644 index 0000000000..4c28438009 --- /dev/null +++ b/projects/hip-tests/catch/unit/executionControl/CMakeLists.txt @@ -0,0 +1,11 @@ +set(TEST_SRC + execution_control_common.cc + hipFuncSetCacheConfig.cc + hipFuncSetSharedMemConfig.cc + hipFuncSetAttribute.cc +) + +hip_add_exe_to_target(NAME ExecutionControlTest + TEST_SRC ${TEST_SRC} + TEST_TARGET_NAME build_tests + COMPILE_OPTIONS -std=c++17) \ No newline at end of file diff --git a/projects/hip-tests/catch/unit/executionControl/execution_control_common.cc b/projects/hip-tests/catch/unit/executionControl/execution_control_common.cc new file mode 100644 index 0000000000..f9a2cc1675 --- /dev/null +++ b/projects/hip-tests/catch/unit/executionControl/execution_control_common.cc @@ -0,0 +1,27 @@ +/* +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 "execution_control_common.hh" + +#include + +__global__ void kernel() {} \ No newline at end of file diff --git a/projects/hip-tests/catch/unit/executionControl/execution_control_common.hh b/projects/hip-tests/catch/unit/executionControl/execution_control_common.hh new file mode 100644 index 0000000000..e66fcf28f3 --- /dev/null +++ b/projects/hip-tests/catch/unit/executionControl/execution_control_common.hh @@ -0,0 +1,25 @@ +/* +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. +*/ + +#pragma once + +__global__ void kernel(); \ No newline at end of file diff --git a/projects/hip-tests/catch/unit/executionControl/hipFuncSetAttribute.cc b/projects/hip-tests/catch/unit/executionControl/hipFuncSetAttribute.cc new file mode 100644 index 0000000000..785cc91e45 --- /dev/null +++ b/projects/hip-tests/catch/unit/executionControl/hipFuncSetAttribute.cc @@ -0,0 +1,260 @@ +/* +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 "execution_control_common.hh" + +#include +#include + +/** + * @addtogroup hipFuncSetAttribute hipFuncSetAttribute + * @{ + * @ingroup ExecutionTest + * `hipFuncSetAttribute(const void* func, hipFuncAttribute attr, int value)` - + * Set attribute for a specific function. + */ + +/** + * Test Description + * ------------------------ + * - Sets maximum dynamic shared memory size to the non-default value. + * - Expected output: return `hipSuccess` + * Test source + * ------------------------ + * - unit/executionControl/hipFuncSetAttribute.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipFuncSetAttribute_Positive_MaxDynamicSharedMemorySize") { + HIP_CHECK(hipFuncSetAttribute(reinterpret_cast(kernel), + hipFuncAttributeMaxDynamicSharedMemorySize, 1024)); + + hipFuncAttributes attributes; + HIP_CHECK(hipFuncGetAttributes(&attributes, reinterpret_cast(kernel))); + + REQUIRE(attributes.maxDynamicSharedSizeBytes == 1024); +} + +/** + * Test Description + * ------------------------ + * - Sets preferred shared memory carveout to the non-default value. + * - Expected output: return `hipSuccess` + * Test source + * ------------------------ + * - unit/executionControl/hipFuncSetAttribute.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout") { + HIP_CHECK(hipFuncSetAttribute(reinterpret_cast(kernel), + hipFuncAttributePreferredSharedMemoryCarveout, 50)); + + hipFuncAttributes attributes; + HIP_CHECK(hipFuncGetAttributes(&attributes, reinterpret_cast(kernel))); + + REQUIRE(attributes.preferredShmemCarveout == 50); +} + +/** + * Test Description + * ------------------------ + * - Validates handling of valid arguments: + * -# When `hipFuncAttributeMaxDynamicSharedMemorySize == 0` + * - Expected output: return `hipSuccess` + * -# When `hipFuncAttributeMaxDynamicSharedMemorySize == maxSharedMemoryPerBlock - sharedSizeBytes` + * - Expected output: return `hipSuccess` + * -# When `hipFuncAttributePreferredSharedMemoryCarveout` is 0% + * - Expected output: return `hipSuccess` + * -# When `hipFuncAttributePreferredSharedMemoryCarveout` is 100% + * - Expected output: return `hipSuccess` + * -# When `hipFuncAttributePreferredSharedMemoryCarveout` is default (-1) + * - Expected output: return `hipSuccess` + * Test source + * ------------------------ + * - unit/executionControl/hipFuncSetAttribute.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipFuncSetAttribute_Positive_Parameters") { + SECTION("hipFuncAttributeMaxDynamicSharedMemorySize == 0") { + HIP_CHECK(hipFuncSetAttribute(reinterpret_cast(kernel), + hipFuncAttributeMaxDynamicSharedMemorySize, 0)); + } + + SECTION( + "hipFuncAttributeMaxDynamicSharedMemorySize == maxSharedMemoryPerBlock - sharedSizeBytes") { + // The sum of this value and the function attribute sharedSizeBytes cannot exceed the device + // attribute cudaDevAttrMaxSharedMemoryPerBlockOptin + int max_shared; + HIP_CHECK(hipDeviceGetAttribute(&max_shared, hipDeviceAttributeMaxSharedMemoryPerBlock, 0)); + + hipFuncAttributes attributes; + HIP_CHECK(hipFuncGetAttributes(&attributes, reinterpret_cast(kernel))); + + HIP_CHECK(hipFuncSetAttribute(reinterpret_cast(kernel), + hipFuncAttributeMaxDynamicSharedMemorySize, + max_shared - attributes.sharedSizeBytes)); + } + + SECTION("hipFuncAttributePreferredSharedMemoryCarveout == 0") { + HIP_CHECK(hipFuncSetAttribute(reinterpret_cast(kernel), + hipFuncAttributePreferredSharedMemoryCarveout, 0)); + } + + SECTION("hipFuncAttributePreferredSharedMemoryCarveout == 100") { + HIP_CHECK(hipFuncSetAttribute(reinterpret_cast(kernel), + hipFuncAttributePreferredSharedMemoryCarveout, 100)); + } + + SECTION("hipFuncAttributePreferredSharedMemoryCarveout == -1 (default)") { + HIP_CHECK(hipFuncSetAttribute(reinterpret_cast(kernel), + hipFuncAttributePreferredSharedMemoryCarveout, -1)); + } +} + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When pointer to the kernel function is `nullptr` + * - Expected output: return `hipErrorInvalidDeviceFunction` + * -# When the attribute is invalid + * - Expected output: return `hipErrorInvalidValue` + * -# When `hipFuncAttributeMaxDynamicSharedMemorySize < 0` + * - Expected output: return `hipErrorInvalidValue` + * -# When `hipFuncAttributeMaxDynamicSharedMemorySize > maxSharedMemoryPerBlock - sharedSizeBytes` + * - Expected output: return `hipErrorInvalidValue` + * -# When `hipFuncAttributePreferredSharedMemoryCarveout` is negative + * - Expected output: return `hipErrorInvalidValue` + * -# When `hipFuncAttributePreferredSharedMemoryCarveout` is above 100% + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/executionControl/hipFuncSetAttribute.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipFuncSetAttribute_Negative_Parameters") { + SECTION("func == nullptr") { + HIP_CHECK_ERROR(hipFuncSetAttribute(nullptr, hipFuncAttributePreferredSharedMemoryCarveout, 50), + hipErrorInvalidDeviceFunction); + } + + SECTION("invalid attribute") { + HIP_CHECK_ERROR( + hipFuncSetAttribute(reinterpret_cast(kernel), static_cast(-1), 50), + hipErrorInvalidValue); + } + + SECTION("hipFuncAttributeMaxDynamicSharedMemorySize < 0") { + HIP_CHECK_ERROR(hipFuncSetAttribute(reinterpret_cast(kernel), + hipFuncAttributeMaxDynamicSharedMemorySize, -1), + hipErrorInvalidValue); + } + + SECTION( + "hipFuncAttributeMaxDynamicSharedMemorySize > maxSharedMemoryPerBlock - sharedSizeBytes") { + // The sum of this value and the function attribute sharedSizeBytes cannot exceed the device + // attribute cudaDevAttrMaxSharedMemoryPerBlockOptin + int max_shared; + HIP_CHECK(hipDeviceGetAttribute(&max_shared, hipDeviceAttributeMaxSharedMemoryPerBlock, 0)); + + hipFuncAttributes attributes; + HIP_CHECK(hipFuncGetAttributes(&attributes, reinterpret_cast(kernel))); + + HIP_CHECK_ERROR(hipFuncSetAttribute(reinterpret_cast(kernel), + hipFuncAttributeMaxDynamicSharedMemorySize, + max_shared - attributes.sharedSizeBytes + 1), + hipErrorInvalidValue); + } + + SECTION("hipFuncAttributePreferredSharedMemoryCarveout < -1") { + HIP_CHECK_ERROR(hipFuncSetAttribute(reinterpret_cast(kernel), + hipFuncAttributePreferredSharedMemoryCarveout, -2), + hipErrorInvalidValue); + } + + SECTION("hipFuncAttributePreferredSharedMemoryCarveout > 100") { + HIP_CHECK_ERROR(hipFuncSetAttribute(reinterpret_cast(kernel), + hipFuncAttributePreferredSharedMemoryCarveout, 101), + hipErrorInvalidValue); + } +} + +/** + * Test Description + * ------------------------ + * - Sets `hipFuncAttributeMaxDynamicSharedMemorySize` to the non-supported value + * - Expected output: return `hipErrorNotSupported` + * Test source + * ------------------------ + * - unit/executionControl/hipFuncSetAttribute.cc + * Test requirements + * ------------------------ + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipFuncSetAttribute_Positive_MaxDynamicSharedMemorySize_Not_Supported") { + hipFuncAttributes old_attributes; + HIP_CHECK(hipFuncGetAttributes(&old_attributes, reinterpret_cast(kernel))); + + HIP_CHECK_ERROR(hipFuncSetAttribute(reinterpret_cast(kernel), + hipFuncAttributeMaxDynamicSharedMemorySize, 1024), + hipErrorNotSupported); + + hipFuncAttributes new_attributes; + HIP_CHECK(hipFuncGetAttributes(&new_attributes, reinterpret_cast(kernel))); + + REQUIRE(old_attributes.maxDynamicSharedSizeBytes == new_attributes.maxDynamicSharedSizeBytes); +} + +/** + * Test Description + * ------------------------ + * - Sets `hipFuncAttributePreferredSharedMemoryCarveout` to the non-supported value + * - Expected output: return `hipErrorNotSupported` + * Test source + * ------------------------ + * - unit/executionControl/hipFuncSetAttribute.cc + * Test requirements + * ------------------------ + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout_Not_Supported") { + hipFuncAttributes old_attributes; + HIP_CHECK(hipFuncGetAttributes(&old_attributes, reinterpret_cast(kernel))); + + HIP_CHECK_ERROR(hipFuncSetAttribute(reinterpret_cast(kernel), + hipFuncAttributePreferredSharedMemoryCarveout, 50), + hipErrorNotSupported); + + hipFuncAttributes new_attributes; + HIP_CHECK(hipFuncGetAttributes(&new_attributes, reinterpret_cast(kernel))); + + REQUIRE(old_attributes.preferredShmemCarveout == new_attributes.preferredShmemCarveout); +} diff --git a/projects/hip-tests/catch/unit/executionControl/hipFuncSetCacheConfig.cc b/projects/hip-tests/catch/unit/executionControl/hipFuncSetCacheConfig.cc new file mode 100644 index 0000000000..1f5ce8dfda --- /dev/null +++ b/projects/hip-tests/catch/unit/executionControl/hipFuncSetCacheConfig.cc @@ -0,0 +1,105 @@ +/* +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 "execution_control_common.hh" + +#include +#include + +/** + * @addtogroup hipFuncSetCacheConfig hipFuncSetCacheConfig + * @{ + * @ingroup ExecutionTest + * `hipFuncSetCacheConfig(const void* func, hipFuncCache_t config)` - + * Set Cache configuration for a specific function. + */ + +namespace { +constexpr std::array kCacheConfigs{ + hipFuncCachePreferNone, hipFuncCachePreferShared, hipFuncCachePreferL1, + hipFuncCachePreferEqual}; +} // anonymous namespace + +/** + * Test Description + * ------------------------ + * - Sets cache config for every cache config enumeration. + * Test source + * ------------------------ + * - unit/executionControl/hipFuncSetCacheConfig.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipFuncSetCacheConfig_Positive_Basic") { + const auto cache_config = GENERATE(from_range(begin(kCacheConfigs), end(kCacheConfigs))); + + HIP_CHECK(hipFuncSetCacheConfig(reinterpret_cast(kernel), cache_config)); + + kernel<<<1, 1>>>(); + HIP_CHECK(hipDeviceSynchronize()); +} + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When pointer to the kernel function is `nullptr` + * - Expected output: return `hipErrorInvalidDeviceFunction` + * -# When cache config enumeration is invalid + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/executionControl/hipFuncSetCacheConfig.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipFuncSetCacheConfig_Negative_Parameters") { + SECTION("func == nullptr") { + HIP_CHECK_ERROR(hipFuncSetCacheConfig(nullptr, hipFuncCachePreferNone), + hipErrorInvalidDeviceFunction); + } + SECTION("invalid cache config") { + HIP_CHECK_ERROR( + hipFuncSetCacheConfig(reinterpret_cast(kernel), static_cast(-1)), + hipErrorInvalidValue); + } +} + +/** + * Test Description + * ------------------------ + * - Sets cache config that is not supported. + * - Expected output: return `hipErrorNotSupported` + * Test source + * ------------------------ + * - unit/executionControl/hipFuncSetCacheConfig.cc + * Test requirements + * ------------------------ + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipFuncSetCacheConfig_Negative_Not_Supported") { + HIP_CHECK_ERROR(hipFuncSetCacheConfig(reinterpret_cast(kernel), hipFuncCachePreferNone), + hipErrorNotSupported); +} diff --git a/projects/hip-tests/catch/unit/executionControl/hipFuncSetSharedMemConfig.cc b/projects/hip-tests/catch/unit/executionControl/hipFuncSetSharedMemConfig.cc new file mode 100644 index 0000000000..c44a83b3be --- /dev/null +++ b/projects/hip-tests/catch/unit/executionControl/hipFuncSetSharedMemConfig.cc @@ -0,0 +1,106 @@ +/* +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 "execution_control_common.hh" + +#include +#include + +/** + * @addtogroup hipFuncSetSharedMemConfig hipFuncSetSharedMemConfig + * @{ + * @ingroup ExecutionTest + * `hipFuncSetSharedMemConfig(const void* func, hipSharedMemConfig config)` - + * Set shared memory configuation for a specific function. + */ + +namespace { +constexpr std::array kSharedMemConfigs{ + hipSharedMemBankSizeDefault, hipSharedMemBankSizeFourByte, hipSharedMemBankSizeEightByte}; +} // anonymous namespace + +/** + * Test Description + * ------------------------ + * - Sets cache config for every shared memory config enumeration. + * Test source + * ------------------------ + * - unit/executionControl/hipFuncSetSharedMemConfig.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipFuncSetSharedMemConfig_Positive_Basic") { + const auto shared_mem_config = + GENERATE(from_range(begin(kSharedMemConfigs), end(kSharedMemConfigs))); + + HIP_CHECK(hipFuncSetSharedMemConfig(reinterpret_cast(kernel), shared_mem_config)); + + kernel<<<1, 1>>>(); + HIP_CHECK(hipDeviceSynchronize()); +} + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When pointer to the kernel function is `nullptr` + * - Expected output: return `hipErrorInvalidDeviceFunction` + * -# When shared memory config enumeration is invalid + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/executionControl/hipFuncSetSharedMemConfig.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipFuncSetSharedMemConfig_Negative_Parameters") { + SECTION("func == nullptr") { + HIP_CHECK_ERROR(hipFuncSetSharedMemConfig(nullptr, hipSharedMemBankSizeDefault), + hipErrorInvalidDeviceFunction); + } + SECTION("invalid shared mem config") { + HIP_CHECK_ERROR(hipFuncSetSharedMemConfig(reinterpret_cast(kernel), + static_cast(-1)), + hipErrorInvalidValue); + } +} + +/** + * Test Description + * ------------------------ + * - Sets shared memory config that is not supported. + * - Expected output: return `hipErrorNotSupported` + * Test source + * ------------------------ + * - unit/executionControl/hipFuncSetSharedMemConfig.cc + * Test requirements + * ------------------------ + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipFuncSetSharedMemConfig_Negative_Not_Supported") { + HIP_CHECK_ERROR( + hipFuncSetSharedMemConfig(reinterpret_cast(kernel), hipSharedMemBankSizeDefault), + hipErrorNotSupported); +} From d7f8a95ce112aab06150c5e2ac18ff76642f82fe Mon Sep 17 00:00:00 2001 From: milos-mozetic <118800401+milos-mozetic@users.noreply.github.com> Date: Sat, 8 Jul 2023 17:21:34 +0200 Subject: [PATCH 02/25] EXSWHTEC-100 - Miscellaneous modifications to existing memory tests (#96) - Miscellaneous modifications to existing memory tests - Update config_amd_linux_common.json - Update config_amd_windows_common.json - Disable tests which failed on external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/96 [ROCm/hip-tests commit: 2f64855322a1f22eb4b93b17421c19316a0810db] --- .../config/config_amd_linux_common.json | 4 +- .../config/config_amd_windows_common.json | 4 +- .../hip-tests/catch/unit/memory/hipFree.cc | 18 +++---- .../unit/memory/hipHostGetDevicePointer.cc | 30 +++++++++-- .../catch/unit/memory/hipHostRegister.cc | 7 ++- .../catch/unit/memory/hipHostUnregister.cc | 6 +++ .../catch/unit/memory/hipMallocPitch.cc | 52 ++++++------------- .../unit/memory/hipPointerGetAttribute.cc | 5 +- 8 files changed, 67 insertions(+), 59 deletions(-) diff --git a/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json b/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json index 9704e80d49..f3a751f348 100644 --- a/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json +++ b/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json @@ -98,6 +98,8 @@ "=== Below tests fail in stress test on 30/06/23 ===", "Unit_hipStreamValue_Wait32_Blocking_NoMask_Nor", "Unit_hipStreamValue_Write - TestParams", - "Unit_hipMemcpyParam2DAsync_multiDevice-StreamOnDiffDevice" + "Unit_hipMemcpyParam2DAsync_multiDevice-StreamOnDiffDevice", + "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/96 ===", + "Unit_hipHostGetDevicePointer_Negative" ] } diff --git a/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json b/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json index 2d050a9ca4..4d7fdff960 100644 --- a/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json +++ b/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json @@ -185,6 +185,8 @@ "SWDEV-398981 fails in stress test", "Unit_hipStreamCreateWithPriority_MulthreadDefaultflag", "Note: UUID returned empty on some windows nodes", - "Unit_hipDeviceGetUuid_Positive" + "Unit_hipDeviceGetUuid_Positive", + "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/96 ===", + "Unit_hipHostGetDevicePointer_Negative" ] } diff --git a/projects/hip-tests/catch/unit/memory/hipFree.cc b/projects/hip-tests/catch/unit/memory/hipFree.cc index b46f8ae8fb..1db0ec9502 100644 --- a/projects/hip-tests/catch/unit/memory/hipFree.cc +++ b/projects/hip-tests/catch/unit/memory/hipFree.cc @@ -49,11 +49,10 @@ using namespace std::chrono_literals; const std::chrono::duration delay = 50ms; constexpr size_t numAllocs = 10; -#if HT_AMD /* Disabled because frequency based wait is timing out on nvidia platforms */ -TEMPLATE_TEST_CASE("Unit_hipFreeImplicitSyncDev", "", char, float, float2, float4) { - TestType* devPtr{}; +TEST_CASE("Unit_hipFreeImplicitSyncDev") { + int* devPtr{}; size_t size_mult = GENERATE(1, 32, 64, 128, 256); - HIP_CHECK(hipMalloc(&devPtr, sizeof(TestType) * size_mult)); + HIP_CHECK(hipMalloc(&devPtr, sizeof(*devPtr) * size_mult)); HipTest::runKernelForDuration(delay); // make sure device is busy @@ -62,11 +61,11 @@ TEMPLATE_TEST_CASE("Unit_hipFreeImplicitSyncDev", "", char, float, float2, float HIP_CHECK(hipStreamQuery(nullptr)); } -TEMPLATE_TEST_CASE("Unit_hipFreeImplicitSyncHost", "", char, float, float2, float4) { - TestType* hostPtr{}; +TEST_CASE("Unit_hipFreeImplicitSyncHost") { + int* hostPtr{}; size_t size_mult = GENERATE(1, 32, 64, 128, 256); - HIP_CHECK(hipHostMalloc(&hostPtr, sizeof(TestType) * size_mult)); + HIP_CHECK(hipHostMalloc(&hostPtr, sizeof(*hostPtr) * size_mult)); HipTest::runKernelForDuration(delay); // make sure device is busy @@ -75,7 +74,7 @@ TEMPLATE_TEST_CASE("Unit_hipFreeImplicitSyncHost", "", char, float, float2, floa HIP_CHECK(hipStreamQuery(nullptr)); } -#if HT_NVIDIA // Meaningless at the moment, since we are not running wait kernel on nvidia. +#if HT_NVIDIA TEMPLATE_TEST_CASE("Unit_hipFreeImplicitSyncArray", "", char, float, float2, float4) { using vec_info = vector_info; DriverContext ctx; @@ -135,7 +134,6 @@ TEMPLATE_TEST_CASE("Unit_hipFreeImplicitSyncArray", "", char, float, float2, flo } } -#endif #endif // Freeing a invalid pointer with on device @@ -166,8 +164,6 @@ TEST_CASE("Unit_hipFreeNegativeHost") { #if HT_NVIDIA TEST_CASE("Unit_hipFreeNegativeArray") { DriverContext ctx; - hipArray_t arrayPtr{}; - hiparray cuArrayPtr{}; SECTION("ArrayFree") { HIP_CHECK(hipFreeArray(nullptr)); } SECTION("ArrayDestroy") { diff --git a/projects/hip-tests/catch/unit/memory/hipHostGetDevicePointer.cc b/projects/hip-tests/catch/unit/memory/hipHostGetDevicePointer.cc index 7c3e689e05..7f07468935 100644 --- a/projects/hip-tests/catch/unit/memory/hipHostGetDevicePointer.cc +++ b/projects/hip-tests/catch/unit/memory/hipHostGetDevicePointer.cc @@ -21,11 +21,19 @@ THE SOFTWARE. */ #include +#include TEST_CASE("Unit_hipHostGetDevicePointer_Negative") { int* hPtr{nullptr}; + int* dPtr{nullptr}; HIP_CHECK(hipHostMalloc(&hPtr, sizeof(int))); + if (!DeviceAttributesSupport(0, hipDeviceAttributeCanMapHostMemory)) { + HIP_CHECK_ERROR(hipHostGetDevicePointer(reinterpret_cast(&dPtr), hPtr, 0), + hipErrorNotSupported); + return; + } + SECTION("Nullptr as device") { HIP_CHECK_ERROR(hipHostGetDevicePointer(nullptr, hPtr, 0), hipErrorInvalidValue); } @@ -36,13 +44,29 @@ TEST_CASE("Unit_hipHostGetDevicePointer_Negative") { hipErrorInvalidValue); } - // Not adding check for flags since CUDA spec states that there might be more values added to it + SECTION("Non pinned memory as host") { + int* hPtr = reinterpret_cast(malloc(sizeof(*hPtr))); + HIP_CHECK_ERROR(hipHostGetDevicePointer(reinterpret_cast(&dPtr), hPtr, 0), + hipErrorInvalidValue); + free(hPtr); + } + + SECTION("Flags non-zero") { + HIP_CHECK_ERROR(hipHostGetDevicePointer(reinterpret_cast(&dPtr), hPtr, 1), + hipErrorInvalidValue); + } + HIP_CHECK(hipHostFree(hPtr)); } template __global__ void set(T* ptr, T val) { *ptr = val; } TEST_CASE("Unit_hipHostGetDevicePointer_UseCase") { + if(!DeviceAttributesSupport(0, hipDeviceAttributeCanMapHostMemory)) { + HipTest::HIP_SKIP_TEST("Device does not support mapping host memory"); + return; + } + int* hPtr{nullptr}; HIP_CHECK(hipHostMalloc(&hPtr, sizeof(int))); @@ -71,8 +95,8 @@ TEST_CASE("Unit_hipHostGetDevicePointer_UseCase") { HIP_CHECK(hipDeviceSynchronize()); HIP_CHECK(hipHostUnregister(&res)); - REQUIRE(value == 10); + REQUIRE(res == value); } HIP_CHECK(hipHostFree(hPtr)); -} +} \ No newline at end of file diff --git a/projects/hip-tests/catch/unit/memory/hipHostRegister.cc b/projects/hip-tests/catch/unit/memory/hipHostRegister.cc index f6964db616..5e1b10d234 100644 --- a/projects/hip-tests/catch/unit/memory/hipHostRegister.cc +++ b/projects/hip-tests/catch/unit/memory/hipHostRegister.cc @@ -27,9 +27,10 @@ This testfile verifies the following scenarios of hipHostRegister API 2. hipHostRegister and perform hipMemcpy on it. */ +#include "hip/hip_runtime_api.h" #include #include -#include "hip/hip_runtime_api.h" +#include #define OFFSET 128 static constexpr auto LEN{1024 * 1024}; @@ -63,9 +64,7 @@ void doMemCopy(size_t numElements, int offset, T* A, T* Bh, T* Bd, bool internal HIP_CHECK(hipMemcpy(Bh, Bd, sizeBytes, hipMemcpyDeviceToHost)); // Make sure the copy worked - for (size_t i = 0; i < numElements; i++) { - REQUIRE(Bh[i] == A[i]); - } + ArrayMismatch(A, Bh, numElements); if (internalRegister) { HIP_CHECK(hipHostUnregister(A)); diff --git a/projects/hip-tests/catch/unit/memory/hipHostUnregister.cc b/projects/hip-tests/catch/unit/memory/hipHostUnregister.cc index 69373133d0..ea3d018a33 100644 --- a/projects/hip-tests/catch/unit/memory/hipHostUnregister.cc +++ b/projects/hip-tests/catch/unit/memory/hipHostUnregister.cc @@ -68,6 +68,12 @@ TEST_CASE("Unit_hipHostUnregister_NullPtr") { HIP_CHECK_ERROR(hipHostUnregister(nullptr), hipErrorInvalidValue); } +TEST_CASE("Unit_hipHostUnregister_Ptr_Different_Than_Specified_To_Register") { + std::vector alloc(2); + HIP_CHECK(hipHostRegister(alloc.data(), alloc.size(), 0)); + HIP_CHECK_ERROR(hipHostUnregister(&alloc.data()[1]), hipErrorHostMemoryNotRegistered); +} + TEST_CASE("Unit_hipHostUnregister_NotRegisteredPointer") { auto x = std::unique_ptr(new int); HIP_CHECK_ERROR(hipHostUnregister(x.get()), hipErrorHostMemoryNotRegistered); diff --git a/projects/hip-tests/catch/unit/memory/hipMallocPitch.cc b/projects/hip-tests/catch/unit/memory/hipMallocPitch.cc index 19c803c7c2..7b26c16034 100644 --- a/projects/hip-tests/catch/unit/memory/hipMallocPitch.cc +++ b/projects/hip-tests/catch/unit/memory/hipMallocPitch.cc @@ -228,6 +228,21 @@ TEST_CASE("Unit_hipMallocPitch_Negative") { } } +TEST_CASE("Unit_hipMallocPitch_Zero_Dims") { + void* ptr = nullptr; + size_t pitch = 0; + + SECTION("width == 0") { + HIP_CHECK(hipMallocPitch(&ptr, &pitch, 0, 1)); + REQUIRE(ptr == nullptr); + } + + SECTION("height == 0") { + HIP_CHECK(hipMallocPitch(&ptr, &pitch, 1, 0)); + REQUIRE(ptr == nullptr); + } +} + TEST_CASE("Unit_hipMemAllocPitch_Negative") { size_t pitch = 0; hipDeviceptr_t ptr{}; @@ -360,42 +375,7 @@ static void MemoryAllocDiffSizes(int gpu) { static void threadFunc(int gpu) { MemoryAllocDiffSizes(gpu); } -/* - * This testcase verifies the negative scenarios of hipMallocPitch API - */ -#if 0 //TODO: Review, fix and re-enable test -TEST_CASE("Unit_hipMallocPitch_Negative") { - float* A_d; - size_t pitch_A = 0; - size_t width{NUM_W * sizeof(float)}; -#if HT_NVIDIA - SECTION("NullPtr to Pitched Ptr") { - REQUIRE(hipMallocPitch(nullptr, - &pitch_A, width, NUM_H) != hipSuccess); - } - SECTION("nullptr to pitch") { - REQUIRE(hipMallocPitch(reinterpret_cast(&A_d), - nullptr, width, NUM_H) != hipSuccess); - } -#endif - SECTION("Width 0 in hipMallocPitch") { - REQUIRE(hipMallocPitch(reinterpret_cast(&A_d), - &pitch_A, 0, NUM_H) == hipSuccess); - } - - SECTION("Height 0 in hipMallocPitch") { - REQUIRE(hipMallocPitch(reinterpret_cast(&A_d), - &pitch_A, width, 0) == hipSuccess); - } - - SECTION("Max int values") { - REQUIRE(hipMallocPitch(reinterpret_cast(&A_d), - &pitch_A, std::numeric_limits::max(), - std::numeric_limits::max()) != hipSuccess); - } -} -#endif /* * This testcase verifies the basic scenario of * hipMallocPitch API for different datatypes @@ -408,6 +388,7 @@ TEMPLATE_TEST_CASE("Unit_hipMallocPitch_Basic", size_t width{NUM_W * sizeof(TestType)}; REQUIRE(hipMallocPitch(reinterpret_cast(&A_d), &pitch_A, width, NUM_H) == hipSuccess); + REQUIRE(width <= pitch_A); HIP_CHECK(hipFree(A_d)); } @@ -538,4 +519,3 @@ TEMPLATE_TEST_CASE("Unit_hipMallocPitch_KernelLaunch", "" HipTest::freeArrays(nullptr, nullptr, nullptr, A_h, B_h, C_h, false); } - diff --git a/projects/hip-tests/catch/unit/memory/hipPointerGetAttribute.cc b/projects/hip-tests/catch/unit/memory/hipPointerGetAttribute.cc index 393221da11..b0e1e7a5f8 100644 --- a/projects/hip-tests/catch/unit/memory/hipPointerGetAttribute.cc +++ b/projects/hip-tests/catch/unit/memory/hipPointerGetAttribute.cc @@ -316,9 +316,8 @@ TEST_CASE("Unit_hipPointerGetAttribute_Negative") { == hipErrorInvalidValue); } SECTION("Pass invalid attribute") { - hipPointer_attribute attr{HIP_POINTER_ATTRIBUTE_DEVICE_POINTER}; - REQUIRE(hipPointerGetAttribute(&data, attr, - reinterpret_cast(A_h)) == hipErrorInvalidValue); + REQUIRE(hipPointerGetAttribute(&data, static_cast(-1), + reinterpret_cast(A_h)) == hipErrorInvalidValue); } #if HT_AMD SECTION("Pass HIP_POINTER_ATTRIBUTE_IS_GPU_DIRECT_RDMA_CAPABLE" From 799859507d9a2864b31e3009a953045f94d2ff8e Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Sat, 8 Jul 2023 20:53:10 +0530 Subject: [PATCH 03/25] SWDEV-362365 - Enable Unit_hipDeviceSetSharedMemConfig_Negative_Parameters. (#219) Change-Id: Ib8e2ac7abb2c64bc5140b2bc64e768d4312b2440 [ROCm/hip-tests commit: 8a49594fdb39be4257f8a3414966df7586cf4601] --- .../catch/hipTestMain/config/config_amd_linux_common.json | 1 - .../catch/hipTestMain/config/config_amd_windows_common.json | 1 - 2 files changed, 2 deletions(-) diff --git a/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json b/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json index f3a751f348..3a0014bedb 100644 --- a/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json +++ b/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json @@ -57,7 +57,6 @@ "Unit_hipIpcGetMemHandle_Positive_Unique_Handles_Separate_Allocations", "Unit_hipStreamCreateWithFlags_DefaultStreamInteraction", "Unit_hipStreamWaitEvent_UninitializedStream_Negative", - "Unit_hipDeviceSetSharedMemConfig_Negative_Parameters", "Unit_hipMemset3DSync", "Unit_hipStreamAddCallback_StrmSyncTiming", "Disabling test tracked SWDEV-394199", diff --git a/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json b/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json index 4d7fdff960..87d534cfd8 100644 --- a/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json +++ b/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json @@ -163,7 +163,6 @@ "Unit_hipGraphExecMemsetNodeSetParams_Positive_Basic - uint32_t", "Unit_hipGraphMemsetNodeSetParams_Positive_Basic - uint8_t", "Unit_hipStreamWaitEvent_UninitializedStream_Negative", - "Unit_hipDeviceSetSharedMemConfig_Negative_Parameters", "Unit_hipDeviceGetUuid_Positive", "Disabling test tracked SWDEV-394199", "Unit_hipStreamCreateWithPriority_MulthreadNonblockingflag", From ce58c13ffab34b0725af2d7394ca901426609f6c Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Sat, 8 Jul 2023 20:53:51 +0530 Subject: [PATCH 04/25] SWDEV-403382 - fix errors for vulkan test (#341) Change-Id: Icfe4c0cf1745c18caeae419e66544b6770f33e70 [ROCm/hip-tests commit: c67e5dae232519a5fe59caa4012d37a7c90ca955] --- .../catch/unit/vulkan_interop/vulkan_test.cc | 13 +-- .../catch/unit/vulkan_interop/vulkan_test.hh | 80 ++++++++++++++++++- 2 files changed, 87 insertions(+), 6 deletions(-) diff --git a/projects/hip-tests/catch/unit/vulkan_interop/vulkan_test.cc b/projects/hip-tests/catch/unit/vulkan_interop/vulkan_test.cc index 4252916177..9bb61eff31 100644 --- a/projects/hip-tests/catch/unit/vulkan_interop/vulkan_test.cc +++ b/projects/hip-tests/catch/unit/vulkan_interop/vulkan_test.cc @@ -24,6 +24,8 @@ THE SOFTWARE. #include #include + + VkFence VulkanTest::CreateFence() { VkFence fence; VkFenceCreateInfo fence_create_info = {}; @@ -80,7 +82,7 @@ hipExternalMemoryHandleDesc VulkanTest::BuildMemoryDescriptor(VkDeviceMemory vk_ hipExternalMemoryHandleDesc mem_handle_desc = {}; mem_handle_desc.type = VulkanMemHandleTypeToHIPHandleType(); #ifdef _WIN64 - mem_handle_desc.handle.win32.handle = GetMemoryHandle(ck_mem); + mem_handle_desc.handle.win32.handle = GetMemoryHandle(vk_mem); #else mem_handle_desc.handle.fd = GetMemoryHandle(vk_mem); #endif @@ -170,7 +172,7 @@ bool VulkanTest::CheckExtensionSupport(std::vector expected_extensi std::back_inserter(supported_extensions), [](const auto& p) { return p.extensionName; }); - constexpr auto p = [](const char* l, const char* r) { return strcmp(l, r) < 0; }; + auto p = [](const char* l, const char* r) { return strcmp(l, r) < 0; }; std::sort(expected_extensions.begin(), expected_extensions.end(), p); std::sort(supported_extensions.begin(), supported_extensions.end(), p); @@ -328,7 +330,7 @@ int VulkanTest::GetSemaphoreHandle(VkSemaphore semaphore) { #ifdef _WIN64 HANDLE VulkanTest::GetMemoryHandle(VkDeviceMemory memory) { - Handle handle = 0; + HANDLE handle = 0; VkMemoryGetWin32HandleInfoKHR vkMemoryGetWin32HandleInfoKHR = {}; vkMemoryGetWin32HandleInfoKHR.sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR; @@ -336,7 +338,7 @@ VulkanTest::GetMemoryHandle(VkDeviceMemory memory) { vkMemoryGetWin32HandleInfoKHR.handleType = _mem_handle_type; PFN_vkGetMemoryWin32HandleKHR fpGetMemoryWin32HandleKHR = - (PFN_vkGetMemoryWin32HandleKHR)vkGetDeviceProcAddr(m_device, "vkGetMemoryWin32HandleKHR"); + (PFN_vkGetMemoryWin32HandleKHR)vkGetDeviceProcAddr(_device, "vkGetMemoryWin32HandleKHR"); if (!fpGetMemoryWin32HandleKHR) { throw std::runtime_error("Failed to retrieve vkGetMemoryWin32HandleKHR"); @@ -407,4 +409,5 @@ hipExternalSemaphore_t ImportBinarySemaphore(VulkanTest& vkt) { HIP_CHECK(hipImportExternalSemaphore(&hip_ext_semaphore, &sem_handle_desc)); return hip_ext_semaphore; -} \ No newline at end of file +} + diff --git a/projects/hip-tests/catch/unit/vulkan_interop/vulkan_test.hh b/projects/hip-tests/catch/unit/vulkan_interop/vulkan_test.hh index e223e8cd2b..82123958f6 100644 --- a/projects/hip-tests/catch/unit/vulkan_interop/vulkan_test.hh +++ b/projects/hip-tests/catch/unit/vulkan_interop/vulkan_test.hh @@ -20,12 +20,24 @@ THE SOFTWARE. #pragma once #include -#include + #ifdef _WIN64 + +#include +#include #include + +#include +#include +#include +#include +#include + #endif +#include +#include #include #include @@ -39,6 +51,72 @@ THE SOFTWARE. } \ } +#ifdef _WIN64 +class WindowsSecurityAttributes +{ +protected: + SECURITY_ATTRIBUTES m_winSecurityAttributes; + PSECURITY_DESCRIPTOR m_winPSecurityDescriptor; + +public: +WindowsSecurityAttributes::WindowsSecurityAttributes() +{ + m_winPSecurityDescriptor = (PSECURITY_DESCRIPTOR)calloc(1, SECURITY_DESCRIPTOR_MIN_LENGTH + 2 * sizeof(void **)); + if (!m_winPSecurityDescriptor) { + throw std::runtime_error("Failed to allocate memory for security descriptor"); + } + + PSID *ppSID = (PSID *)((PBYTE)m_winPSecurityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH); + PACL *ppACL = (PACL *)((PBYTE)ppSID + sizeof(PSID *)); + + InitializeSecurityDescriptor(m_winPSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION); + + SID_IDENTIFIER_AUTHORITY sidIdentifierAuthority = SECURITY_WORLD_SID_AUTHORITY; + AllocateAndInitializeSid(&sidIdentifierAuthority, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, ppSID); + + EXPLICIT_ACCESS explicitAccess; + ZeroMemory(&explicitAccess, sizeof(EXPLICIT_ACCESS)); + explicitAccess.grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL; + explicitAccess.grfAccessMode = SET_ACCESS; + explicitAccess.grfInheritance = INHERIT_ONLY; + explicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID; + explicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; + explicitAccess.Trustee.ptstrName = (LPTSTR) * ppSID; + + SetEntriesInAcl(1, &explicitAccess, NULL, ppACL); + + SetSecurityDescriptorDacl(m_winPSecurityDescriptor, TRUE, *ppACL, FALSE); + + m_winSecurityAttributes.nLength = sizeof(m_winSecurityAttributes); + m_winSecurityAttributes.lpSecurityDescriptor = m_winPSecurityDescriptor; + m_winSecurityAttributes.bInheritHandle = TRUE; +} + +SECURITY_ATTRIBUTES * +WindowsSecurityAttributes::operator&() +{ + return &m_winSecurityAttributes; +} + +WindowsSecurityAttributes::~WindowsSecurityAttributes() +{ + PSID *ppSID = (PSID *)((PBYTE)m_winPSecurityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH); + PACL *ppACL = (PACL *)((PBYTE)ppSID + sizeof(PSID *)); + + if (*ppSID) { + FreeSid(*ppSID); + } + if (*ppACL) { + LocalFree(*ppACL); + } + free(m_winPSecurityDescriptor); +} +}; + + +#endif /* _WIN64 */ + + class VulkanTest { public: VulkanTest(bool enable_validation) From e93c1dd3303d91ae62e6563640fa4f403cbd8367 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Sat, 8 Jul 2023 20:54:08 +0530 Subject: [PATCH 05/25] SWDEV-377322- [catch2][dtest] Added functional tests for the API hipGraphAddKernelNode (#344) Change-Id: I693402be766f9cdc9369a92dc1fa5196ffd4d9b7 [ROCm/hip-tests commit: 8fe180bfdb6a6b3ca0438ec9651c2f38b704e66c] --- .../hip-tests/catch/unit/graph/CMakeLists.txt | 4 + .../hip-tests/catch/unit/graph/add_Kernel.cpp | 24 ++ .../catch/unit/graph/hipGraphAddKernelNode.cc | 397 +++++++++++++++++- 3 files changed, 406 insertions(+), 19 deletions(-) create mode 100644 projects/hip-tests/catch/unit/graph/add_Kernel.cpp diff --git a/projects/hip-tests/catch/unit/graph/CMakeLists.txt b/projects/hip-tests/catch/unit/graph/CMakeLists.txt index 034063060f..6d8e5e45d1 100644 --- a/projects/hip-tests/catch/unit/graph/CMakeLists.txt +++ b/projects/hip-tests/catch/unit/graph/CMakeLists.txt @@ -130,6 +130,8 @@ set(TEST_SRC hipGraphKernelNodeGetAttribute.cc hipGraphKernelNodeSetAttribute.cc) +add_custom_target(add_Kernel.code COMMAND ${CMAKE_CXX_COMPILER} --genco ${OFFLOAD_ARCH_STR} ${CMAKE_CURRENT_SOURCE_DIR}/add_Kernel.cpp -o ${CMAKE_CURRENT_BINARY_DIR}/../graph/add_Kernel.code -I${CMAKE_CURRENT_SOURCE_DIR}/../../../../include/ -I${CMAKE_CURRENT_SOURCE_DIR}/../../include --rocm-path=${ROCM_PATH}) + hip_add_exe_to_target(NAME GraphsTest2 TEST_SRC ${TEST_SRC} TEST_TARGET_NAME build_tests) @@ -138,3 +140,5 @@ if(HIP_PLATFORM MATCHES "amd") add_custom_target(hipMatMul COMMAND ${CMAKE_CXX_COMPILER} --genco ${OFFLOAD_ARCH_STR} ${CMAKE_CURRENT_SOURCE_DIR}/hipMatMul.cc -o ${CMAKE_CURRENT_BINARY_DIR}/../../unit/graph/hipMatMul.code -I${CMAKE_CURRENT_SOURCE_DIR}/../../../../include/ -I${CMAKE_CURRENT_SOURCE_DIR}/../../include --rocm-path=${ROCM_PATH}) add_dependencies(build_tests hipMatMul) endif() + +add_dependencies(build_tests add_Kernel.code) diff --git a/projects/hip-tests/catch/unit/graph/add_Kernel.cpp b/projects/hip-tests/catch/unit/graph/add_Kernel.cpp new file mode 100644 index 0000000000..92ffc0a12f --- /dev/null +++ b/projects/hip-tests/catch/unit/graph/add_Kernel.cpp @@ -0,0 +1,24 @@ +/* +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 WARRANNTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNNESS 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 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. +*/ +#include "hip/hip_runtime.h" +extern "C" __global__ void Add(int* a, int* b, int* c) { + size_t tx = (blockIdx.x * blockDim.x + threadIdx.x); + c[tx] = a[tx] + b[tx]; +} + diff --git a/projects/hip-tests/catch/unit/graph/hipGraphAddKernelNode.cc b/projects/hip-tests/catch/unit/graph/hipGraphAddKernelNode.cc index 1f4d96f292..9f030c9807 100644 --- a/projects/hip-tests/catch/unit/graph/hipGraphAddKernelNode.cc +++ b/projects/hip-tests/catch/unit/graph/hipGraphAddKernelNode.cc @@ -1,5 +1,5 @@ /* -Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +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 @@ -18,12 +18,47 @@ 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 -/* Test verifies hipGraphAddKernelNode API Negative scenarios. +#define CODEOBJ_FILE "add_Kernel.code" +#define KERNEL_NAME "Add" +#define THREADS_PER_BLOCK 512 + +/** +* @addtogroup hipGraphAddKernelNode hipModuleLoad hipModuleGetFunction +* @{ +* @ingroup GraphTest +* `hipError_t hipGraphAddKernelNode(hipGraphNode_t* pGraphNode, hipGraph_t graph, + const hipGraphNode_t* pDependencies, size_t numDependencies, + const hipKernelNodeParams* pNodeParams)` - +* Creates a kernel execution node and adds it to a graph +* `hipError_t hipModuleLoad(hipModule_t* module, const char* fname)` - +* Loads code object from file into a module the currrent context +* `hipError_t hipModuleGetFunction(hipFunction_t* function, hipModule_t module, const char* kname)` - +* Function with kname will be extracted if present in module +*/ + +/** + * Test Description + * ------------------------ + * - Test case to verify negative scenarios of hipGraphAddKernelNode API. + * Test source + * ------------------------ + * - catch/unit/graph/hipGraphAddKernelNode.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 */ + +constexpr size_t size = 1 << 12; +enum fnType { + normal, + object +}; + TEST_CASE("Unit_hipGraphAddKernelNode_Negative") { constexpr int N = 1024; size_t NElem{N}; @@ -48,46 +83,46 @@ TEST_CASE("Unit_hipGraphAddKernelNode_Negative") { kNodeParams.kernelParams = reinterpret_cast(kernelArgs); SECTION("Pass pGraphNode as nullptr") { - HIP_CHECK_ERROR(hipGraphAddKernelNode(nullptr, graph, nullptr, 0, &kNodeParams), - hipErrorInvalidValue); + HIP_CHECK_ERROR(hipGraphAddKernelNode(nullptr, graph, nullptr, + 0, &kNodeParams), hipErrorInvalidValue); } SECTION("Pass Graph as nullptr") { - HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, nullptr, nullptr, 0, &kNodeParams), - hipErrorInvalidValue); + HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, nullptr, nullptr, + 0, &kNodeParams), hipErrorInvalidValue); } SECTION("Pass invalid numDependencies") { - HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, graph, nullptr, 11, &kNodeParams), - hipErrorInvalidValue); + HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, graph, nullptr, 11, + &kNodeParams), hipErrorInvalidValue); } SECTION("Pass invalid numDependencies and valid list for dependencies") { HIP_CHECK(hipGraphAddKernelNode(&kNode, graph, nullptr, 0, &kNodeParams)); dependencies.push_back(kNode); HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, graph, dependencies.data(), - dependencies.size() + 1, &kNodeParams), - hipErrorInvalidValue); + dependencies.size() + 1, + &kNodeParams), hipErrorInvalidValue); } SECTION("Pass NodeParams as nullptr") { HIP_CHECK_ERROR( - hipGraphAddKernelNode(&kNode, graph, dependencies.data(), dependencies.size(), nullptr), - hipErrorInvalidValue); + hipGraphAddKernelNode(&kNode, graph, dependencies.data(), + dependencies.size(), nullptr), hipErrorInvalidValue); } #if HT_NVIDIA // on AMD this returns hipErrorInvalidValue SECTION("Pass NodeParams func data member as nullptr") { kNodeParams.func = nullptr; - HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, graph, nullptr, 0, &kNodeParams), - hipErrorInvalidDeviceFunction); + HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, graph, nullptr, 0, + &kNodeParams), hipErrorInvalidDeviceFunction); } #endif SECTION("Pass kernelParams data member as nullptr") { kNodeParams.kernelParams = nullptr; - HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, graph, nullptr, 0, &kNodeParams), - hipErrorInvalidValue); + HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, graph, nullptr, 0, + &kNodeParams), hipErrorInvalidValue); } #if HT_AMD // On Cuda setup this test case getting failed @@ -95,8 +130,8 @@ TEST_CASE("Unit_hipGraphAddKernelNode_Negative") { hipGraph_t destroyed_graph; HIP_CHECK(hipGraphCreate(&destroyed_graph, 0)); HIP_CHECK(hipGraphDestroy(destroyed_graph)); - HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, destroyed_graph, nullptr, 0, &kNodeParams), - hipErrorInvalidValue); + HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, destroyed_graph, nullptr, + 0, &kNodeParams), hipErrorInvalidValue); } #endif @@ -105,3 +140,327 @@ TEST_CASE("Unit_hipGraphAddKernelNode_Negative") { HIP_CHECK(hipFree(C_d)); HIP_CHECK(hipGraphDestroy(graph)); } +#if HT_AMD +static __global__ void Add(int* A_d, int* B_d, int* C_d) { + size_t tx = (blockIdx.x * blockDim.x + threadIdx.x); + C_d[tx] = A_d[tx] + B_d[tx]; +} +static void validateOutput(const hipGraph_t &graph , int* A_h, + int* B_h, int* C_h, + size_t inputSize) { + hipStream_t streamForGraph; + HIP_CHECK(hipStreamCreate(&streamForGraph)); + hipGraphExec_t graphExec; + HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph)); + HIP_CHECK(hipStreamSynchronize(streamForGraph)); + + HIP_CHECK(hipGraphExecDestroy(graphExec)); + HIP_CHECK(hipStreamDestroy(streamForGraph)); + // Verify output + for (size_t i = 0; i < inputSize; i++) { + REQUIRE((A_h[i] + B_h[i]) == C_h[i]); + } +} +static void kernelFnChange(int* A_d, int* A_h, + int* B_d, int* B_h, int* C_d, int* C_h, + size_t inputSize, size_t numOfBlocks, enum fnType fn) { + hipGraph_t graph; + std::vector nodeDependencies; + hipGraphNode_t memcpyNode, memcpyNode1, memcpyNode2, kernelNode; + + hipModule_t Module; + hipFunction_t Function; + HIPCHECK(hipModuleLoad(&Module, CODEOBJ_FILE)); + HIPCHECK(hipModuleGetFunction(&Function, Module, KERNEL_NAME)); + + HIP_CHECK(hipGraphCreate(&graph, 0)); + // Add MemCpy nodes H2D + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyNode, graph, nullptr, 0, A_d, + A_h, sizeof(int)*inputSize, hipMemcpyHostToDevice)); + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyNode1, graph, nullptr, 0, B_d, + B_h, sizeof(int)*inputSize, hipMemcpyHostToDevice)); + nodeDependencies.push_back(memcpyNode); + nodeDependencies.push_back(memcpyNode1); + // kernel node. + hipKernelNodeParams kernelNodeParams{}, kernelNodeParamsUpdate{}; + void* kernelArgs[4] = {reinterpret_cast(&A_d), + reinterpret_cast(&B_d), + reinterpret_cast(&C_d), + &numOfBlocks}; + if (fn == normal) { // normal function + kernelNodeParams.func = reinterpret_cast(Add); + } else { // Code Object function + kernelNodeParams.func = reinterpret_cast(Function); + } + kernelNodeParams.gridDim = dim3(inputSize / THREADS_PER_BLOCK, 1, 1); + kernelNodeParams.blockDim = dim3(THREADS_PER_BLOCK, 1, 1); + kernelNodeParams.sharedMemBytes = 0; + kernelNodeParams.kernelParams = reinterpret_cast(kernelArgs); + kernelNodeParams.extra = nullptr; + HIP_CHECK(hipGraphAddKernelNode(&kernelNode, graph, nodeDependencies.data(), + nodeDependencies.size(), &kernelNodeParams)); + if (fn == normal) { + kernelNodeParamsUpdate.func = reinterpret_cast(Function); + } else { + kernelNodeParamsUpdate.func = reinterpret_cast(Add); + } + kernelNodeParamsUpdate.gridDim = dim3(inputSize / THREADS_PER_BLOCK, 1, 1); + kernelNodeParamsUpdate.blockDim = dim3(THREADS_PER_BLOCK, 1, 1); + kernelNodeParamsUpdate.sharedMemBytes = 0; + kernelNodeParamsUpdate.kernelParams = reinterpret_cast(kernelArgs); + kernelNodeParamsUpdate.extra = nullptr; + HIP_CHECK(hipGraphKernelNodeSetParams(kernelNode, &kernelNodeParamsUpdate)); + nodeDependencies.clear(); + nodeDependencies.push_back(kernelNode); + + // Add MemCpy nodes D2H + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyNode2, graph, + nodeDependencies.data(), nodeDependencies.size(), C_h, + C_d, sizeof(int)*inputSize, hipMemcpyDeviceToHost)); + nodeDependencies.clear(); + + // Validation + validateOutput(graph, A_h, B_h, C_h, inputSize); + + HIP_CHECK(hipGraphDestroy(graph)); + HIPCHECK(hipModuleUnload(Module)); +} +/** + * Test Description + * ------------------------ + * - Test case to verify kernel function output in the graph, cloned graph by adding + * hipGraphAddKernelNode by loading kernerl function through hipModuleLoad, + * hipModuleGetFunction from the code object file. + * Test source + * ------------------------ + * - catch/unit/graph/hipGraphAddKernelNode.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipGraphAddKernelNode_moduleLoadKernelFn_graphNclonedGraph") { + int *A_d, *B_d, *C_d; + int *A_h, *B_h, *C_h; + HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, size, false); + + hipGraph_t graph, clonedGraph; + std::vector nodeDependencies; + hipGraphNode_t memcpyNode, memcpyNode1, memcpyNode2, kernelNode; + HIP_CHECK(hipGraphCreate(&graph, 0)); + + hipModule_t Module; + hipFunction_t Function; + HIPCHECK(hipModuleLoad(&Module, CODEOBJ_FILE)); + HIPCHECK(hipModuleGetFunction(&Function, Module, KERNEL_NAME)); + + // Add MemCpy nodes H2D + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyNode, graph, nullptr, 0, A_d, + A_h, sizeof(int)*size, hipMemcpyHostToDevice)); + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyNode1, graph, nullptr, 0, B_d, + B_h, sizeof(int)*size, hipMemcpyHostToDevice)); + nodeDependencies.push_back(memcpyNode); + nodeDependencies.push_back(memcpyNode1); + + // Add Kernel Node + hipKernelNodeParams kernelNodeParams{}; + void* kernelArgs[3] = {reinterpret_cast(&A_d), + reinterpret_cast(&B_d), + reinterpret_cast(&C_d)}; + kernelNodeParams.func = reinterpret_cast(Function); + kernelNodeParams.gridDim = dim3(size / THREADS_PER_BLOCK, 1, 1); + kernelNodeParams.blockDim = dim3(THREADS_PER_BLOCK, 1, 1); + kernelNodeParams.sharedMemBytes = 0; + kernelNodeParams.kernelParams = reinterpret_cast(kernelArgs); + kernelNodeParams.extra = nullptr; + HIP_CHECK(hipGraphAddKernelNode(&kernelNode, graph, nodeDependencies.data(), + nodeDependencies.size(), &kernelNodeParams)); + nodeDependencies.clear(); + nodeDependencies.push_back(kernelNode); + + // Add MemCpy nodes D2H + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyNode2, graph, + nodeDependencies.data(), nodeDependencies.size(), C_h, + C_d, sizeof(int)*size, hipMemcpyDeviceToHost)); + nodeDependencies.clear(); + SECTION("Original Graph") { + // Original Graph validation + validateOutput(graph, A_h, B_h, C_h, size); + } + SECTION("Cloned Graph") { + // Clone the graph + HIP_CHECK(hipGraphClone(&clonedGraph, graph)); + // Cloned graph Validation + validateOutput(clonedGraph, A_h, B_h, C_h, size); + HIP_CHECK(hipGraphDestroy(clonedGraph)); + } + HIP_CHECK(hipGraphDestroy(graph)); + HIPCHECK(hipModuleUnload(Module)); + HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false); +} +/** + * Test Description + * ------------------------ + * - Test case to verify kernel function output by adding hipGraphAddKernelNode and updating the + * kernel functions from normal to Code object and vice versa in the graph by loading kernerl + * function through hipModuleLoad, hipModuleGetFunction from code object file. + * Test source + * ------------------------ + * - catch/unit/graph/hipGraphAddKernelNode.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipGraphAddKernelNode_moduleLoadKernelFn_kernelFnUpdate") { + size_t maxBlocks = 512; + int *A_d, *B_d, *C_d; // Device pointers + int *A_h, *B_h, *C_h; // Host Pointers + HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, size, false); + + SECTION("Kernel function change from Normal fn to Code object fn") { + kernelFnChange(A_d, A_h, B_d, B_h, C_d, C_h, size, maxBlocks, object); + } + SECTION("Kernel function change from Code object fn to normal fn") { + kernelFnChange(A_d, A_h, B_d, B_h, C_d, C_h, size, maxBlocks, normal); + } + + HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false); +} +/** + * Test Description + * ------------------------ + * - Test case to verify kernel function output in the child graph and cloned graph by adding + * hipGraphAddKernelNode by loading kernerl function through hipModuleLoad, + * hipModuleGetFunction from the code object file. + * Test source + * ------------------------ + * - catch/unit/graph/hipGraphAddKernelNode.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipGraphAddKernelNode_moduleLoadKernelFn_childGraph") { + int *A_d, *B_d, *C_d; // Device pointers + int *A_h, *B_h, *C_h; // Host Pointers + HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, size, false); + + hipGraph_t graph, childgraph, clonedGraph; + std::vector nodeDependencies; + hipGraphNode_t memcpyh2d1, memcpyh2d2, memcpyd2h, childGraphNode, kernelNode; + + hipModule_t Module; + hipFunction_t Function; + HIPCHECK(hipModuleLoad(&Module, CODEOBJ_FILE)); + HIPCHECK(hipModuleGetFunction(&Function, Module, KERNEL_NAME)); + + // Create child graph + HIP_CHECK(hipGraphCreate(&childgraph, 0)); + + // kerrel params. + hipKernelNodeParams kernelNodeParams{}; + void* kernelArgs[3] = {reinterpret_cast(&A_d), + reinterpret_cast(&B_d), + reinterpret_cast(&C_d)}; + kernelNodeParams.func = reinterpret_cast(Function); + kernelNodeParams.gridDim = dim3(size / THREADS_PER_BLOCK, 1, 1); + kernelNodeParams.blockDim = dim3(THREADS_PER_BLOCK, 1, 1); + kernelNodeParams.sharedMemBytes = 0; + kernelNodeParams.kernelParams = reinterpret_cast(kernelArgs); + kernelNodeParams.extra = nullptr; + HIP_CHECK(hipGraphAddKernelNode(&kernelNode, childgraph, nullptr, + 0, &kernelNodeParams)); + + HIP_CHECK(hipGraphCreate(&graph, 0)); + // Add MemCpy nodes H2D + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyh2d1, graph, nullptr, 0, A_d, + A_h, sizeof(int)*size, hipMemcpyHostToDevice)); + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyh2d2, graph, nullptr, 0, B_d, + B_h, sizeof(int)*size, hipMemcpyHostToDevice)); + nodeDependencies.push_back(memcpyh2d1); + nodeDependencies.push_back(memcpyh2d2); + // Add child graph node + HIP_CHECK(hipGraphAddChildGraphNode(&childGraphNode, graph, + nullptr, + 0, childgraph)); + nodeDependencies.push_back(childGraphNode); + + // Add MemCpy nodes D2H + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyd2h, graph, + nodeDependencies.data(), nodeDependencies.size(), C_h, + C_d, sizeof(int)*size, hipMemcpyDeviceToHost)); + nodeDependencies.clear(); + + SECTION("Original Graph") { + // Original Graph validation + validateOutput(graph, A_h, B_h, C_h, size); + } + SECTION("Cloned Graph") { + // Clone the graph + HIP_CHECK(hipGraphClone(&clonedGraph, graph)); + // Cloned Graph validation + validateOutput(clonedGraph, A_h, B_h, C_h, size); + HIP_CHECK(hipGraphDestroy(clonedGraph)); + } + HIP_CHECK(hipGraphDestroy(graph)); + HIPCHECK(hipModuleUnload(Module)); + HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false); +} +/** + * Test Description + * ------------------------ + * - Test case to verify kernel function output in the graph which is created by stream capture. + * The kernel function is loading through hipModuleLoad, hipModuleGetFunction from code object file + * Test source + * ------------------------ + * - catch/unit/graph/hipGraphAddKernelNode.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipGraphAddKernelNode_moduleLoadKernelFn_streamCapture") { + size_t maxBlocks = 512; + size_t Nbytes = sizeof(int)*maxBlocks; + + int *A_d, *B_d, *C_d; // Device pointers + int *A_h, *B_h, *C_h; // Host Pointers + HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, maxBlocks, + false); + + hipGraph_t graph; + hipStream_t stream; + + hipModule_t Module; + hipFunction_t Function; + HIPCHECK(hipModuleLoad(&Module, CODEOBJ_FILE)); + HIPCHECK(hipModuleGetFunction(&Function, Module, KERNEL_NAME)); + + HIP_CHECK(hipStreamCreate(&stream)); + HIP_CHECK(hipStreamBeginCapture(stream, hipStreamCaptureModeGlobal)); + + // MemCpy node H2D + HIP_CHECK(hipMemcpyAsync(A_d, A_h, Nbytes, hipMemcpyHostToDevice, + stream)); + HIP_CHECK(hipMemcpyAsync(B_d, B_h, Nbytes, hipMemcpyHostToDevice, + stream)); + // kerrel params. + void* kernelArgs[] = {&A_d, &B_d, &C_d}; + + // Kernel node + HIP_CHECK(hipModuleLaunchKernel(Function, 1, 1, 1, maxBlocks, 1, 1, 0, + stream, kernelArgs, nullptr)); + + // MemCpy nodes D2H + HIP_CHECK(hipMemcpyAsync(C_h, C_d, Nbytes, hipMemcpyDeviceToHost, + stream)); + HIP_CHECK(hipStreamEndCapture(stream, &graph)); + HIP_CHECK(hipStreamDestroy(stream)); + + // validation + validateOutput(graph, A_h, B_h, C_h, maxBlocks); + + HIP_CHECK(hipGraphDestroy(graph)); + HIPCHECK(hipModuleUnload(Module)); + HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false); +} +#endif + From a1346c114a55f0b8b45d3976fe893d5bfadb43f9 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Sat, 8 Jul 2023 20:54:42 +0530 Subject: [PATCH 06/25] SWDEV-388834 - [catch2][dtest] Kernel tests migrated from direct to catch2 (#345) Change-Id: I8d1d7c6d5db018301cd76f2e38b5997ae91c15db [ROCm/hip-tests commit: a461ae2fc986945b5c4667a257999d2387d6c639] --- .../catch/include/hip_test_defgroups.hh | 9 +- .../catch/unit/kernel/CMakeLists.txt | 18 ++ .../catch/unit/kernel/hipPrintfKernel.cc | 67 +++++ .../catch/unit/kernel/hipTestConstant.cc | 76 ++++++ .../unit/kernel/hipTestGlobalVariable.cc | 101 +++++++ .../catch/unit/kernel/hipTestMemKernel.cc | 248 ++++++++++++++++++ .../catch/unit/kernel/inline_asm_vadd.cc | 136 ++++++++++ .../catch/unit/kernel/inline_asm_vmac.cc | 128 +++++++++ .../catch/unit/kernel/launch_bounds.cc | 102 +++++++ .../catch/unit/kernel/printf_common.h | 99 +++++++ 10 files changed, 983 insertions(+), 1 deletion(-) create mode 100644 projects/hip-tests/catch/unit/kernel/hipPrintfKernel.cc create mode 100644 projects/hip-tests/catch/unit/kernel/hipTestConstant.cc create mode 100644 projects/hip-tests/catch/unit/kernel/hipTestGlobalVariable.cc create mode 100644 projects/hip-tests/catch/unit/kernel/hipTestMemKernel.cc create mode 100644 projects/hip-tests/catch/unit/kernel/inline_asm_vadd.cc create mode 100644 projects/hip-tests/catch/unit/kernel/inline_asm_vmac.cc create mode 100644 projects/hip-tests/catch/unit/kernel/launch_bounds.cc create mode 100644 projects/hip-tests/catch/unit/kernel/printf_common.h diff --git a/projects/hip-tests/catch/include/hip_test_defgroups.hh b/projects/hip-tests/catch/include/hip_test_defgroups.hh index 172f228f84..f4ceedbc1b 100644 --- a/projects/hip-tests/catch/include/hip_test_defgroups.hh +++ b/projects/hip-tests/catch/include/hip_test_defgroups.hh @@ -1,5 +1,5 @@ /* -Copyright (c) 2021 - 2022 Advanced Micro Devices, Inc. All rights reserved. +Copyright (c) 2021 - 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 @@ -100,3 +100,10 @@ THE SOFTWARE. * This section describes the stream management types & functions of HIP runtime API. * @} */ + +/** + * @defgroup KernelTest Kernel Functions Management + * @{ + * This section describes the various kernel functions invocation. + * @} + */ diff --git a/projects/hip-tests/catch/unit/kernel/CMakeLists.txt b/projects/hip-tests/catch/unit/kernel/CMakeLists.txt index 22fef5b29f..77a48363ed 100644 --- a/projects/hip-tests/catch/unit/kernel/CMakeLists.txt +++ b/projects/hip-tests/catch/unit/kernel/CMakeLists.txt @@ -23,7 +23,25 @@ set(TEST_SRC hipMemFaultStackAllocation.cc hipLaunchBounds.cc hipShflTests.cc + hipTestConstant.cc + hipTestGlobalVariable.cc + hipTestMemKernel.cc + launch_bounds.cc + inline_asm_vadd.cc ) +if(UNIX) + set(TEST_SRC ${TEST_SRC} + hipPrintfKernel.cc) +endif() +string(FIND "${OFFLOAD_ARCH_STR}" "gfx1030" RESULT) +if ("${RESULT}" EQUAL "-1") + set(AMD_TEST_SRC + inline_asm_vmac.cc) +endif() + +if(HIP_PLATFORM MATCHES "amd") + set(TEST_SRC ${TEST_SRC} ${AMD_TEST_SRC}) +endif() # only for AMD if(HIP_PLATFORM MATCHES "amd") diff --git a/projects/hip-tests/catch/unit/kernel/hipPrintfKernel.cc b/projects/hip-tests/catch/unit/kernel/hipPrintfKernel.cc new file mode 100644 index 0000000000..da81c767fa --- /dev/null +++ b/projects/hip-tests/catch/unit/kernel/hipPrintfKernel.cc @@ -0,0 +1,67 @@ +/* +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 WARRANNTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNNESS 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 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. +*/ +#include +#include +#include +#include "../kernel/printf_common.h" + +#define HIP_ENABLE_PRINTF + +__global__ void run_printf() { + printf("Hello World\n"); +} +/** +* @addtogroup hipLaunchKernelGGL +* @{ +* @ingroup KernelTest +* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks, + std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` - +* Method to invocate kernel functions +*/ + +/** + * Test Description + * ------------------------ + * - Test case to check printf function via kernel call. + + * Test source + * ------------------------ + * - catch/unit/kernel/hipPrintfKernel.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_kernel_ChkPrintf") { + int device_count = 0; + CaptureStream capture(stdout); + HIP_CHECK(hipGetDeviceCount(&device_count)); + std::string st = "Hello World"; + const char * check = st.c_str(); + for (int i = 0; i < device_count; ++i) { + HIP_CHECK(hipSetDevice(i)); + hipLaunchKernelGGL(run_printf, dim3(1), dim3(1), 0, 0); + HIP_CHECK(hipDeviceSynchronize()); + char* data = new char[st.size()];; + std::ifstream CapturedData = capture.getCapturedData(); + CapturedData.getline(data, st.size()+1); + int result = strcmp(data, check); + REQUIRE(result == 0); + delete [] data; + } +} diff --git a/projects/hip-tests/catch/unit/kernel/hipTestConstant.cc b/projects/hip-tests/catch/unit/kernel/hipTestConstant.cc new file mode 100644 index 0000000000..911457af0f --- /dev/null +++ b/projects/hip-tests/catch/unit/kernel/hipTestConstant.cc @@ -0,0 +1,76 @@ +/* +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 WARRANNTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNNESS 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 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. +*/ +#include +#include + +#define LEN 512 +#define SIZE 2048 + +__constant__ int Value[LEN]; + +static __global__ void Get(int* Ad) { + int tid = threadIdx.x + blockIdx.x * blockDim.x; + Ad[tid] = Value[tid]; +} +/** +* @addtogroup hipLaunchKernelGGL +* @{ +* @ingroup KernelTest +* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks, + std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` - +* Method to invocate kernel functions +*/ + +/** + * Test Description + * ------------------------ + * - Test case to check const variable via kernel call. + + * Test source + * ------------------------ + * - catch/unit/kernel/hipTestConstant.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ + +TEST_CASE("Unit_kernel_chkConstantViaKernel") { + int *A, *B, *Ad; + A = new int[LEN]; + B = new int[LEN]; + for (unsigned i = 0; i < LEN; i++) { + A[i] = -1 * i; + B[i] = 0; + } + + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + + HIP_CHECK(hipMemcpyToSymbol(HIP_SYMBOL(Value), A, SIZE, 0, + hipMemcpyHostToDevice)); + hipLaunchKernelGGL(Get, dim3(1, 1, 1), dim3(LEN, 1, 1), 0, 0, Ad); + HIP_CHECK(hipMemcpy(B, Ad, SIZE, hipMemcpyDeviceToHost)); + + for (unsigned i = 0; i < LEN; i++) { + REQUIRE(A[i] == B[i]); + } + delete [] A; + delete [] B; + HIP_CHECK(hipFree(Ad)); +} + diff --git a/projects/hip-tests/catch/unit/kernel/hipTestGlobalVariable.cc b/projects/hip-tests/catch/unit/kernel/hipTestGlobalVariable.cc new file mode 100644 index 0000000000..a2d99fa8b7 --- /dev/null +++ b/projects/hip-tests/catch/unit/kernel/hipTestGlobalVariable.cc @@ -0,0 +1,101 @@ +/* +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 WARRANNTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNNESS 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 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. +*/ +#include +#include + +#define LEN 512 +#define SIZE 2048 +/** +* @addtogroup hipLaunchKernelGGL +* @{ +* @ingroup KernelTest +* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks, + std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` - +* Method to invocate kernel functions +*/ + +/** + * Test Description + * ------------------------ + * - Test case to check constant global variable and global array via kernel call. + + * Test source + * ------------------------ + * - catch/unit/kernel/hipTestGlobalVariable.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +__constant__ int ConstantGlobalVar = 123; + +static __global__ void kernel(int* Ad) { + int tid = threadIdx.x + blockIdx.x * blockDim.x; + Ad[tid] = ConstantGlobalVar; +} + +void runTestConstantGlobalVar() { + int *A, *Ad; + A = new int[LEN]; + for (unsigned i = 0; i < LEN; i++) { + A[i] = 0; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + hipLaunchKernelGGL(kernel, dim3(1, 1, 1), dim3(LEN, 1, 1), 0, 0, Ad); + HIP_CHECK(hipMemcpy(A, Ad, SIZE, hipMemcpyDeviceToHost)); + + for (unsigned i = 0; i < LEN; i++) { + REQUIRE(123 == A[i]); + } + delete [] A; + HIP_CHECK(hipFree(Ad)); +} + +__device__ int GlobalArray[LEN]; +static __global__ void kernelWrite() { + int tid = threadIdx.x + blockIdx.x * blockDim.x; + GlobalArray[tid] = tid; +} +static __global__ void kernelRead(int* Ad) { + int tid = threadIdx.x + blockIdx.x * blockDim.x; + Ad[tid] = GlobalArray[tid]; +} + +void runTestGlobalArray() { + int *A, *Ad; + A = new int[LEN]; + for (unsigned i = 0; i < LEN; i++) { + A[i] = 0; + } + + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + hipLaunchKernelGGL(kernelWrite, dim3(1, 1, 1), dim3(LEN, 1, 1), 0, 0); + hipLaunchKernelGGL(kernelRead, dim3(1, 1, 1), dim3(LEN, 1, 1), 0, 0, Ad); + HIP_CHECK(hipMemcpy(A, Ad, SIZE, hipMemcpyDeviceToHost)); + + for (unsigned i = 0; i < LEN; i++) { + REQUIRE(i == A[i]); + } + delete [] A; + HIP_CHECK(hipFree(Ad)); +} + +TEST_CASE("Unit_kernel_chkGlobalArrAndGlobalVaribleViaKernelFn") { + runTestConstantGlobalVar(); + runTestGlobalArray(); +} diff --git a/projects/hip-tests/catch/unit/kernel/hipTestMemKernel.cc b/projects/hip-tests/catch/unit/kernel/hipTestMemKernel.cc new file mode 100644 index 0000000000..d97a5698e0 --- /dev/null +++ b/projects/hip-tests/catch/unit/kernel/hipTestMemKernel.cc @@ -0,0 +1,248 @@ +/* +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 WARRANNTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNNESS 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 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. +*/ +#include +#include + +#define LEN8 8 * 4 +#define LEN9 9 * 4 +#define LEN10 10 * 4 +#define LEN11 11 * 4 +#define LEN12 12 * 4 + +__global__ void MemCpy8(uint8_t* In, uint8_t* Out) { + int tid = threadIdx.x + blockIdx.x * blockDim.x; + memcpy(Out + tid * 8, In + tid * 8, 8); +} + +__global__ void MemCpy9(uint8_t* In, uint8_t* Out) { + int tid = threadIdx.x + blockIdx.x * blockDim.x; + memcpy(Out + tid * 9, In + tid * 9, 9); +} + +__global__ void MemCpy10(uint8_t* In, uint8_t* Out) { + int tid = threadIdx.x + blockIdx.x * blockDim.x; + memcpy(Out + tid * 10, In + tid * 10, 10); +} + +__global__ void MemCpy11(uint8_t* In, uint8_t* Out) { + int tid = threadIdx.x + blockIdx.x * blockDim.x; + memcpy(Out + tid * 11, In + tid * 11, 11); +} + +__global__ void MemCpy12(uint8_t* In, uint8_t* Out) { + int tid = threadIdx.x + blockIdx.x * blockDim.x; + memcpy(Out + tid * 12, In + tid * 12, 12); +} + +__global__ void MemSet8(uint8_t* In) { + int tid = threadIdx.x + blockIdx.x * blockDim.x; + memset(In + tid * 8, 1, 8); +} + +__global__ void MemSet9(uint8_t* In) { + int tid = threadIdx.x + blockIdx.x * blockDim.x; + memset(In + tid * 9, 1, 9); +} + +__global__ void MemSet10(uint8_t* In) { + int tid = threadIdx.x + blockIdx.x * blockDim.x; + memset(In + tid * 10, 1, 10); +} + +__global__ void MemSet11(uint8_t* In) { + int tid = threadIdx.x + blockIdx.x * blockDim.x; + memset(In + tid * 11, 1, 11); +} + +__global__ void MemSet12(uint8_t* In) { + int tid = threadIdx.x + blockIdx.x * blockDim.x; + memset(In + tid * 12, 1, 12); +} +/** +* @addtogroup hipLaunchKernelGGL +* @{ +* @ingroup KernelTest +* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks, + std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` - +* Method to invocate kernel functions +*/ + +/** + * Test Description + * ------------------------ + * - Test case to check memcpy and memset via kernel call. + + * Test source + * ------------------------ + * - catch/unit/kernel/hipTestMemKernel.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ + +TEST_CASE("Unit_kernel_MemoryOperationsViaKernels") { + uint8_t *A, *Ad, *B, *Bd, *C, *Cd; + A = new uint8_t[LEN8]; + B = new uint8_t[LEN8]; + C = new uint8_t[LEN8]; + for (uint32_t i = 0; i < LEN8; i++) { + A[i] = i; + B[i] = 0; + C[i] = 0; + } + HIP_CHECK(hipMalloc(&Ad, LEN8)); + HIP_CHECK(hipMalloc(&Bd, LEN8)); + HIP_CHECK(hipMalloc(&Cd, LEN8)); + HIP_CHECK(hipMemcpy(Ad, A, LEN8, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(MemCpy8, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Ad, Bd); + hipLaunchKernelGGL(MemSet8, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Cd); + HIP_CHECK(hipMemcpy(B, Bd, LEN8, hipMemcpyDeviceToHost)); + HIP_CHECK(hipMemcpy(C, Cd, LEN8, hipMemcpyDeviceToHost)); + for (uint32_t i = 0; i < LEN8; i++) { + REQUIRE(A[i] == B[i]); + REQUIRE(C[i] == 1); + } + + delete[] A; + delete[] B; + delete[] C; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + + SECTION("MemCpySet1") { + A = new uint8_t[LEN9]; + B = new uint8_t[LEN9]; + C = new uint8_t[LEN9]; + for (uint32_t i = 0; i < LEN9; i++) { + A[i] = i; + B[i] = 0; + C[i] = 0; + } + HIP_CHECK(hipMalloc(&Ad, LEN9)); + HIP_CHECK(hipMalloc(&Bd, LEN9)); + HIP_CHECK(hipMalloc(&Cd, LEN9)); + HIP_CHECK(hipMemcpy(Ad, A, LEN9, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(MemCpy9, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Ad, Bd); + hipLaunchKernelGGL(MemSet9, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Cd); + HIP_CHECK(hipMemcpy(B, Bd, LEN9, hipMemcpyDeviceToHost)); + HIP_CHECK(hipMemcpy(C, Cd, LEN9, hipMemcpyDeviceToHost)); + for (uint32_t i = 0; i < LEN9; i++) { + REQUIRE(A[i] == B[i]); + REQUIRE(C[i] == 1); + } + + delete[] A; + delete[] B; + delete[] C; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + } + + SECTION("MemCpySet2") { + A = new uint8_t[LEN10]; + B = new uint8_t[LEN10]; + C = new uint8_t[LEN10]; + for (uint32_t i = 0; i < LEN10; i++) { + A[i] = i; + B[i] = 0; + C[i] = 0; + } + HIP_CHECK(hipMalloc(&Ad, LEN10)); + HIP_CHECK(hipMalloc(&Bd, LEN10)); + HIP_CHECK(hipMalloc(&Cd, LEN10)); + HIP_CHECK(hipMemcpy(Ad, A, LEN10, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(MemCpy10, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Ad, Bd); + hipLaunchKernelGGL(MemSet10, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Cd); + HIP_CHECK(hipMemcpy(B, Bd, LEN10, hipMemcpyDeviceToHost)); + HIP_CHECK(hipMemcpy(C, Cd, LEN10, hipMemcpyDeviceToHost)); + for (uint32_t i = 0; i < LEN10; i++) { + REQUIRE(A[i] == B[i]); + REQUIRE(C[i] == 1); + } + + delete[] A; + delete[] B; + delete[] C; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + } + + SECTION("MemCpySet3") { + A = new uint8_t[LEN11]; + B = new uint8_t[LEN11]; + C = new uint8_t[LEN11]; + for (uint32_t i = 0; i < LEN11; i++) { + A[i] = i; + B[i] = 0; + C[i] = 0; + } + HIP_CHECK(hipMalloc(&Ad, LEN11)); + HIP_CHECK(hipMalloc(&Bd, LEN11)); + HIP_CHECK(hipMalloc(&Cd, LEN11)); + HIP_CHECK(hipMemcpy(Ad, A, LEN11, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(MemCpy11, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Ad, Bd); + hipLaunchKernelGGL(MemSet11, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Cd); + HIP_CHECK(hipMemcpy(B, Bd, LEN11, hipMemcpyDeviceToHost)); + HIP_CHECK(hipMemcpy(C, Cd, LEN11, hipMemcpyDeviceToHost)); + for (uint32_t i = 0; i < LEN11; i++) { + REQUIRE(A[i] == B[i]); + REQUIRE(C[i] == 1); + } + + delete[] A; + delete[] B; + delete[] C; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + } + + SECTION("MemCpySet4") { + A = new uint8_t[LEN12]; + B = new uint8_t[LEN12]; + C = new uint8_t[LEN12]; + for (uint32_t i = 0; i < LEN12; i++) { + A[i] = i; + B[i] = 0; + C[i] = 0; + } + HIP_CHECK(hipMalloc(&Ad, LEN12)); + HIP_CHECK(hipMalloc(&Bd, LEN12)); + HIP_CHECK(hipMalloc(&Cd, LEN12)); + HIP_CHECK(hipMemcpy(Ad, A, LEN12, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(MemCpy12, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Ad, Bd); + hipLaunchKernelGGL(MemSet12, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Cd); + HIP_CHECK(hipMemcpy(B, Bd, LEN12, hipMemcpyDeviceToHost)); + HIP_CHECK(hipMemcpy(C, Cd, LEN12, hipMemcpyDeviceToHost)); + for (uint32_t i = 0; i < LEN12; i++) { + REQUIRE(A[i] == B[i]); + REQUIRE(C[i] == 1); + } + + delete[] A; + delete[] B; + delete[] C; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + } +} diff --git a/projects/hip-tests/catch/unit/kernel/inline_asm_vadd.cc b/projects/hip-tests/catch/unit/kernel/inline_asm_vadd.cc new file mode 100644 index 0000000000..29a4d8fe29 --- /dev/null +++ b/projects/hip-tests/catch/unit/kernel/inline_asm_vadd.cc @@ -0,0 +1,136 @@ +/* +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 WARRANNTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNNESS 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 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. +*/ +#include +#include + +#define NUM 1024 +#define THREADS_PER_BLOCK_X 4 + +// Device (Kernel) function, it must be void +__global__ void vadd_asm(float* out, float* in) { + int i = blockDim.x * blockIdx.x + threadIdx.x; + + #ifdef __HIP_PLATFORM_NVIDIA__ + asm volatile("add.f32 %0,%1,%2;" : "=f"(out[i]) : "f"(in[i]), "f"(out[i])); + #endif + + #ifdef __HIP_PLATFORM_AMD__ + asm volatile("v_add_f32_e32 %0, %1, %2" : "=v"(out[i]) : "v"(in[i]), + "v"(out[i])); + #endif +} + +// CPU implementation of Vector Result +void addCPUReference(float* output, float* input) { + for (unsigned int j = 0; j < NUM; j++) { + output[j] = input[j] + output[j]; + } +} +/** +* @addtogroup hipLaunchKernelGGL +* @{ +* @ingroup KernelTest +* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks, + std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` - +* Method to invocate kernel functions +*/ + +/** + * Test Description + * ------------------------ + * - Test case to check inline asm vadd instruction via kernel call. + + * Test source + * ------------------------ + * - catch/unit/kernel/inline_asm_vadd.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ + +TEST_CASE("Unit_kernel_inline_asm_vadd_Functional") { + float* VectorA; + float* ResultVector; + float* VectorB; + + float* gpuVector; + float* gpuResultVector; + + int i; + int errors; + + VectorA = reinterpret_cast(malloc(NUM * sizeof(float))); + ResultVector = reinterpret_cast(malloc(NUM * sizeof(float))); + VectorB = reinterpret_cast(malloc(NUM * sizeof(float))); + + // initialize the input data + for (i = 0; i < NUM; i++) { + VectorA[i] = static_cast(i * 10.0f); + VectorB[i] = static_cast(i * 30.0f); + } + + // allocate the memory on the device side + HIP_CHECK(hipMalloc(reinterpret_cast(&gpuVector), + NUM * sizeof(float))); + HIP_CHECK(hipMalloc(reinterpret_cast(&gpuResultVector), + NUM * sizeof(float))); + + // Memory transfer from host to device + HIP_CHECK(hipMemcpy(gpuVector, VectorA, NUM * sizeof(float), + hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(gpuResultVector, VectorB, NUM * sizeof(float), + hipMemcpyHostToDevice)); + + // Lauching kernel from host + hipLaunchKernelGGL(vadd_asm, dim3(NUM / THREADS_PER_BLOCK_X), + dim3(THREADS_PER_BLOCK_X), 0, 0, + gpuResultVector, gpuVector); + + // Memory transfer from device to host + HIP_CHECK(hipMemcpy(ResultVector, gpuResultVector, NUM * sizeof(float), + hipMemcpyDeviceToHost)); + + // CPU Result computation + addCPUReference(VectorB, VectorA); + + // verify the results + errors = 0; + double eps = 1.0E-3; + for (i = 0; i < NUM; i++) { + if (std::abs(ResultVector[i] - VectorB[i]) > eps) { + errors++; + } + } + if (errors != 0) { + REQUIRE(false); + } else { + REQUIRE(true); + } + + // free the resources on device side + HIP_CHECK(hipFree(gpuVector)); + HIP_CHECK(hipFree(gpuResultVector)); + + HIP_CHECK(hipDeviceReset()); + + // free the resources on host side + free(VectorA); + free(ResultVector); + free(VectorB); +} diff --git a/projects/hip-tests/catch/unit/kernel/inline_asm_vmac.cc b/projects/hip-tests/catch/unit/kernel/inline_asm_vmac.cc new file mode 100644 index 0000000000..e9fbebda37 --- /dev/null +++ b/projects/hip-tests/catch/unit/kernel/inline_asm_vmac.cc @@ -0,0 +1,128 @@ +/* +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 WARRANNTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNNESS 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 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. +*/ +#include +#include + +#define NUM 1024 +#define THREADS_PER_BLOCK_X 4 + +// Device (Kernel) function, it must be void +__global__ void vmac_asm(float* out, float* in, float a) { + int i = blockDim.x * blockIdx.x + threadIdx.x; + asm volatile("v_mac_f32_e32 %0, %2, %3" : "=v"(out[i]) : + "0"(out[i]), "v"(a), "v"(in[i])); +} + +// CPU implementation of saxpy +void addCPUReference(float* output, float* input, float a) { + for (unsigned int j = 0; j < NUM; j++) { + output[j] = a * input[j] + output[j]; + } +} +/** +* @addtogroup hipLaunchKernelGGL +* @{ +* @ingroup KernelTest +* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks, + std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` - +* Method to invocate kernel functions +*/ + +/** + * Test Description + * ------------------------ + * - Test case to check inline asm vmac instruction via kernel call. + + * Test source + * ------------------------ + * - catch/unit/kernel/inline_asm_vmac.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_kernel_inline_asm_vmac_Functional") { + float* VectorA; + float* ResultVector; + float* VectorB; + + float* gpuVector; + float* gpuResultVector; + + const float a = 10.0f; + int i; + int errors; + + VectorA = reinterpret_cast(malloc(NUM * sizeof(float))); + ResultVector = reinterpret_cast(malloc(NUM * sizeof(float))); + VectorB = reinterpret_cast(malloc(NUM * sizeof(float))); + + // initialize the input data + for (i = 0; i < NUM; i++) { + VectorA[i] = static_cast(i * 10.0f); + VectorB[i] = static_cast(i * 30.0f); + } + + // allocate the memory on the device side + HIP_CHECK(hipMalloc(reinterpret_cast(&gpuVector), + NUM * sizeof(float))); + HIP_CHECK(hipMalloc(reinterpret_cast(&gpuResultVector), + NUM * sizeof(float))); + + // Memory transfer from host to device + HIP_CHECK(hipMemcpy(gpuVector, VectorA, NUM * sizeof(float), + hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(gpuResultVector, VectorB, NUM * sizeof(float), + hipMemcpyHostToDevice)); + + // Lauching kernel from host + hipLaunchKernelGGL(vmac_asm, dim3(NUM / THREADS_PER_BLOCK_X), + dim3(THREADS_PER_BLOCK_X), 0, 0, + gpuResultVector, gpuVector, a); + + // Memory transfer from device to host + HIP_CHECK(hipMemcpy(ResultVector, gpuResultVector, NUM * sizeof(float), + hipMemcpyDeviceToHost)); + + // CPU Result computation + addCPUReference(VectorB, VectorA, a); + + // verify the results + errors = 0; + double eps = 1.0E-3; + for (i = 0; i < NUM; i++) { + if (std::abs(ResultVector[i] - VectorB[i]) > eps) { + errors++; + } + } + if (errors != 0) { + REQUIRE(false); + } else { + REQUIRE(true); + } + + // free the resources on device side + HIP_CHECK(hipFree(gpuVector)); + HIP_CHECK(hipFree(gpuResultVector)); + HIP_CHECK(hipDeviceReset()); + + // free the resources on host side + free(VectorA); + free(ResultVector); + free(VectorB); +} diff --git a/projects/hip-tests/catch/unit/kernel/launch_bounds.cc b/projects/hip-tests/catch/unit/kernel/launch_bounds.cc new file mode 100644 index 0000000000..59b1132898 --- /dev/null +++ b/projects/hip-tests/catch/unit/kernel/launch_bounds.cc @@ -0,0 +1,102 @@ +/* +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 WARRANNTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNNESS 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 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. +*/ +#include +#include + +constexpr size_t N = 1024; +int p_blockSize = 256; + +__global__ void +__launch_bounds__(256, 2) + myKern(int* C, const int* A, int N) { + int tid = (blockIdx.x * blockDim.x + threadIdx.x); + + if (tid < N) { + C[tid] = A[tid]; + } +} +/** +* @addtogroup hipLaunchKernelGGL +* @{ +* @ingroup KernelTest +* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks, + std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` - +* Method to invocate kernel functions +*/ + +/** + * Test Description + * ------------------------ + * - Test case to check launch bounds via kernel call. + + * Test source + * ------------------------ + * - catch/unit/kernel/launch_bounds.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ + +TEST_CASE("Unit_kernel_LaunchBounds_Functional") { + size_t Nbytes = N * sizeof(int); + int *A_d, *C_d, *A_h, *C_h; + HIPCHECK(hipMalloc(&A_d, Nbytes)); + HIPCHECK(hipMalloc(&C_d, Nbytes)); + + A_h = reinterpret_cast(malloc(Nbytes)); + C_h = reinterpret_cast(malloc(Nbytes)); + + for (int i = 0; i < N; i++) { + A_h[i] = i * 10; + C_h[i] = 0x0; + } + int blocks = N / p_blockSize; + + HIPCHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice)); + HIPCHECK(hipGetLastError()); + hipLaunchKernelGGL(myKern, dim3(blocks), dim3(p_blockSize), 0, + 0, C_d, A_d, N); + +#ifdef __HIP_PLATFORM_NVIDIA__ + cudaFuncAttributes attrib; + cudaFuncGetAttributes(&attrib, myKern); + printf("binaryVersion = %d\n", attrib.binaryVersion); + printf("cacheModeCA = %d\n", attrib.cacheModeCA); + printf("constSizeBytes = %zu\n", attrib.constSizeBytes); + printf("localSizeBytes = %zud\n", attrib.localSizeBytes); + printf("maxThreadsPerBlock = %d\n", attrib.maxThreadsPerBlock); + printf("numRegs = %d\n", attrib.numRegs); + printf("ptxVersion = %d\n", attrib.ptxVersion); + printf("sharedSizeBytes = %zud\n", attrib.sharedSizeBytes); +#endif + + HIPCHECK(hipDeviceSynchronize()); + HIPCHECK(hipGetLastError()); + HIPCHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + HIPCHECK(hipDeviceSynchronize()); + + for (int i = 0; i < N; i++) { + int goldVal = i * 10; + REQUIRE(C_h[i] == goldVal); + } + HIP_CHECK(hipFree(A_d)); + HIP_CHECK(hipFree(C_d)); + free(A_h); + free(C_h); +} diff --git a/projects/hip-tests/catch/unit/kernel/printf_common.h b/projects/hip-tests/catch/unit/kernel/printf_common.h new file mode 100644 index 0000000000..36c512d2a2 --- /dev/null +++ b/projects/hip-tests/catch/unit/kernel/printf_common.h @@ -0,0 +1,99 @@ +/* +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 _STRESSTEST_PRINTF_COMMON_H_ +#define _STRESSTEST_PRINTF_COMMON_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct CaptureStream { + int saved_fd; + int orig_fd; + int temp_fd; + + char tempname[13] = "mytestXXXXXX"; + + explicit CaptureStream(FILE *original) { + orig_fd = fileno(original); + saved_fd = dup(orig_fd); + + if ((temp_fd = mkstemp(tempname)) == -1) { + error(0, errno, "Error"); + assert(false); + } + + fflush(nullptr); + if (dup2(temp_fd, orig_fd) == -1) { + error(0, errno, "Error"); + assert(false); + } + if (close(temp_fd) != 0) { + error(0, errno, "Error"); + assert(false); + } + } + + void restoreStream() { + if (saved_fd == -1) + return; + fflush(nullptr); + if (dup2(saved_fd, orig_fd) == -1) { + error(0, errno, "Error"); + assert(false); + } + if (close(saved_fd) != 0) { + error(0, errno, "Error"); + assert(false); + } + saved_fd = -1; + } + + const char *getTempFilename() { + return (const char*)tempname; + } + + std::ifstream getCapturedData() { + restoreStream(); + std::ifstream temp(tempname); + return temp; + } + + ~CaptureStream() { + restoreStream(); + if (remove(tempname) != 0) { + error(0, errno, "Error"); + assert(false); + } + } +}; + +#endif // _STRESSTEST_PRINTF_COMMON_H_ From dac192e64bc2fcb1c85d6640bcb90380a89bd902 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Sat, 8 Jul 2023 20:55:09 +0530 Subject: [PATCH 07/25] SWDEV-405157 - Rewrite sample 11_texture_driver to use texture objects (#348) Change-Id: I107bfc06fabd62f43e6665b8b038226fe2154fc5 [ROCm/hip-tests commit: c60a07656f4a97a9937c7889f2abd045c77719cd] --- .../11_texture_driver/tex2dKernel.cpp | 42 +++++------ .../11_texture_driver/texture2dDrv.cpp | 69 +++++++++++-------- 2 files changed, 57 insertions(+), 54 deletions(-) diff --git a/projects/hip-tests/samples/2_Cookbook/11_texture_driver/tex2dKernel.cpp b/projects/hip-tests/samples/2_Cookbook/11_texture_driver/tex2dKernel.cpp index d20b1d0864..b434eab33e 100644 --- a/projects/hip-tests/samples/2_Cookbook/11_texture_driver/tex2dKernel.cpp +++ b/projects/hip-tests/samples/2_Cookbook/11_texture_driver/tex2dKernel.cpp @@ -21,76 +21,66 @@ THE SOFTWARE. */ #include "hip/hip_runtime.h" -texture texChar; -texture texShort; -texture texInt; -texture texFloat; - -texture texChar4; -texture texShort4; -texture texInt4; -texture texFloat4; - -extern "C" __global__ void tex2dKernelChar(char* outputData, int width, int height) { +extern "C" __global__ void tex2dKernelChar(char* outputData,hipTextureObject_t texObj, int width, int height) { #if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT int x = blockIdx.x * blockDim.x + threadIdx.x; int y = blockIdx.y * blockDim.y + threadIdx.y; - outputData[y * width + x] = tex2D(texChar, x, y); + outputData[y * width + x] = tex2D(texObj, x, y); #endif } -extern "C" __global__ void tex2dKernelShort(short* outputData, int width, int height) { +extern "C" __global__ void tex2dKernelShort(short* outputData,hipTextureObject_t texObj, int width, int height) { #if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT int x = blockIdx.x * blockDim.x + threadIdx.x; int y = blockIdx.y * blockDim.y + threadIdx.y; - outputData[y * width + x] = tex2D(texShort, x, y); + outputData[y * width + x] = tex2D(texObj, x, y); #endif } -extern "C" __global__ void tex2dKernelInt(int* outputData, int width, int height) { +extern "C" __global__ void tex2dKernelInt(int* outputData,hipTextureObject_t texObj ,int width, int height) { #if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT int x = blockIdx.x * blockDim.x + threadIdx.x; int y = blockIdx.y * blockDim.y + threadIdx.y; - outputData[y * width + x] = tex2D(texInt, x, y); + outputData[y * width + x] = tex2D(texObj, x, y); #endif } -extern "C" __global__ void tex2dKernelFloat(float* outputData, int width, int height) { +extern "C" __global__ void tex2dKernelFloat(float* outputData,hipTextureObject_t texObj, int width, int height) { #if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT int x = blockIdx.x * blockDim.x + threadIdx.x; int y = blockIdx.y * blockDim.y + threadIdx.y; - outputData[y * width + x] = tex2D(texFloat, x, y); + outputData[y * width + x] = tex2D(texObj, x, y); #endif } -extern "C" __global__ void tex2dKernelChar4(char4* outputData, int width, int height) { +extern "C" __global__ void tex2dKernelChar4(char4* outputData,hipTextureObject_t texObj, int width, int height) { #if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT int x = blockIdx.x * blockDim.x + threadIdx.x; int y = blockIdx.y * blockDim.y + threadIdx.y; - outputData[y * width + x] = tex2D(texChar4, x, y); + outputData[y * width + x] = tex2D(texObj, x, y); #endif } -extern "C" __global__ void tex2dKernelShort4(short4* outputData, int width, int height) { +extern "C" __global__ void tex2dKernelShort4(short4* outputData,hipTextureObject_t texObj, int width, int height) { #if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT int x = blockIdx.x * blockDim.x + threadIdx.x; int y = blockIdx.y * blockDim.y + threadIdx.y; - outputData[y * width + x] = tex2D(texShort4, x, y); + outputData[y * width + x] = tex2D(texObj, x, y); #endif } -extern "C" __global__ void tex2dKernelInt4(int4* outputData, int width, int height) { +extern "C" __global__ void tex2dKernelInt4(int4* outputData,hipTextureObject_t texObj, int width, int height) { #if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT int x = blockIdx.x * blockDim.x + threadIdx.x; int y = blockIdx.y * blockDim.y + threadIdx.y; - outputData[y * width + x] = tex2D(texInt4, x, y); + outputData[y * width + x] = tex2D(texObj, x, y); #endif } -extern "C" __global__ void tex2dKernelFloat4(float4* outputData, int width, int height) { +extern "C" __global__ void tex2dKernelFloat4(float4* outputData,hipTextureObject_t texObj, int width, int height) { #if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT int x = blockIdx.x * blockDim.x + threadIdx.x; int y = blockIdx.y * blockDim.y + threadIdx.y; - outputData[y * width + x] = tex2D(texFloat4, x, y); + outputData[y * width + x] = tex2D(texObj, x, y); #endif } diff --git a/projects/hip-tests/samples/2_Cookbook/11_texture_driver/texture2dDrv.cpp b/projects/hip-tests/samples/2_Cookbook/11_texture_driver/texture2dDrv.cpp index fbeac3d41a..f03b3873bf 100644 --- a/projects/hip-tests/samples/2_Cookbook/11_texture_driver/texture2dDrv.cpp +++ b/projects/hip-tests/samples/2_Cookbook/11_texture_driver/texture2dDrv.cpp @@ -65,6 +65,19 @@ static inline constexpr int rank() { return sizeof(T) / sizeof(decltype(T::x)); } +#ifdef __HIP_PLATFORM_NVIDIA__ +template ::value || + std::is_same::value || + std::is_same::value || + std::is_same::value>::type *t = nullptr> +static inline bool operator!=(const T& a, const T& b) +{ + return (a.x != b.x) || (a.y != b.y) || (a.z != b.z) || (a.w != b.w); +} +#endif + + template static inline T getRandom() { double r = 0; @@ -139,43 +152,42 @@ bool runTest(hipModule_t &module, const char *refName, const char *funcName) { } } - hipArray *array; - HIP_ARRAY_DESCRIPTOR desc; - desc.Format = format; - desc.NumChannels = channels; - desc.Width = width; - desc.Height = height; - HIP_CHECK(hipArrayCreate(&array, &desc)); + hipChannelFormatDesc channelDesc = hipCreateChannelDesc(); + hipArray_t array; + HIP_CHECK(hipMallocArray(&array, &channelDesc, width, height)); - hip_Memcpy2D copyParam; - memset(©Param, 0, sizeof(copyParam)); - copyParam.dstMemoryType = hipMemoryTypeArray; - copyParam.dstArray = array; - copyParam.srcMemoryType = hipMemoryTypeHost; - copyParam.srcHost = hData; - copyParam.srcPitch = width * sizeof(T); - copyParam.WidthInBytes = copyParam.srcPitch; - copyParam.Height = height; - HIP_CHECK(hipMemcpyParam2D(©Param)); + const size_t spitch = width * sizeof(T); - textureReference *texref; - HIP_CHECK(hipModuleGetTexRef(&texref, module, refName)); - HIP_CHECK(hipTexRefSetAddressMode(texref, 0, hipAddressModeClamp)); - HIP_CHECK(hipTexRefSetAddressMode(texref, 1, hipAddressModeClamp)); - HIP_CHECK(hipTexRefSetFilterMode(texref, hipFilterModePoint)); - HIP_CHECK(hipTexRefSetFlags(texref, HIP_TRSF_READ_AS_INTEGER)); - HIP_CHECK(hipTexRefSetFormat(texref, format, channels)); - HIP_CHECK(hipTexRefSetArray(texref, array, HIP_TRSA_OVERRIDE_FORMAT)); + HIP_CHECK(hipMemcpy2DToArray(array, 0, 0, hData, spitch, width * sizeof(T), + height, hipMemcpyHostToDevice)); + + hipResourceDesc resDesc; + memset(&resDesc, 0, sizeof(resDesc)); + resDesc.resType = hipResourceTypeArray; + resDesc.res.array.array = array; + + hipTextureDesc texDesc; + memset(&texDesc, 0, sizeof(texDesc)); + texDesc.addressMode[0] = hipAddressModeClamp; + texDesc.addressMode[1] = hipAddressModeClamp; + texDesc.filterMode = hipFilterModePoint; + texDesc.readMode = hipReadModeElementType; + texDesc.normalizedCoords = 0; + + hipTextureObject_t texObj; + HIP_CHECK(hipCreateTextureObject(&texObj, &resDesc, &texDesc, nullptr)); T *dData = NULL; HIP_CHECK(hipMalloc((void** )&dData, size)); struct { void *_Ad; + hipTextureObject_t _texObj; unsigned int _Bd; unsigned int _Cd; } args; args._Ad = (void*) dData; + args._texObj = texObj; args._Bd = width; args._Cd = height; @@ -192,7 +204,7 @@ bool runTest(hipModule_t &module, const char *refName, const char *funcName) { HIP_CHECK( hipModuleLaunchKernel(Function, 16, 16, 1, temp1, temp2, 1, 0, 0, NULL, (void** )&config)); - hipDeviceSynchronize(); + HIP_CHECK(hipDeviceSynchronize()); T *hOutputData = (T*) malloc(size); memset(hOutputData, 0, size); @@ -207,7 +219,7 @@ bool runTest(hipModule_t &module, const char *refName, const char *funcName) { } } } - HIP_CHECK(hipUnbindTexture(texref)); + HIP_CHECK(hipDestroyTextureObject(texObj)); HIP_CHECK(hipFree(dData)); HIP_CHECK(hipFreeArray(array)); free(hOutputData); @@ -230,7 +242,8 @@ int main(int argc, char** argv) { printf("Texture is not support on the device. Skipped.\n"); return 0; } - hipInit(0); + HIP_CHECK(hipInit(0)); + HIP_CHECK(hipSetDevice(0)); hipModule_t module; HIP_CHECK(hipModuleLoad(&module, fileName)); testResult = testResult && runTest(module, "texChar", "tex2dKernelChar"); From 4e3f45443cf6f428fd3cc0711d3817ddf113d1e1 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Sat, 8 Jul 2023 20:55:39 +0530 Subject: [PATCH 08/25] SWDEV-403768 - Enable test (#349) Change-Id: I64e446d71e92898d74bdfa8acdb76d4de8aa29ab [ROCm/hip-tests commit: d6b0f53ac7e68c182b9aaab5295217552327c1dc] --- .../catch/hipTestMain/config/config_amd_linux_common.json | 1 - 1 file changed, 1 deletion(-) diff --git a/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json b/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json index 3a0014bedb..1a3df8cc4c 100644 --- a/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json +++ b/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json @@ -39,7 +39,6 @@ "Unit_hipDrvMemcpy3DAsync_Positive_Array", "Unit_hipMemRangeGetAttribute_Positive_AccessedBy_Basic", "Unit_hipMemRangeGetAttribute_Positive_AccessedBy_Partial_Range", - "Unit_hipMemRangeGetAttributes_Negative_Parameters", "Unit_hipStreamAttachMemAsync_Positive_Basic", "Unit_hipStreamAttachMemAsync_Positive_AttachGlobal", "Unit_hipStreamAttachMemAsync_Negative_Parameters", From 8f7d58e3b96416d6bfb3cfc3bdd8696250581d5b Mon Sep 17 00:00:00 2001 From: Jatin Chaudhary <51944368+cjatin@users.noreply.github.com> Date: Sat, 8 Jul 2023 16:25:55 +0100 Subject: [PATCH 09/25] SWDEV-397031 - fix device functions as well (#352) Change-Id: I9081a5497c89b563c3761e533bb9ee03d61f5867 [ROCm/hip-tests commit: 3e1169eb511d6ce3c5c779c814cca014e07da7e5] --- .../15_static_library/device_functions/hipMain2.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/projects/hip-tests/samples/2_Cookbook/15_static_library/device_functions/hipMain2.cpp b/projects/hip-tests/samples/2_Cookbook/15_static_library/device_functions/hipMain2.cpp index a3c3f8f164..fafbf5a72d 100644 --- a/projects/hip-tests/samples/2_Cookbook/15_static_library/device_functions/hipMain2.cpp +++ b/projects/hip-tests/samples/2_Cookbook/15_static_library/device_functions/hipMain2.cpp @@ -23,8 +23,15 @@ #include #include #include +#include -#define HIP_ASSERT(status) assert(status == hipSuccess) +#define HIP_ASSERT(status) \ + { \ + if ((status != hipSuccess)) { \ + std::cerr << "Failed in: " << __LINE__ << " on hip call: " #status << std::endl; \ + throw std::runtime_error("generic failure"); \ + } \ + } #define LEN 512 extern __device__ int square_me(int); From f8d26ea3478c76790bb28b054688db057cb6d0c1 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Sat, 8 Jul 2023 20:56:17 +0530 Subject: [PATCH 10/25] SWDEV-404445 - [catch2][dtest] Adding test cases for uniform/non-uniform workgroup feature (#355) Change-Id: I6d0764c1a42e08034158b9138695fee7bdc3f93e [ROCm/hip-tests commit: dce969d702c39dbb4df1834b504853394e52e765] --- projects/hip-tests/catch/unit/CMakeLists.txt | 1 + .../catch/unit/module/CMakeLists.txt | 48 ++++ .../hip-tests/catch/unit/module/copyKernel.cc | 29 +++ .../unit/module/hipExtModuleLaunchKernel.cc | 239 ++++++++++++++++++ 4 files changed, 317 insertions(+) create mode 100644 projects/hip-tests/catch/unit/module/CMakeLists.txt create mode 100644 projects/hip-tests/catch/unit/module/copyKernel.cc create mode 100644 projects/hip-tests/catch/unit/module/hipExtModuleLaunchKernel.cc diff --git a/projects/hip-tests/catch/unit/CMakeLists.txt b/projects/hip-tests/catch/unit/CMakeLists.txt index 06739c623a..4426b79b64 100644 --- a/projects/hip-tests/catch/unit/CMakeLists.txt +++ b/projects/hip-tests/catch/unit/CMakeLists.txt @@ -36,6 +36,7 @@ add_subdirectory(compiler) add_subdirectory(errorHandling) add_subdirectory(cooperativeGrps) add_subdirectory(context) +add_subdirectory(module) if(HIP_PLATFORM STREQUAL "amd") add_subdirectory(callback) #add_subdirectory(clock) diff --git a/projects/hip-tests/catch/unit/module/CMakeLists.txt b/projects/hip-tests/catch/unit/module/CMakeLists.txt new file mode 100644 index 0000000000..eb9e2d699f --- /dev/null +++ b/projects/hip-tests/catch/unit/module/CMakeLists.txt @@ -0,0 +1,48 @@ +# 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. + +# Common Tests - Test independent of all platforms +if(HIP_PLATFORM MATCHES "amd") +set(TEST_SRC + hipExtModuleLaunchKernel.cc +) + +# Note to pass arch use format like -DOFFLOAD_ARCH_STR="--offload-arch=gfx900 --offload-arch=gfx906" +# having space at the start/end of OFFLOAD_ARCH_STR can cause build failures + +add_custom_target(copyKernel.code + COMMAND ${CMAKE_CXX_COMPILER} -mcode-object-version=5 --genco ${OFFLOAD_ARCH_STR} + ${CMAKE_CURRENT_SOURCE_DIR}/copyKernel.cc + -o ${CMAKE_CURRENT_BINARY_DIR}/../../unit/module/copyKernel.code + -I${CMAKE_CURRENT_SOURCE_DIR}/../../../../include/ + -I${CMAKE_CURRENT_SOURCE_DIR}/../../include --rocm-path=${ROCM_PATH}) + +add_custom_target(copyKernel.s + COMMAND ${CMAKE_CXX_COMPILER} -mcode-object-version=5 -S ${CMAKE_CURRENT_SOURCE_DIR}/copyKernel.cc + -o ${CMAKE_CURRENT_BINARY_DIR}/../../unit/module/copyKernel.s + -I${CMAKE_CURRENT_SOURCE_DIR}/../../../../include/ + -I${CMAKE_CURRENT_SOURCE_DIR}/../../include --rocm-path=${ROCM_PATH}) + +hip_add_exe_to_target(NAME ModuleTest + TEST_SRC ${TEST_SRC} + TEST_TARGET_NAME build_tests COMMON_SHARED_SRC ${COMMON_SHARED_SRC}) + +add_dependencies(build_tests copyKernel.code copyKernel.s) +endif() diff --git a/projects/hip-tests/catch/unit/module/copyKernel.cc b/projects/hip-tests/catch/unit/module/copyKernel.cc new file mode 100644 index 0000000000..cf006629f2 --- /dev/null +++ b/projects/hip-tests/catch/unit/module/copyKernel.cc @@ -0,0 +1,29 @@ +/* +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 "hip/hip_runtime.h" + +extern "C" __global__ void copy_ker(int* Ad, int *Bd, size_t size) { + int myId = threadIdx.x + blockDim.x * blockIdx.x; + if (myId < size) { + Bd[myId] = Ad[myId]; + } +} diff --git a/projects/hip-tests/catch/unit/module/hipExtModuleLaunchKernel.cc b/projects/hip-tests/catch/unit/module/hipExtModuleLaunchKernel.cc new file mode 100644 index 0000000000..b8bceb26ee --- /dev/null +++ b/projects/hip-tests/catch/unit/module/hipExtModuleLaunchKernel.cc @@ -0,0 +1,239 @@ +/* +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. +*/ + +/** + * @addtogroup hipExtModuleLaunchKernel hipExtModuleLaunchKernel + * @{ + * @ingroup KernelTest + * `hipError_t hipExtModuleLaunchKernel (hipFunction_t f, + * uint32_t globalWorkSizeX, + * uint32_t globalWorkSizeY, + * uint32_t globalWorkSizeZ, + * uint32_t localWorkSizeX, + * uint32_t localWorkSizeY, + * uint32_t localWorkSizeZ, + * size_t sharedMemBytes, + * hipStream_t hStream, + * void ** kernelParams, + * void ** extra, + * hipEvent_t startEvent = nullptr, + * hipEvent_t stopEvent = nullptr, + * uint32_t flags = 0 + * )` - + * Launches kernel with parameters and shared memory on stream with arguments + * passed to kernel params or extra arguments. + */ + +#include +#include +#include +#include +#include "hip/hip_ext.h" +#include // NOLINT + +static constexpr auto totalWorkGroups{1024}; +static constexpr auto localWorkSize{512}; +static constexpr auto lastWorkSizeEven{256}; +static constexpr auto lastWorkSizeOdd{257}; + +#define fileName "copyKernel.code" +#define kernel_name "copy_ker" + +/** + Local Function to search a string in file. +*/ +static bool searchRegExpr(const std::regex& expr, const char* filename) { + std::ifstream assemblyfile(filename, std::ifstream::binary); + REQUIRE(true == assemblyfile.is_open()); + + // Copy the contents of the file to buffer + assemblyfile.seekg(0, assemblyfile.end); + int len = assemblyfile.tellg(); + assemblyfile.seekg(0, assemblyfile.beg); + char *fbuf = new char[len + 1]; + assemblyfile.read(fbuf, len); + fbuf[len] = '\0'; + + // Search for uniform_work_group_size + std::smatch pattern; + std::string assemblyStr = fbuf; + bool bfound = std::regex_search(assemblyStr, pattern, expr); + delete[] fbuf; + assemblyfile.close(); + return bfound; +} +/** + * Test Description + * ------------------------ + * - Parse the Code Object Assembly file copyKernel.s and verify + * if .uniform_work_group_size metadata is available. + * ------------------------ + * - catch\unit\module\hipExtModuleLaunchKernel.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.7 + */ +TEST_CASE("Unit_hipExtModuleLaunchKernel_CheckCodeObjAttr") { + // Open copyKernel.s and read the file + const std::regex regexp("uniform_work_group_size\\s*:\\s*[0-1]"); + REQUIRE(true == searchRegExpr(regexp, "copyKernel.s")); +} + +/** + * Test Description + * ------------------------ + * - Precondition: .uniform_work_group_size = 1. Which means uniform workgroup + * is enforced. + * - Create a buffer of size globalWorkSizeX = (non multiple of localWorkSizeX) + * and launch a kernel to perform some operations on it. If uniform work grouping + * is enforced then hipExtModuleLaunchKernel returns hipErrorInvalidValue. + * Test source + * ------------------------ + * - catch\unit\module\hipExtModuleLaunchKernel.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.7 + */ +TEST_CASE("Unit_hipExtModuleLaunchKernel_NonUniformWorkGroup") { + // first check if uniform_work_group_size = 1. + const std::regex regexp("uniform_work_group_size\\s*:\\s*1"); + if (false == searchRegExpr(regexp, "copyKernel.s")) { + HipTest::HIP_SKIP_TEST("uniform_work_group_size != 1. Skipping test ..."); + return; + } + REQUIRE(true == searchRegExpr(regexp, "copyKernel.s")); + auto isEven = GENERATE(0, 1); + // Calculate size + auto lastWorkSize = isEven ? lastWorkSizeEven : lastWorkSizeOdd; + size_t arraylength = + (totalWorkGroups - 1)*localWorkSize + lastWorkSize; + size_t sizeBytes{arraylength * sizeof(int)}; + // Get module and function from module + hipModule_t Module; + hipFunction_t Function; + HIP_CHECK(hipModuleLoad(&Module, fileName)); + HIP_CHECK(hipModuleGetFunction(&Function, Module, kernel_name)); + // Allocate resources + int *A = new int[arraylength]; + REQUIRE(A != nullptr); + int *B = new int[arraylength]; + REQUIRE(B != nullptr); + // Inititialize data + for (size_t i = 0; i < arraylength; i++) { + A[i] = i; + } + int *Ad, *Bd; + HIP_CHECK(hipMalloc(&Ad, sizeBytes)); + HIP_CHECK(hipMalloc(&Bd, sizeBytes)); + struct { + void* _Ad; + void* _Bd; + size_t buffersize; + } args; + + args._Ad = Ad; + args._Bd = Bd; + args.buffersize = arraylength; + size_t size = sizeof(args); + + void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args, + HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, + HIP_LAUNCH_PARAM_END}; + // Memcpy from A to Ad + HIP_CHECK(hipMemcpy(Ad, A, sizeBytes, hipMemcpyDefault)); + REQUIRE(hipErrorInvalidValue == hipExtModuleLaunchKernel(Function, + arraylength, 1, 1, localWorkSize, 1, 1, 0, 0, NULL, + reinterpret_cast(&config), 0)); + HIP_CHECK(hipDeviceSynchronize()); + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + delete[] A; + delete[] B; + HIP_CHECK(hipModuleUnload(Module)); +} + +/** + * Test Description + * ------------------------ + * - Create a buffer of size globalWorkSizeX = (multiple of localWorkSizeX) + * and launch a kernel to perform some operations on it. Verify the output. This + * operation should be allowed for both uniform_work_group_size = true/false. + * + * Test source + * ------------------------ + * - catch\unit\module\hipExtModuleLaunchKernel.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.7 + */ +TEST_CASE("Unit_hipExtModuleLaunchKernel_UniformWorkGroup") { + size_t arraylength = totalWorkGroups * localWorkSize; + size_t sizeBytes{arraylength * sizeof(int)}; + // Get module and function from module + hipModule_t Module; + hipFunction_t Function; + HIP_CHECK(hipModuleLoad(&Module, fileName)); + HIP_CHECK(hipModuleGetFunction(&Function, Module, kernel_name)); + // Allocate resources + int *A = new int[arraylength]; + REQUIRE(A != nullptr); + int *B = new int[arraylength]; + REQUIRE(B != nullptr); + // Inititialize data + for (size_t i = 0; i < arraylength; i++) { + A[i] = i; + } + int *Ad, *Bd; + HIP_CHECK(hipMalloc(&Ad, sizeBytes)); + HIP_CHECK(hipMalloc(&Bd, sizeBytes)); + struct { + void* _Ad; + void* _Bd; + size_t buffersize; + } args; + + args._Ad = Ad; + args._Bd = Bd; + args.buffersize = arraylength; + size_t size = sizeof(args); + + void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args, + HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, + HIP_LAUNCH_PARAM_END}; + // Memcpy from A to Ad + HIP_CHECK(hipMemcpy(Ad, A, sizeBytes, hipMemcpyDefault)); + HIP_CHECK(hipExtModuleLaunchKernel(Function, arraylength, 1, 1, + localWorkSize, 1, 1, 0, 0, NULL, + reinterpret_cast(&config), 0)); + // Memcpy results back to host + HIP_CHECK(hipMemcpy(B, Bd, sizeBytes, hipMemcpyDefault)); + HIP_CHECK(hipDeviceSynchronize()); + // Verify results + for (size_t i = 0; i < arraylength; i++) { + REQUIRE(B[i] == i); + } + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + delete[] A; + delete[] B; + HIP_CHECK(hipModuleUnload(Module)); +} From d407c5799b7dc38629b0de4c6875c5d36013ec7b Mon Sep 17 00:00:00 2001 From: Maneesh Gupta Date: Sat, 8 Jul 2023 21:12:54 +0530 Subject: [PATCH 11/25] Fix build breakage in vulkan tests Fix bug introduced by #341. Move vulkan/vulkan_win32.h include to _WIN64 only section. [ROCm/hip-tests commit: 2c41a3a34d6e57041c77075fb20ba9c9357ececf] --- projects/hip-tests/catch/unit/vulkan_interop/vulkan_test.hh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/projects/hip-tests/catch/unit/vulkan_interop/vulkan_test.hh b/projects/hip-tests/catch/unit/vulkan_interop/vulkan_test.hh index 82123958f6..5c6089462a 100644 --- a/projects/hip-tests/catch/unit/vulkan_interop/vulkan_test.hh +++ b/projects/hip-tests/catch/unit/vulkan_interop/vulkan_test.hh @@ -21,7 +21,6 @@ THE SOFTWARE. #include - #ifdef _WIN64 #include @@ -33,10 +32,10 @@ THE SOFTWARE. #include #include #include +#include #endif -#include #include #include #include @@ -334,4 +333,4 @@ VulkanTest::MappedBuffer VulkanTest::CreateMappedStorage(uint32_t count, // Sometimes in CUDA the stream is not immediately ready after a semaphore has been signaled void PollStream(hipStream_t stream, hipError_t expected, uint32_t num_iterations = 5); -hipExternalSemaphore_t ImportBinarySemaphore(VulkanTest& vkt); \ No newline at end of file +hipExternalSemaphore_t ImportBinarySemaphore(VulkanTest& vkt); From 15b519869c46a2dc7d697db7df2498da79340f91 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Sun, 9 Jul 2023 08:53:17 +0530 Subject: [PATCH 12/25] SWDEV-388833 - [catch2][dtest] g++ test migrated from dtests to catch2 (#353) Change-Id: I6f23fa88dc6066c2c779348c245a1eb69fb807cb [ROCm/hip-tests commit: a50aaea8031a519242ac27f071e34b9a2d534cc1] --- .../catch/include/hip_test_defgroups.hh | 9 +++- projects/hip-tests/catch/unit/CMakeLists.txt | 2 + .../hip-tests/catch/unit/g++/CMakeLists.txt | 19 +++++++ .../hip-tests/catch/unit/g++/hipMalloc.cc | 49 +++++++++++++++++++ .../hip-tests/catch/unit/g++/hipMalloc.cpp | 35 +++++++++++++ projects/hip-tests/catch/unit/g++/hipMalloc.h | 22 +++++++++ 6 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 projects/hip-tests/catch/unit/g++/CMakeLists.txt create mode 100644 projects/hip-tests/catch/unit/g++/hipMalloc.cc create mode 100644 projects/hip-tests/catch/unit/g++/hipMalloc.cpp create mode 100644 projects/hip-tests/catch/unit/g++/hipMalloc.h diff --git a/projects/hip-tests/catch/include/hip_test_defgroups.hh b/projects/hip-tests/catch/include/hip_test_defgroups.hh index f4ceedbc1b..83d2c4610b 100644 --- a/projects/hip-tests/catch/include/hip_test_defgroups.hh +++ b/projects/hip-tests/catch/include/hip_test_defgroups.hh @@ -102,7 +102,14 @@ THE SOFTWARE. */ /** - * @defgroup KernelTest Kernel Functions Management + * @defgroup MemoryTest memory Management APIs + * @{ + * This section describes the memory management types & functions of HIP runtime API. + * @} + */ + +/** +* @defgroup KernelTest Kernel Functions Management * @{ * This section describes the various kernel functions invocation. * @} diff --git a/projects/hip-tests/catch/unit/CMakeLists.txt b/projects/hip-tests/catch/unit/CMakeLists.txt index 4426b79b64..ae5c866e32 100644 --- a/projects/hip-tests/catch/unit/CMakeLists.txt +++ b/projects/hip-tests/catch/unit/CMakeLists.txt @@ -36,7 +36,9 @@ add_subdirectory(compiler) add_subdirectory(errorHandling) add_subdirectory(cooperativeGrps) add_subdirectory(context) +add_subdirectory(g++) add_subdirectory(module) + if(HIP_PLATFORM STREQUAL "amd") add_subdirectory(callback) #add_subdirectory(clock) diff --git a/projects/hip-tests/catch/unit/g++/CMakeLists.txt b/projects/hip-tests/catch/unit/g++/CMakeLists.txt new file mode 100644 index 0000000000..5adf876616 --- /dev/null +++ b/projects/hip-tests/catch/unit/g++/CMakeLists.txt @@ -0,0 +1,19 @@ +# AMD specific test +if(HIP_PLATFORM MATCHES "amd") +if(UNIX) +set(TEST_SRC + hipMalloc.cc +) +# Creating Custom object file +add_custom_target(malloc_custom COMMAND g++ -c ${CMAKE_CURRENT_SOURCE_DIR}/hipMalloc.cpp -I${HIP_PATH}/include -D__HIP_PLATFORM_AMD__ -o malloc.o BYPRODUCTS malloc.o) +add_library(malloc_gpp OBJECT IMPORTED) +set_property(TARGET malloc_gpp PROPERTY IMPORTED_OBJECTS "${CMAKE_CURRENT_BINARY_DIR}/malloc.o") + +hip_add_exe_to_target(NAME gppTests + TEST_SRC ${TEST_SRC} + TEST_TARGET_NAME build_tests + LINKER_LIBS malloc_gpp) + +add_dependencies(gppTests malloc_custom) +endif() +endif() diff --git a/projects/hip-tests/catch/unit/g++/hipMalloc.cc b/projects/hip-tests/catch/unit/g++/hipMalloc.cc new file mode 100644 index 0000000000..22e3141c0e --- /dev/null +++ b/projects/hip-tests/catch/unit/g++/hipMalloc.cc @@ -0,0 +1,49 @@ +/* + * 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 WARRANNTY OF ANY KIND, EXPRESS OR + * IMPLIED, INNCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANNY CLAIM, DAMAGES OR OTHER + * 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. + * */ + +#include +#include +#include "hipMalloc.h" +/** + * @addtogroup hipMalloc hipMalloc + * @{ + * @ingroup MemoryTest + * `hipError_t hipMalloc(void** ptr, size_t size)` - + * Allocate memory on the default accelerator. + * @} + */ + +/** + * Test Description + * ------------------------ + * - Allocate memory by using hipMalloc API and verify hipSuccess is returned. + + * Test source + * ------------------------ + * - catch/unit/g++/hipMalloc.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ + +TEST_CASE("Unit_hipMalloc_gpptest") { + printf("calling cpp function from here\n"); + int result = MallocFunc(); + REQUIRE(result == 1); +} diff --git a/projects/hip-tests/catch/unit/g++/hipMalloc.cpp b/projects/hip-tests/catch/unit/g++/hipMalloc.cpp new file mode 100644 index 0000000000..d954dc5e33 --- /dev/null +++ b/projects/hip-tests/catch/unit/g++/hipMalloc.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2019 - 2021 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 WARRANNTY OF ANY KIND, EXPRESS OR + * IMPLIED, INNCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANNY CLAIM, DAMAGES OR OTHER + * 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. + * */ + +#include +#include +#include "hipMalloc.h" + +int MallocFunc() { + int* Ad; + hipError_t err; + err = hipMalloc(reinterpret_cast(&Ad), 1024); + if (err == hipSuccess) { + std::cout <<"PASSED!" < + +extern int MallocFunc(); \ No newline at end of file From 6df8431d83ecba29d6fd67e989e358aa5d3b6b03 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Sun, 9 Jul 2023 08:55:01 +0530 Subject: [PATCH 13/25] SWDEV-380340 - [catch2][dtest] DynamicLoading tests migrated from direct to catch2 (#346) Change-Id: I5f82ddd565d4e86270498d2d8b155200ce568849 [ROCm/hip-tests commit: ee95b284c35d5dd240eb6078adf5e3bfe574613c] --- .../catch/include/hip_test_defgroups.hh | 7 + projects/hip-tests/catch/unit/CMakeLists.txt | 3 +- .../catch/unit/dynamicLoading/CMakeLists.txt | 49 ++++ .../dynamicLoading/bit_extract_kernel.cpp | 32 +++ .../complex_loading_behavior.cc | 147 ++++++++++++ .../unit/dynamicLoading/hipApiDynamicLoad.cc | 169 ++++++++++++++ .../catch/unit/dynamicLoading/liblazyLoad.cc | 212 ++++++++++++++++++ 7 files changed, 618 insertions(+), 1 deletion(-) create mode 100644 projects/hip-tests/catch/unit/dynamicLoading/CMakeLists.txt create mode 100644 projects/hip-tests/catch/unit/dynamicLoading/bit_extract_kernel.cpp create mode 100644 projects/hip-tests/catch/unit/dynamicLoading/complex_loading_behavior.cc create mode 100644 projects/hip-tests/catch/unit/dynamicLoading/hipApiDynamicLoad.cc create mode 100644 projects/hip-tests/catch/unit/dynamicLoading/liblazyLoad.cc diff --git a/projects/hip-tests/catch/include/hip_test_defgroups.hh b/projects/hip-tests/catch/include/hip_test_defgroups.hh index 83d2c4610b..d8fdc5b26d 100644 --- a/projects/hip-tests/catch/include/hip_test_defgroups.hh +++ b/projects/hip-tests/catch/include/hip_test_defgroups.hh @@ -101,6 +101,13 @@ THE SOFTWARE. * @} */ +/** + * @defgroup DynamicLoadingTest Kernel Loading Management + * @{ + * This section describes the different kernel launch approaches. + * @} + */ + /** * @defgroup MemoryTest memory Management APIs * @{ diff --git a/projects/hip-tests/catch/unit/CMakeLists.txt b/projects/hip-tests/catch/unit/CMakeLists.txt index ae5c866e32..5b3bbf66b6 100644 --- a/projects/hip-tests/catch/unit/CMakeLists.txt +++ b/projects/hip-tests/catch/unit/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2023 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2021-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 @@ -36,6 +36,7 @@ add_subdirectory(compiler) add_subdirectory(errorHandling) add_subdirectory(cooperativeGrps) add_subdirectory(context) +add_subdirectory(dynamicLoading) add_subdirectory(g++) add_subdirectory(module) diff --git a/projects/hip-tests/catch/unit/dynamicLoading/CMakeLists.txt b/projects/hip-tests/catch/unit/dynamicLoading/CMakeLists.txt new file mode 100644 index 0000000000..d58f4ec436 --- /dev/null +++ b/projects/hip-tests/catch/unit/dynamicLoading/CMakeLists.txt @@ -0,0 +1,49 @@ +# 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. +if(UNIX) + set(TEST_SRC ${TEST_SRC} + complex_loading_behavior.cc) + set(AMD_TEST_SRC + hipApiDynamicLoad.cc) + +if(HIP_PLATFORM MATCHES "amd") + set(TEST_SRC ${TEST_SRC} ${AMD_TEST_SRC}) +endif() + +hip_add_exe_to_target(NAME dynamicLoading + TEST_SRC ${TEST_SRC} + TEST_TARGET_NAME build_tests) + +if(HIP_PLATFORM MATCHES "amd") +add_custom_target(libLazyLoad.so COMMAND ${CMAKE_CXX_COMPILER} -fPIC -lpthread -shared ${OFFLOAD_ARCH_STR} ${CMAKE_CURRENT_SOURCE_DIR}/liblazyLoad.cc -I${CMAKE_CURRENT_SOURCE_DIR}/../../include -I${CMAKE_CURRENT_SOURCE_DIR}/../../external/Catch2 -o libLazyLoad.so) +elseif(HIP_PLATFORM MATCHES "nvidia") +add_custom_target(libLazyLoad.so COMMAND ${CMAKE_CXX_COMPILER} -Xcompiler -fPIC -lpthread -shared ${CMAKE_CURRENT_SOURCE_DIR}/liblazyLoad.cc -I${CMAKE_CURRENT_SOURCE_DIR}/../../include -I${CMAKE_CURRENT_SOURCE_DIR}/../../external/Catch2 -o libLazyLoad.so) +endif() + +add_custom_target(bit_extract_kernel.code COMMAND ${CMAKE_CXX_COMPILER} --genco ${OFFLOAD_ARCH_STR} ${CMAKE_CURRENT_SOURCE_DIR}/bit_extract_kernel.cpp -o ${CMAKE_CURRENT_BINARY_DIR}/../dynamicLoading/bit_extract_kernel.code -I${CMAKE_CURRENT_SOURCE_DIR}/../../../../include/ -I${CMAKE_CURRENT_SOURCE_DIR}/../../include) + +if(HIP_PLATFORM MATCHES "amd") +hip_add_exe_to_target(NAME Dynamic + TEST_SRC ${LINUX_TEST_SRC} + TEST_TARGET_NAME build_tests + LINKER_LIBS ${CMAKE_DL_LIBS}) +endif() +add_dependencies(build_tests bit_extract_kernel.code libLazyLoad.so) +endif() diff --git a/projects/hip-tests/catch/unit/dynamicLoading/bit_extract_kernel.cpp b/projects/hip-tests/catch/unit/dynamicLoading/bit_extract_kernel.cpp new file mode 100644 index 0000000000..7eff993665 --- /dev/null +++ b/projects/hip-tests/catch/unit/dynamicLoading/bit_extract_kernel.cpp @@ -0,0 +1,32 @@ +/* +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 WARRANNTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNNESS 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 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. +*/ +#include +extern "C" __global__ void bit_extract_kernel(uint32_t* C_d, const uint32_t* + A_d, size_t N) { + size_t offset = (blockIdx.x * blockDim.x + threadIdx.x); + size_t stride = blockDim.x * gridDim.x; + for (size_t i = offset; i < N; i += stride) { +#if HT_AMD + C_d[i] = __bitextract_u32(A_d[i], 8, 4); +#else /* defined __HIP_PLATFORM_NVIDIA__ or other path */ + C_d[i] = ((A_d[i] & 0xf00) >> 8); +#endif + } +} + diff --git a/projects/hip-tests/catch/unit/dynamicLoading/complex_loading_behavior.cc b/projects/hip-tests/catch/unit/dynamicLoading/complex_loading_behavior.cc new file mode 100644 index 0000000000..c1c412052f --- /dev/null +++ b/projects/hip-tests/catch/unit/dynamicLoading/complex_loading_behavior.cc @@ -0,0 +1,147 @@ +/* +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 WARRANNTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNNESS 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 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. +*/ +#include +#include +#include +/** +* @addtogroup hipLaunchKernelGGL hipLaunchCooperativeKernel +* @{ +* @ingroup DynamicLoading +* `hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks, + std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` - +* launches Kernel with launch parameters and shared memory on stream with arguments passed +* `hipError_t hipLaunchCooperativeKernel(const void* f, dim3 gridDim, dim3 blockDimX, + void** kernelParams, unsigned int sharedMemBytes, + hipStream_t stream))` - +* launches kernel f with launch parameters and shared memory on stream with arguments passed +* to kernelparams or extra, where thread blocks can cooperate and synchronize as they execute +*/ + +/** + * Test Description + * ------------------------ + * - Test case to verify locally loaded kernels and dynamically loaded kernels from the library. + + * Test source + * ------------------------ + * - catch/unit/dynamicLoading/complex_loading_behavior.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ + +__global__ static void vector_add(float* C, float* A, float* B, size_t N) { + size_t offset = blockIdx.x * blockDim.x + threadIdx.x; + size_t stride = blockDim.x * gridDim.x; + for (size_t i = offset; i < N; i += stride) { + C[i] = A[i] + B[i]; + } +} + +static bool launch_local_kernel() { + bool testResult = true; + float *A_d, *B_d, *C_d; + float *A_h, *B_h, *C_h; + size_t N = 1000000; + size_t Nbytes = N * sizeof(float); + static int device = 0; + + HIPCHECK(hipSetDevice(device)); + hipDeviceProp_t props; + HIPCHECK(hipGetDeviceProperties(&props, device)); + + A_h = reinterpret_cast(malloc(Nbytes)); + HIPCHECK(A_h == nullptr ? hipErrorOutOfMemory : hipSuccess); + B_h = reinterpret_cast(malloc(Nbytes)); + HIPCHECK(B_h == nullptr ? hipErrorOutOfMemory : hipSuccess); + C_h = reinterpret_cast(malloc(Nbytes)); + HIPCHECK(C_h == nullptr ? hipErrorOutOfMemory : hipSuccess); + + // Fill with Phi + i + for (size_t i = 0; i < N; i++) { + A_h[i] = 1.618f + i; + B_h[i] = 1.618f + i; + } + + HIPCHECK(hipMalloc(&A_d, Nbytes)); + HIPCHECK(hipMalloc(&B_d, Nbytes)); + HIPCHECK(hipMalloc(&C_d, Nbytes)); + HIPCHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice)); + HIPCHECK(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice)); + + const unsigned blocks = 512; + const unsigned threadsPerBlock = 256; + hipLaunchKernelGGL(vector_add, dim3(blocks), dim3(threadsPerBlock), + 0, 0, C_d, A_d, B_d, N); + HIPCHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + + for (size_t i=0; i < N ; i++) { + if (C_h[i] != (A_h[i] + B_h[i])) { + testResult = false; + break; + } + } + + HIPCHECK(hipFree(A_d)); + HIPCHECK(hipFree(B_d)); + HIPCHECK(hipFree(C_d)); + + free(A_h); + free(B_h); + free(C_h); + return testResult; +} + +static bool launch_dynamically_loaded_kernel() { + bool testResult = true; + int ret = 1; + + void* handle = dlopen("./libLazyLoad.so", RTLD_LAZY); + if (!handle) { + INFO("dlopen Error: " << dlerror() << "\n"); + testResult = false; + return testResult; + } + void* sym = dlsym(handle, "lazyLoad"); + if (!sym) { + INFO("unable to locate lazyLoad within lazyLoad.so\n"); + dlclose(handle); + testResult = false; + return testResult; + } + + int(*fp)() = reinterpret_cast(sym); + ret = fp(); + + if (ret == 0) { + testResult = false; + } + + dlclose(handle); + return testResult; +} + +TEST_CASE("Unit_dynamic_loading_device_kernels_from_library") { + bool testResult = true; + + testResult &= launch_local_kernel(); + testResult &= launch_dynamically_loaded_kernel(); + + REQUIRE(testResult == true); +} diff --git a/projects/hip-tests/catch/unit/dynamicLoading/hipApiDynamicLoad.cc b/projects/hip-tests/catch/unit/dynamicLoading/hipApiDynamicLoad.cc new file mode 100644 index 0000000000..e583f4a3d1 --- /dev/null +++ b/projects/hip-tests/catch/unit/dynamicLoading/hipApiDynamicLoad.cc @@ -0,0 +1,169 @@ +/* +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 WARRANNTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNNESS 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 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. +*/ +#include +#include +#include +#include +#include +#include +#include + +#define fileName "bit_extract_kernel.code" + +#define LEN 64 +#define SIZE LEN * sizeof(float) + +/** +* @addtogroup dyn_hipModuleLoad dyn_hipModuleGetFunction dyn_hipModuleLaunchKernel +* @{ +* @ingroup DynamicLoading +* ` hipError_t (*dyn_hipModuleLoad)(hipModule_t*, const char*) = reinterpret_cast + (sym_hipModuleLoad)` - +* Loads code object from file into a module the currrent context +* `hipError_t (*dyn_hipModuleGetFunction)(hipFunction_t*, hipModule_t, + const char*) = reinterpret_cast < hipError_t (*)(hipFunction_t*, + hipModule_t, const char*)>(sym_hipModuleGetFunction)` - +* Function with kernelname will be extracted if present in module +* `hipError_t (*dyn_hipModuleLaunchKernel)(hipFunction_t, unsigned int, + unsigned int, unsigned int, unsigned int, unsigned int, + unsigned int, unsigned int, hipStream_t, void**, void**) + = reinterpret_cast(sym_hipModuleLaunchKernel)` - +* launches Kernel with launch parameters and shared memory on stream with arguments passed +*/ + +/** + * Test Description + * ------------------------ + * - Test is to load hip runtime using dlopen and get function pointer using dlsym for hip apis. + + * Test source + * ------------------------ + * - catch/unit/dynamicLoading/hipApiDynamicLoad.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ + +TEST_CASE("Unit_hipApiDynamicLoad") { + uint32_t *A_d, *C_d; + uint32_t *A_h, *C_h; + size_t N = 1000000; + size_t Nbytes = N * sizeof(uint32_t); + + void* handle = dlopen("libamdhip64.so", RTLD_LAZY); + REQUIRE(handle != NULL); + + void* sym_hipGetDevice = dlsym(handle, "hipGetDevice"); + void* sym_hipMalloc = dlsym(handle, "hipMalloc"); + void* sym_hipMemcpyHtoD = dlsym(handle, "hipMemcpyHtoD"); + void* sym_hipMemcpyDtoH = dlsym(handle, "hipMemcpyDtoH"); + void* sym_hipModuleLoad = dlsym(handle, "hipModuleLoad"); + void* sym_hipGetDeviceProperties = dlsym(handle, "hipGetDeviceProperties"); + void* sym_hipModuleGetFunction = dlsym(handle, "hipModuleGetFunction"); + void* sym_hipModuleLaunchKernel = dlsym(handle, "hipModuleLaunchKernel"); + + dlclose(handle); + hipError_t (*dyn_hipGetDevice)(hipDevice_t*, int) = reinterpret_cast + (sym_hipGetDevice); + + hipError_t (*dyn_hipMalloc)(void**, uint32_t) = reinterpret_cast + (sym_hipMalloc); + + hipError_t (*dyn_hipMemcpyHtoD)(hipDeviceptr_t, void*, size_t) = + reinterpret_cast(sym_hipMemcpyHtoD); + + hipError_t (*dyn_hipMemcpyDtoH)(void*, hipDeviceptr_t, size_t) = + reinterpret_cast(sym_hipMemcpyDtoH); + + hipError_t (*dyn_hipModuleLoad)(hipModule_t*, const char*) = reinterpret_cast + (sym_hipModuleLoad); + + hipError_t (*dyn_hipGetDeviceProperties)(hipDeviceProp_t*, int) = + reinterpret_cast + (sym_hipGetDeviceProperties); + + hipError_t (*dyn_hipModuleGetFunction)(hipFunction_t*, hipModule_t, + const char*) = reinterpret_cast < hipError_t (*)(hipFunction_t*, + hipModule_t, const char*)>(sym_hipModuleGetFunction); + + hipError_t (*dyn_hipModuleLaunchKernel)(hipFunction_t, unsigned int, + unsigned int, unsigned int, unsigned int, unsigned int, + unsigned int, unsigned int, hipStream_t, void**, void**) + = reinterpret_cast(sym_hipModuleLaunchKernel); + + hipDevice_t device; + HIPCHECK(dyn_hipGetDevice(&device, 0)); + + hipDeviceProp_t props; + HIPCHECK(dyn_hipGetDeviceProperties(&props, device)); + A_h = reinterpret_cast(malloc(Nbytes)); + REQUIRE(A_h != NULL); + C_h = reinterpret_cast(malloc(Nbytes)); + REQUIRE(C_h != NULL); + + for (size_t i = 0; i < N; i++) { + A_h[i] = i; + } + + HIPCHECK(dyn_hipMalloc(reinterpret_cast(&A_d), Nbytes)); + HIPCHECK(dyn_hipMalloc(reinterpret_cast(&C_d), Nbytes)); + + HIPCHECK(dyn_hipMemcpyHtoD((hipDeviceptr_t)(A_d), A_h, Nbytes)); + + struct { + void* _Cd; + void* _Ad; + size_t _N; + } args; + args._Cd = reinterpret_cast (C_d); + args._Ad = reinterpret_cast (A_d); + args._N = static_cast (N); + size_t size = sizeof(args); + + void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args, + HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, HIP_LAUNCH_PARAM_END}; + + hipModule_t Module; + HIPCHECK(dyn_hipModuleLoad(&Module, fileName)); + + hipFunction_t Function; + HIPCHECK(dyn_hipModuleGetFunction(&Function, Module, "bit_extract_kernel")); + + HIPCHECK(dyn_hipModuleLaunchKernel(Function, 1, 1, 1, LEN, 1, 1, 0, 0, NULL, + reinterpret_cast(&config))); + + HIPCHECK(dyn_hipMemcpyDtoH(C_h, (hipDeviceptr_t)(C_d), Nbytes)); + + for (size_t i = 0; i < N; i++) { + unsigned Agold = ((A_h[i] & 0xf00) >> 8); + REQUIRE(C_h[i] == Agold); + } + HIPCHECK(hipFree(A_d)); + HIPCHECK(hipFree(C_d)); + free(A_h); + free(C_h); +} diff --git a/projects/hip-tests/catch/unit/dynamicLoading/liblazyLoad.cc b/projects/hip-tests/catch/unit/dynamicLoading/liblazyLoad.cc new file mode 100644 index 0000000000..54e18bbcab --- /dev/null +++ b/projects/hip-tests/catch/unit/dynamicLoading/liblazyLoad.cc @@ -0,0 +1,212 @@ +/* +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 WARRANNTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNNESS 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 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. +*/ +#include +#include + +#define CHECK_RET_VAL(cmd) \ +{ \ + hipError_t error = cmd;\ + if (error != hipSuccess) {\ + fprintf(stderr, "error: '%s'(%d) at %s:%d\n", hipGetErrorString(error), \ + error, __FILE__, __LINE__);\ + exit(EXIT_FAILURE);\ + }\ +} + +__global__ static void addition(float* C, float* A, float* B, size_t N) { + size_t offset = hipBlockIdx_x * hipBlockDim_x + hipThreadIdx_x; + size_t stride = hipBlockDim_x * hipGridDim_x; + + for (size_t i = offset; i < N; i += stride) { + C[i] = A[i] + B[i]; + } +} + +static int vectorAddKernelTest() { + int testResult = 1; + float *A_d, *B_d, *C_d; + float *A_h, *B_h, *C_h; + size_t N = 1000000; + size_t Nbytes = N * sizeof(float); + static int device = 0; + + CHECK_RET_VAL(hipSetDevice(device)); + hipDeviceProp_t props; + CHECK_RET_VAL(hipGetDeviceProperties(&props, device)); + A_h = reinterpret_cast(malloc(Nbytes)); + CHECK_RET_VAL(A_h == nullptr ? hipErrorOutOfMemory : hipSuccess); + B_h = reinterpret_cast(malloc(Nbytes)); + CHECK_RET_VAL(B_h == nullptr ? hipErrorOutOfMemory : hipSuccess); + C_h = reinterpret_cast(malloc(Nbytes)); + CHECK_RET_VAL(C_h == nullptr ? hipErrorOutOfMemory : hipSuccess); + + // Fill with Phi + i + for (size_t i = 0; i < N; i++) { + A_h[i] = 1.618f + i; + B_h[i] = 1.618f + i; + } + + CHECK_RET_VAL(hipMalloc(&A_d, Nbytes)); + CHECK_RET_VAL(hipMalloc(&B_d, Nbytes)); + CHECK_RET_VAL(hipMalloc(&C_d, Nbytes)); + CHECK_RET_VAL(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice)); + CHECK_RET_VAL(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice)); + + const unsigned blocks = 512; + const unsigned threadsPerBlock = 256; + hipLaunchKernelGGL(addition, dim3(blocks), dim3(threadsPerBlock), + 0, 0, C_d, A_d, B_d, N); + CHECK_RET_VAL(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + + for (size_t i=0; i < N ; i++) { + if (C_h[i] != (A_h[i] + B_h[i])) { + testResult = 0; + break; + } + } + + CHECK_RET_VAL(hipFree(A_d)); + CHECK_RET_VAL(hipFree(B_d)); + CHECK_RET_VAL(hipFree(C_d)); + + free(A_h); + free(B_h); + free(C_h); + return testResult; +} + +#include "hip/hip_cooperative_groups.h" + +namespace cg = cooperative_groups; + +static const uint BufferSizeInDwords = 448 * 1024 * 1024; + +__global__ static void test_gws(uint* buf, uint bufSize, + int64_t* tmpBuf, int64_t* result) { + extern __shared__ int64_t tmp[]; + uint offset = blockIdx.x * blockDim.x + threadIdx.x; + uint stride = gridDim.x * blockDim.x; + cg::grid_group gg = cg::this_grid(); + + int64_t sum = 0; + + for (uint i = offset; i < bufSize; i += stride) { + sum += buf[i]; + } + + tmp[threadIdx.x] = sum; + __syncthreads(); + + if (threadIdx.x == 0) { + sum = 0; + for (uint i = 0; i < blockDim.x; i++) { + sum += tmp[i]; + } + tmpBuf[blockIdx.x] = sum; + } + + gg.sync(); + + if (offset == 0) { + for (uint i = 1; i < gridDim.x; ++i) { + sum += tmpBuf[i]; + } + *result = sum; + } +} + +static int cooperativeKernelTest() { + int testResult = 1; + uint* dA; + int64_t* dB; + int64_t* dC; + int64_t* Ah; + + hipDeviceProp_t deviceProp; + hipGetDeviceProperties(&deviceProp, 0); + + if (!deviceProp.cooperativeLaunch) { + return testResult; + } + + uint32_t* init = new uint32_t[BufferSizeInDwords]; + + for (uint32_t i = 0; i < BufferSizeInDwords; ++i) { + init[i] = i; + } + size_t SIZE = BufferSizeInDwords * sizeof(uint); + + CHECK_RET_VAL(hipMalloc(reinterpret_cast(&dA), SIZE)); + CHECK_RET_VAL(hipMalloc(reinterpret_cast(&dC), sizeof(int64_t))); + CHECK_RET_VAL(hipMemcpy(dA, init, SIZE, hipMemcpyHostToDevice)); + Ah = reinterpret_cast(malloc(sizeof(int64_t))); + + hipStream_t stream; + CHECK_RET_VAL(hipStreamCreate(&stream)); + + dim3 dimBlock = dim3(1); + dim3 dimGrid = dim3(1); + + int numBlocks = 0; + uint workgroups[4] = {32, 64, 128, 256}; + + for (uint i = 0; i < 4; ++i) { + dimBlock.x = workgroups[i]; + /* Calculate the device occupancy to know how many blocks can be + run concurrently */ + hipOccupancyMaxActiveBlocksPerMultiprocessor(&numBlocks, + test_gws, dimBlock.x * dimBlock.y * dimBlock.z, dimBlock.x * + sizeof(int64_t)); + dimGrid.x = deviceProp.multiProcessorCount * std::min(numBlocks, 32); + CHECK_RET_VAL(hipMalloc(reinterpret_cast(&dB), + dimGrid.x * sizeof(int64_t))); + + void *params[4]; + params[0] = reinterpret_cast(&dA); + params[1] = (void*)(&BufferSizeInDwords); // NOLINT + params[2] = reinterpret_cast(&dB); + params[3] = reinterpret_cast(&dC); + + CHECK_RET_VAL(hipLaunchCooperativeKernel(reinterpret_cast(test_gws), + dimGrid, dimBlock, params, + dimBlock.x * sizeof(int64_t), stream)); + + CHECK_RET_VAL(hipMemcpy(Ah, dC, sizeof(int64_t), hipMemcpyDeviceToHost)); + + if (*Ah != (((int64_t)(BufferSizeInDwords) * (BufferSizeInDwords - 1)) + / 2)) { + CHECK_RET_VAL(hipFree(dB)); + testResult = 0; + break; + + } else { + CHECK_RET_VAL(hipFree(dB)); + } + } + CHECK_RET_VAL(hipStreamDestroy(stream)); + CHECK_RET_VAL(hipFree(dC)); + CHECK_RET_VAL(hipFree(dA)); + delete [] init; + free(Ah); + return testResult; +} + +extern "C" int lazyLoad() { + return vectorAddKernelTest() & cooperativeKernelTest(); +} From c5b57687b2f0016d5f5318560730829c0c22c100 Mon Sep 17 00:00:00 2001 From: milos-mozetic <118800401+milos-mozetic@users.noreply.github.com> Date: Sun, 9 Jul 2023 05:38:20 +0200 Subject: [PATCH 14/25] EXSWHTEC-282 - Implement Unit Tests for channel descriptor create function (#215) - Implement basic test cases for channel descriptor API - Fix indentation - Refactor channel descriptor tests - Extend the list of FormatNone types - Implement unit test for 16-Bit Floating-Point channel descriptor - Regroup vector types and basic types within test cases - Add builtin types to the size/kind calculation - Uncomment mistakenly commented tests - Remove cout from channel_descriptor_common.hh - Exclude 16-bit floating point tests from NVIDIA build due to the build error for hipCreateChannelDescHalf* functions - Add doxygen comments and disable tests due to defects - Fix errors in doxygen comments - Rename group for channel descriptor - Modify Copyright header comment - Apply clang-format - Use std::is_same_v<> instead of std::is_same<>::value to enhance readability - Disable failed tests on external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/215 [ROCm/hip-tests commit: 262dc3d072fc4c4ced6d25f1c8c3ad477de8963a] --- projects/hip-tests/catch/DoxyfileTests | 3 +- .../config/config_amd_linux_common.json | 13 +- .../config/config_amd_windows_common.json | 15 +- .../config/config_nvidia_linux_common.json | 14 +- .../config/config_nvidia_windows_common.json | 14 +- .../catch/include/hip_test_defgroups.hh | 7 + projects/hip-tests/catch/unit/CMakeLists.txt | 3 +- .../unit/channelDescriptor/CMakeLists.txt | 27 +++ .../channelDescriptor/channel_descriptor.cc | 194 +++++++++++++++ .../channel_descriptor_common.hh | 221 ++++++++++++++++++ 10 files changed, 505 insertions(+), 6 deletions(-) create mode 100644 projects/hip-tests/catch/unit/channelDescriptor/CMakeLists.txt create mode 100644 projects/hip-tests/catch/unit/channelDescriptor/channel_descriptor.cc create mode 100644 projects/hip-tests/catch/unit/channelDescriptor/channel_descriptor_common.hh diff --git a/projects/hip-tests/catch/DoxyfileTests b/projects/hip-tests/catch/DoxyfileTests index d703ed8b9e..b731fc0c13 100644 --- a/projects/hip-tests/catch/DoxyfileTests +++ b/projects/hip-tests/catch/DoxyfileTests @@ -2160,7 +2160,8 @@ PREDEFINED = TEMPLATE_TEST_CASE(x)=x() \ __linux__ \ HT_AMD \ HT_NVIDIA \ - __HIP_PLATFORM_NVCC__ + __HIP_PLATFORM_NVCC__ \ + __GNUC__ # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff --git a/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json b/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json index 1a3df8cc4c..4d26b020ae 100644 --- a/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json +++ b/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json @@ -46,6 +46,7 @@ "Unit_hipGraphAddMemcpyNode1D_Negative_Basic", "intermittent issue: corrupted double-linked list", "Unit_hipGraphRetainUserObject_Functional_2", + "Unit_ChannelDescriptor_Positive_16BitFloatingPoint", "intermittent issue: failure expected but sucess returned", "Unit_hipMemAdvise_NegtveTsts", "Note: Following four tests disabled due to defect - EXSWHTEC-203", @@ -98,6 +99,16 @@ "Unit_hipStreamValue_Write - TestParams", "Unit_hipMemcpyParam2DAsync_multiDevice-StreamOnDiffDevice", "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/96 ===", - "Unit_hipHostGetDevicePointer_Negative" + "Unit_hipHostGetDevicePointer_Negative", + "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/215 ===", + "Unit_ChannelDescriptor_Positive_Basic_1D - long", + "Unit_ChannelDescriptor_Positive_Basic_1D - unsigned long", + "Unit_ChannelDescriptor_Positive_Basic_1D - ulong1", + "Unit_ChannelDescriptor_Positive_Basic_1D - signed long", + "Unit_ChannelDescriptor_Positive_Basic_1D - long1", + "Unit_ChannelDescriptor_Positive_Basic_2D - ulong2", + "Unit_ChannelDescriptor_Positive_Basic_2D - long2", + "Unit_ChannelDescriptor_Positive_Basic_4D - ulong4", + "Unit_ChannelDescriptor_Positive_Basic_4D - long4" ] } diff --git a/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json b/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json index 87d534cfd8..d5faf9b538 100644 --- a/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json +++ b/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json @@ -150,6 +150,7 @@ "Unit_hipStreamQuery_WithFinishedWork", "Unit_hipLaunchHostFunc_Graph", "Unit_hipLaunchHostFunc_KernelHost", + "Unit_ChannelDescriptor_Positive_16BitFloatingPoint", "Unit_hipStreamSetCaptureDependencies_Positive_Functional", "Note: Following four tests disabled due to defect - EXSWHTEC-203", "Unit_hipGraphAddMemsetNode_Positive_Basic - uint16_t", @@ -186,6 +187,18 @@ "Note: UUID returned empty on some windows nodes", "Unit_hipDeviceGetUuid_Positive", "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/96 ===", - "Unit_hipHostGetDevicePointer_Negative" + "Unit_hipHostGetDevicePointer_Negative", + "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/215 ===", + "Unit_ChannelDescriptor_Positive_Basic_1D - long", + "Unit_ChannelDescriptor_Positive_Basic_1D - unsigned long", + "Unit_ChannelDescriptor_Positive_Basic_1D - ulong1", + "Unit_ChannelDescriptor_Positive_Basic_1D - signed long", + "Unit_ChannelDescriptor_Positive_Basic_1D - long1", + "Unit_ChannelDescriptor_Positive_Basic_2D - ulong2", + "Unit_ChannelDescriptor_Positive_Basic_2D - long2", + "Unit_ChannelDescriptor_Positive_Basic_3D - ulong3", + "Unit_ChannelDescriptor_Positive_Basic_3D - long3", + "Unit_ChannelDescriptor_Positive_Basic_4D - ulong4", + "Unit_ChannelDescriptor_Positive_Basic_4D - long4" ] } diff --git a/projects/hip-tests/catch/hipTestMain/config/config_nvidia_linux_common.json b/projects/hip-tests/catch/hipTestMain/config/config_nvidia_linux_common.json index 7766cbe28d..84df4337fb 100644 --- a/projects/hip-tests/catch/hipTestMain/config/config_nvidia_linux_common.json +++ b/projects/hip-tests/catch/hipTestMain/config/config_nvidia_linux_common.json @@ -6,6 +6,18 @@ "Unit_hipFuncSetAttribute_Positive_MaxDynamicSharedMemorySize_Not_Supported", "Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout_Not_Supported", "=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/85 ===", - "Unit_hipFuncSetAttribute_Negative_Parameters" + "Unit_hipFuncSetAttribute_Negative_Parameters", + "=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/215 ===", + "Unit_ChannelDescriptor_Positive_Basic_1D - long", + "Unit_ChannelDescriptor_Positive_Basic_1D - unsigned long", + "Unit_ChannelDescriptor_Positive_Basic_1D - ulong1", + "Unit_ChannelDescriptor_Positive_Basic_1D - signed long", + "Unit_ChannelDescriptor_Positive_Basic_1D - long1", + "Unit_ChannelDescriptor_Positive_Basic_2D - ulong2", + "Unit_ChannelDescriptor_Positive_Basic_2D - long2", + "Unit_ChannelDescriptor_Positive_Basic_3D - ulong3", + "Unit_ChannelDescriptor_Positive_Basic_3D - long3", + "Unit_ChannelDescriptor_Positive_Basic_4D - ulong4", + "Unit_ChannelDescriptor_Positive_Basic_4D - long4" ] } diff --git a/projects/hip-tests/catch/hipTestMain/config/config_nvidia_windows_common.json b/projects/hip-tests/catch/hipTestMain/config/config_nvidia_windows_common.json index 8247b49e3a..771113cc69 100644 --- a/projects/hip-tests/catch/hipTestMain/config/config_nvidia_windows_common.json +++ b/projects/hip-tests/catch/hipTestMain/config/config_nvidia_windows_common.json @@ -4,6 +4,18 @@ "Unit_hipFuncSetCacheConfig_Negative_Not_Supported", "Unit_hipFuncSetSharedMemConfig_Negative_Not_Supported", "Unit_hipFuncSetAttribute_Positive_MaxDynamicSharedMemorySize_Not_Supported", - "Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout_Not_Supported" + "Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout_Not_Supported", + "=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/215 ===", + "Unit_ChannelDescriptor_Positive_Basic_1D - long", + "Unit_ChannelDescriptor_Positive_Basic_1D - unsigned long", + "Unit_ChannelDescriptor_Positive_Basic_1D - ulong1", + "Unit_ChannelDescriptor_Positive_Basic_1D - signed long", + "Unit_ChannelDescriptor_Positive_Basic_1D - long1", + "Unit_ChannelDescriptor_Positive_Basic_2D - ulong2", + "Unit_ChannelDescriptor_Positive_Basic_2D - long2", + "Unit_ChannelDescriptor_Positive_Basic_3D - ulong3", + "Unit_ChannelDescriptor_Positive_Basic_3D - long3", + "Unit_ChannelDescriptor_Positive_Basic_4D - ulong4", + "Unit_ChannelDescriptor_Positive_Basic_4D - long4" ] } diff --git a/projects/hip-tests/catch/include/hip_test_defgroups.hh b/projects/hip-tests/catch/include/hip_test_defgroups.hh index d8fdc5b26d..590f680880 100644 --- a/projects/hip-tests/catch/include/hip_test_defgroups.hh +++ b/projects/hip-tests/catch/include/hip_test_defgroups.hh @@ -72,6 +72,13 @@ THE SOFTWARE. * @} */ +/** + * @defgroup DeviceLanguageTest Device Language + * @{ + * This section describes tests for the Device Language API. + * @} + */ + /** * @defgroup ExecutionTest Execution Control * @{ diff --git a/projects/hip-tests/catch/unit/CMakeLists.txt b/projects/hip-tests/catch/unit/CMakeLists.txt index 5b3bbf66b6..e0b1f5a1b2 100644 --- a/projects/hip-tests/catch/unit/CMakeLists.txt +++ b/projects/hip-tests/catch/unit/CMakeLists.txt @@ -39,6 +39,8 @@ add_subdirectory(context) add_subdirectory(dynamicLoading) add_subdirectory(g++) add_subdirectory(module) +add_subdirectory(channelDescriptor) +add_subdirectory(executionControl) if(HIP_PLATFORM STREQUAL "amd") add_subdirectory(callback) @@ -46,4 +48,3 @@ add_subdirectory(callback) # Vulkan interop APIs currently undefined for Nvidia add_subdirectory(vulkan_interop) endif() -add_subdirectory(executionControl) diff --git a/projects/hip-tests/catch/unit/channelDescriptor/CMakeLists.txt b/projects/hip-tests/catch/unit/channelDescriptor/CMakeLists.txt new file mode 100644 index 0000000000..50970c6cec --- /dev/null +++ b/projects/hip-tests/catch/unit/channelDescriptor/CMakeLists.txt @@ -0,0 +1,27 @@ +# 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. + +set(TEST_SRC + channel_descriptor.cc +) + +hip_add_exe_to_target(NAME ChannelDescriptorTest + TEST_SRC ${TEST_SRC} + TEST_TARGET_NAME build_tests) diff --git a/projects/hip-tests/catch/unit/channelDescriptor/channel_descriptor.cc b/projects/hip-tests/catch/unit/channelDescriptor/channel_descriptor.cc new file mode 100644 index 0000000000..60f68817bc --- /dev/null +++ b/projects/hip-tests/catch/unit/channelDescriptor/channel_descriptor.cc @@ -0,0 +1,194 @@ +/* +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 "channel_descriptor_common.hh" + +/** + * @addtogroup hipCreateChannelDesc hipCreateChannelDesc + * @{ + * @ingroup DeviceLanguageTest + * `hipCreateChannelDesc()` - + * Creates a dedicated channel descriptor based on passed built-in or vector type T. + */ + +/** + * Test Description + * ------------------------ + * - Validates that 1D channel descriptor is created as expected. + * - Compares channel descriptor with the manually created one. + * - Takes into consideration following 1D built-in and vector types: + * -# char (signed and unsigned) + * -# short (signed and unsigned) + * -# int (signed and unsigned) + * -# float + * -# long (signed and unsigned) + * Test source + * ------------------------ + * - unit/channelDescriptor/channel_descriptor.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEMPLATE_TEST_CASE("Unit_ChannelDescriptor_Positive_Basic_1D", "", char, unsigned char, uchar1, + signed char, char1, unsigned short, ushort1, short, signed short, short1, int, + unsigned int, uint1, signed int, int1, float, float1, long, unsigned long, + ulong1, signed long, long1) { + ChannelDescriptorTest1D channel_desc_test; + channel_desc_test.Run(); +} + +/** + * Test Description + * ------------------------ + * - Validates that 2D channel descriptor is created as expected. + * - Compares channel descriptor with the manually created one. + * - Takes into consideration following 2D built-in and vector types: + * -# char (signed and unsigned) + * -# short (signed and unsigned) + * -# int (signed and unsigned) + * -# float + * -# long (signed and unsigned) + * Test source + * ------------------------ + * - unit/channelDescriptor/channel_descriptor.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEMPLATE_TEST_CASE("Unit_ChannelDescriptor_Positive_Basic_2D", "", uchar2, char2, ushort2, short2, + uint2, int2, float2, ulong2, long2) { + ChannelDescriptorTest2D channel_desc_test; + channel_desc_test.Run(); +} + +#ifndef __GNUC__ +/** + * Test Description + * ------------------------ + * - Validates that 3D channel descriptor is created as expected. + * - Compares channel descriptor with the manually created one. + * - Takes into consideration following 3D built-in and vector types: + * -# char (signed and unsigned) + * -# short (signed and unsigned) + * -# int (signed and unsigned) + * -# float + * -# long (signed and unsigned) + * Test source + * ------------------------ + * - unit/channelDescriptor/channel_descriptor.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + * - Available for non-GNUC compilers. + */ +TEMPLATE_TEST_CASE("Unit_ChannelDescriptor_Positive_Basic_3D", "", uchar3, char3, ushort3, short3, + uint3, int3, float3, ulong3, long3) { + ChannelDescriptorTest3D channel_desc_test; + channel_desc_test.Run(); +} +#endif + +/** + * Test Description + * ------------------------ + * - Validates that 4D channel descriptor is created as expected. + * - Compares channel descriptor with the manually created one. + * - Takes into consideration following 4D built-in and vector types: + * -# char (signed and unsigned) + * -# short (signed and unsigned) + * -# int (signed and unsigned) + * -# float + * -# long (signed and unsigned) + * Test source + * ------------------------ + * - unit/channelDescriptor/channel_descriptor.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEMPLATE_TEST_CASE("Unit_ChannelDescriptor_Positive_Basic_4D", "", uchar4, char4, ushort4, short4, + uint4, int4, float4, ulong4, long4) { + ChannelDescriptorTest4D channel_desc_test; + channel_desc_test.Run(); +} + +/** + * Test Description + * ------------------------ + * - Validates that an empty channel descriptor is created as expected. + * - Compares channel descriptor with the manually created one. + * - Takes into consideration all dimensions of the following built-in and vector types: + * -# long long (signed and unsigned) + * -# double + * Test source + * ------------------------ + * - unit/channelDescriptor/channel_descriptor.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEMPLATE_TEST_CASE("Unit_ChannelDescriptor_Positive_FormatNone", "", long long, signed long long, + unsigned long long, longlong1, longlong2, longlong3, longlong4, ulonglong1, + ulonglong2, ulonglong3, ulonglong4, double1, double2, double3, double4) { + ChannelDescriptorTestNone channel_desc_test; + channel_desc_test.Run(); +} + +#if HT_AMD +/** + * Test Description + * ------------------------ + * - Validates that the channel descriptor is created as expected. + * - Compares channel descriptor with the manually created one. + * - Takes into consideration 16-bit floating-point type. + * -# Creates 1D channel descriptor. + * -# Creates 2D channel descriptor. + * Test source + * ------------------------ + * - unit/channelDescriptor/channel_descriptor.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_ChannelDescriptor_Positive_16BitFloatingPoint") { + int size = static_cast(sizeof(unsigned short) * 8); + hipChannelFormatKind kind = hipChannelFormatKindFloat; + hipChannelFormatDesc channel_desc{}; + hipChannelFormatDesc referent_channel_desc{}; + + SECTION("hipCreateChannelDescHalf") { + referent_channel_desc = {size, 0, 0, 0, kind}; + channel_desc = hipCreateChannelDescHalf(); + } + SECTION("hipCreateChannelDescHalf1") { + referent_channel_desc = {size, 0, 0, 0, kind}; + channel_desc = hipCreateChannelDescHalf1(); + } + SECTION("hipCreateChannelDescHalf2") { + referent_channel_desc = {size, size, 0, 0, kind}; + channel_desc = hipCreateChannelDescHalf2(); + } + + REQUIRE(channel_desc.x == referent_channel_desc.x); + REQUIRE(channel_desc.y == referent_channel_desc.y); + REQUIRE(channel_desc.z == referent_channel_desc.z); + REQUIRE(channel_desc.w == referent_channel_desc.w); + REQUIRE(channel_desc.f == referent_channel_desc.f); +} +#endif diff --git a/projects/hip-tests/catch/unit/channelDescriptor/channel_descriptor_common.hh b/projects/hip-tests/catch/unit/channelDescriptor/channel_descriptor_common.hh new file mode 100644 index 0000000000..47e87025be --- /dev/null +++ b/projects/hip-tests/catch/unit/channelDescriptor/channel_descriptor_common.hh @@ -0,0 +1,221 @@ +/* +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 + +enum class ChannelDimension { OneDim, TwoDim, ThreeDim, FourDim }; + +template class ChannelDescriptorTestShell { + protected: + int size; + hipChannelFormatKind kind; + ChannelDimension dimension; + virtual void SetSizeAndKind() = 0; + + public: + void Run() { + hipChannelFormatDesc channel_desc{}; + SetSizeAndKind(); + hipChannelFormatDesc referent_channel_desc{0, 0, 0, 0, kind}; + switch (dimension) { + case ChannelDimension::FourDim: + referent_channel_desc.w = size; + case ChannelDimension::ThreeDim: + referent_channel_desc.z = size; + case ChannelDimension::TwoDim: + referent_channel_desc.y = size; + default: + referent_channel_desc.x = size; + } + channel_desc = hipCreateChannelDesc(); + REQUIRE(channel_desc.x == referent_channel_desc.x); + REQUIRE(channel_desc.y == referent_channel_desc.y); + REQUIRE(channel_desc.z == referent_channel_desc.z); + REQUIRE(channel_desc.w == referent_channel_desc.w); + REQUIRE(channel_desc.f == referent_channel_desc.f); + } + + ChannelDescriptorTestShell(const ChannelDimension dimension) + : size(0), kind(hipChannelFormatKindNone), dimension(dimension) {} + ChannelDescriptorTestShell(const ChannelDescriptorTestShell&) = delete; + ChannelDescriptorTestShell(ChannelDescriptorTestShell&&) = delete; +}; + +template class ChannelDescriptorTest1D : public ChannelDescriptorTestShell { + public: + ChannelDescriptorTest1D() : ChannelDescriptorTestShell(ChannelDimension::OneDim) {} + + protected: + void SetSizeAndKind() { + if (std::is_same_v) { + this->size = static_cast(sizeof(char) * 8); + this->kind = hipChannelFormatKindSigned; + } else if (std::is_same_v || std::is_same_v) { + this->size = static_cast(sizeof(unsigned char) * 8); + this->kind = hipChannelFormatKindUnsigned; + } else if (std::is_same_v || std::is_same_v) { + this->size = static_cast(sizeof(signed char) * 8); + this->kind = hipChannelFormatKindSigned; + } else if (std::is_same_v || std::is_same_v) { + this->size = static_cast(sizeof(unsigned short) * 8); + this->kind = hipChannelFormatKindUnsigned; + } else if (std::is_same_v || std::is_same_v || + std::is_same_v) { + this->size = static_cast(sizeof(signed short) * 8); + this->kind = hipChannelFormatKindSigned; + } else if (std::is_same_v || std::is_same_v) { + this->size = static_cast(sizeof(unsigned int) * 8); + this->kind = hipChannelFormatKindUnsigned; + } else if (std::is_same_v || std::is_same_v || std::is_same_v) { + this->size = static_cast(sizeof(signed int) * 8); + this->kind = hipChannelFormatKindSigned; + } else if (std::is_same_v || std::is_same_v) { + this->size = static_cast(sizeof(float) * 8); + this->kind = hipChannelFormatKindFloat; + } else if (std::is_same_v || std::is_same_v) { + this->size = static_cast(sizeof(unsigned long) * 8); + this->kind = hipChannelFormatKindUnsigned; + } else if (std::is_same_v || std::is_same_v || + std::is_same_v) { + this->size = static_cast(sizeof(signed long) * 8); + this->kind = hipChannelFormatKindSigned; + } + } +}; + +template class ChannelDescriptorTest2D : public ChannelDescriptorTestShell { + public: + ChannelDescriptorTest2D() : ChannelDescriptorTestShell(ChannelDimension::TwoDim) {} + + protected: + void SetSizeAndKind() { + if (std::is_same_v) { + this->size = static_cast(sizeof(unsigned char) * 8); + this->kind = hipChannelFormatKindUnsigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(signed char) * 8); + this->kind = hipChannelFormatKindSigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(unsigned short) * 8); + this->kind = hipChannelFormatKindUnsigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(signed short) * 8); + this->kind = hipChannelFormatKindSigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(unsigned int) * 8); + this->kind = hipChannelFormatKindUnsigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(signed int) * 8); + this->kind = hipChannelFormatKindSigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(float) * 8); + this->kind = hipChannelFormatKindFloat; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(unsigned long) * 8); + this->kind = hipChannelFormatKindUnsigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(signed long) * 8); + this->kind = hipChannelFormatKindSigned; + } + } +}; + +#ifndef __GNUC__ +template class ChannelDescriptorTest3D : public ChannelDescriptorTestShell { + public: + ChannelDescriptorTest3D() : ChannelDescriptorTestShell(ChannelDimension::ThreeDim) {} + + protected: + void SetSizeAndKind() { + if (std::is_same_v) { + this->size = static_cast(sizeof(unsigned char) * 8); + this->kind = hipChannelFormatKindUnsigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(signed char) * 8); + this->kind = hipChannelFormatKindSigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(unsigned short) * 8); + this->kind = hipChannelFormatKindUnsigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(signed short) * 8); + this->kind = hipChannelFormatKindSigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(unsigned int) * 8); + this->kind = hipChannelFormatKindUnsigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(signed int) * 8); + this->kind = hipChannelFormatKindSigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(float) * 8); + this->kind = hipChannelFormatKindFloat; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(unsigned long) * 8); + this->kind = hipChannelFormatKindUnsigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(signed long) * 8); + this->kind = hipChannelFormatKindSigned; + } + } +}; +#endif + +template class ChannelDescriptorTest4D : public ChannelDescriptorTestShell { + public: + ChannelDescriptorTest4D() : ChannelDescriptorTestShell(ChannelDimension::FourDim) {} + + protected: + void SetSizeAndKind() { + if (std::is_same_v) { + this->size = static_cast(sizeof(unsigned char) * 8); + this->kind = hipChannelFormatKindUnsigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(signed char) * 8); + this->kind = hipChannelFormatKindSigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(unsigned short) * 8); + this->kind = hipChannelFormatKindUnsigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(signed short) * 8); + this->kind = hipChannelFormatKindSigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(unsigned int) * 8); + this->kind = hipChannelFormatKindUnsigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(signed int) * 8); + this->kind = hipChannelFormatKindSigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(float) * 8); + this->kind = hipChannelFormatKindFloat; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(unsigned long) * 8); + this->kind = hipChannelFormatKindUnsigned; + } else if (std::is_same_v) { + this->size = static_cast(sizeof(signed long) * 8); + this->kind = hipChannelFormatKindSigned; + } + } +}; + +template class ChannelDescriptorTestNone : public ChannelDescriptorTestShell { + public: + ChannelDescriptorTestNone() : ChannelDescriptorTestShell(ChannelDimension::OneDim) {} + + protected: + void SetSizeAndKind() {} +}; From 29fd338b8481d8961021b30b72e5618424b3304e Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Sun, 9 Jul 2023 09:08:35 +0530 Subject: [PATCH 15/25] SWDEV-407072 - Fix sync issues seen on some event tests (#358) Change-Id: Ib904b9cca7329abcd02004daaeafd170014a1ec0 [ROCm/hip-tests commit: cf65854e7986378f4735ff31b9eb0197a53a4192] --- .../unit/event/Unit_hipEventElapsedTime.cc | 7 +- .../catch/unit/event/Unit_hipEventQuery.cc | 70 ++----------------- 2 files changed, 12 insertions(+), 65 deletions(-) diff --git a/projects/hip-tests/catch/unit/event/Unit_hipEventElapsedTime.cc b/projects/hip-tests/catch/unit/event/Unit_hipEventElapsedTime.cc index 7149c8cbea..93deb7f842 100644 --- a/projects/hip-tests/catch/unit/event/Unit_hipEventElapsedTime.cc +++ b/projects/hip-tests/catch/unit/event/Unit_hipEventElapsedTime.cc @@ -158,7 +158,9 @@ TEST_CASE("Unit_hipEventElapsedTime_NotReady_Negative") { // Record start event HIP_CHECK(hipEventRecord(start, nullptr)); - HipTest::runKernelForDuration(std::chrono::milliseconds(1000)); + HipTest::BlockingContext b_context{nullptr}; + b_context.block_stream(); // blocked stream + REQUIRE(b_context.is_blocked()); // Record stop event HIP_CHECK(hipEventRecord(stop, nullptr)); @@ -166,7 +168,8 @@ TEST_CASE("Unit_hipEventElapsedTime_NotReady_Negative") { // stop event has not been completed float tElapsed = 1.0f; HIP_CHECK_ERROR(hipEventQuery(stop), hipErrorNotReady); - HIP_ASSERT(hipEventElapsedTime(&tElapsed,start,stop) == hipErrorNotReady); + HIP_ASSERT(hipEventElapsedTime(&tElapsed, start, stop) == hipErrorNotReady); + b_context.unblock_stream(); HIP_CHECK(hipStreamSynchronize(nullptr)); HIP_CHECK(hipEventDestroy(start)); diff --git a/projects/hip-tests/catch/unit/event/Unit_hipEventQuery.cc b/projects/hip-tests/catch/unit/event/Unit_hipEventQuery.cc index 726a57ca53..b9606fccf4 100644 --- a/projects/hip-tests/catch/unit/event/Unit_hipEventQuery.cc +++ b/projects/hip-tests/catch/unit/event/Unit_hipEventQuery.cc @@ -19,57 +19,6 @@ THE SOFTWARE. #include -/** - * @addtogroup hipEventQuery hipEventQuery - * @{ - * @ingroup EventTest - * `hipEventQuery(hipEvent_t event)` - - * Query the status of the specified event. - * ________________________ - * Test cases from other modules: - * - @ref Unit_hipEventIpc - */ - -// Since we can not use atomic*_system on every gpu, we will use wait based on clock rate. -// This wont be accurate since current clock rate of a GPU varies depending on many variables -// including thermals, load, utilization etc -__global__ void waitKernel(int clockRate, int seconds) { - auto start = clock(); - auto ms = seconds * 1000; - long long waitTill = clockRate * (long long)ms; - while (1) { - auto end = clock(); - if ((end - start) > waitTill) { - return; - } - } -} - -__global__ void waitKernel_gfx11(int clockRate, int seconds) { -#if HT_AMD - auto start = wall_clock64(); - auto ms = seconds * 1000; - long long waitTill = clockRate * (long long)ms; - while (1) { - auto end = wall_clock64(); - if ((end - start) > waitTill) { - return; - } - } -#endif -} - -/** - * Test Description - * ------------------------ - * - Query events with a single and with multiple devices. - * Test source - * ------------------------ - * - unit/event/Unit_hipEventQuery.cc - * Test requirements - * ------------------------ - * - HIP_VERSION >= 5.2 - */ TEST_CASE("Unit_hipEventQuery_DifferentDevice") { hipEvent_t event1{}, event2{}; HIP_CHECK(hipEventCreate(&event1)); @@ -81,19 +30,14 @@ TEST_CASE("Unit_hipEventQuery_DifferentDevice") { HIP_CHECK(hipStreamCreate(&stream)); REQUIRE(stream != nullptr); - hipDeviceProp_t prop{}; - HIP_CHECK(hipGetDeviceProperties(&prop, 0)); - auto clockRate = prop.clockRate; - - // Start kernel on 1st device + HipTest::BlockingContext b_context1{stream}; // og context + // Block stream { HIP_CHECK(hipSetDevice(0)); HIP_CHECK(hipEventRecord(event1, stream)); - auto waitKernel_used = IsGfx11() ? waitKernel_gfx11 : waitKernel; - // Start kernel and wait for 3 seconds - // Make sure you increase this time if you add more tests here - waitKernel_used<<<1, 1, 0, stream>>>(clockRate, 3); + b_context1.block_stream(); // blocked stream + REQUIRE(b_context1.is_blocked()); HIP_CHECK(hipEventRecord(event2, stream)); @@ -101,7 +45,7 @@ TEST_CASE("Unit_hipEventQuery_DifferentDevice") { HIP_CHECK(hipEventQuery(event1)); // Should be done HIP_CHECK_ERROR(hipEventQuery(event2), - hipErrorNotReady); // Wont be done since kernel is waiting + hipErrorNotReady); // Wont be done since stream is blocked } // If other devices are available, set it @@ -114,8 +58,8 @@ TEST_CASE("Unit_hipEventQuery_DifferentDevice") { HIP_CHECK(hipEventQuery(event1)); HIP_CHECK_ERROR(hipEventQuery(event2), hipErrorNotReady); - // Sync - // if it hangs here it means GPU kernel cant see the value update by atomic store + b_context1.unblock_stream(); + HIP_CHECK(hipEventSynchronize(event2)); // Query, should be done now From a1eee140720ad9b229b0e4fad72bcf2a4214b16f Mon Sep 17 00:00:00 2001 From: Maneesh Gupta Date: Mon, 10 Jul 2023 11:47:54 +0530 Subject: [PATCH 16/25] Disable test Unit_hipExtModuleLaunchKernel_NonUniformWorkGroup (#361) * Update config_amd_linux_common.json * Update config_amd_windows_common.json [ROCm/hip-tests commit: e4734d3ec4223aaf2797960fcfa13010cd41b306] --- .../catch/hipTestMain/config/config_amd_linux_common.json | 3 ++- .../catch/hipTestMain/config/config_amd_windows_common.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json b/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json index 4d26b020ae..b81d7a3d2a 100644 --- a/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json +++ b/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json @@ -109,6 +109,7 @@ "Unit_ChannelDescriptor_Positive_Basic_2D - ulong2", "Unit_ChannelDescriptor_Positive_Basic_2D - long2", "Unit_ChannelDescriptor_Positive_Basic_4D - ulong4", - "Unit_ChannelDescriptor_Positive_Basic_4D - long4" + "Unit_ChannelDescriptor_Positive_Basic_4D - long4", + "Unit_hipExtModuleLaunchKernel_NonUniformWorkGroup" ] } diff --git a/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json b/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json index d5faf9b538..db470678d9 100644 --- a/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json +++ b/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json @@ -199,6 +199,7 @@ "Unit_ChannelDescriptor_Positive_Basic_3D - ulong3", "Unit_ChannelDescriptor_Positive_Basic_3D - long3", "Unit_ChannelDescriptor_Positive_Basic_4D - ulong4", - "Unit_ChannelDescriptor_Positive_Basic_4D - long4" + "Unit_ChannelDescriptor_Positive_Basic_4D - long4", + "Unit_hipExtModuleLaunchKernel_NonUniformWorkGroup" ] } From 5309a60ae238ddd23c16683b64204bf6d2c7fc04 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Mon, 10 Jul 2023 18:59:53 +0530 Subject: [PATCH 17/25] SWDEV-373231 - Enable RTC atomics tests as they are fixed (#127) Change-Id: I4b6ef78a5b1bb537e2e89b5e36a045cd2ec935d4 [ROCm/hip-tests commit: 9adcb28335e558fab129788c6b8a7e04dac00ea5] --- .../config/config_amd_linux_MI2xx.json | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_MI2xx.json b/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_MI2xx.json index a7f158e9b4..e8a37c2830 100644 --- a/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_MI2xx.json +++ b/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_MI2xx.json @@ -5,21 +5,18 @@ "Unit_hipMallocManaged_OverSubscription", "Unit_hipDeviceGetPCIBusId_Negative_PartialFill", "Unit_hipInit_Negative", - "Unit_BuiltinAtomicsRTC_fmaxCoherentGlobalMem", - "Unit_BuiltinAtomicsRTC__fminCoherentGlobalMem", - "Unit_BuiltInAtomicAdd_CoherentGlobalMemWithRtc", "Unit_hipMemGetAddressRange_Negative", - "Unit_hipExternalMemoryGetMappedBuffer_Vulkan_Positive_Read_Write", - "Unit_hipExternalMemoryGetMappedBuffer_Vulkan_Negative_Parameters", - "Unit_hipImportExternalMemory_Vulkan_Negative_Parameters", - "Unit_hipWaitExternalSemaphoresAsync_Vulkan_Positive_Binary_Semaphore", - "Unit_hipWaitExternalSemaphoresAsync_Vulkan_Positive_Multiple_Semaphores", - "Unit_hipWaitExternalSemaphoresAsync_Vulkan_Negative_Parameters", - "Unit_hipSignalExternalSemaphoresAsync_Vulkan_Positive_Binary_Semaphore", - "Unit_hipSignalExternalSemaphoresAsync_Vulkan_Positive_Multiple_Semaphores", - "Unit_hipSignalExternalSemaphoresAsync_Vulkan_Negative_Parameters", - "Unit_hipImportExternalSemaphore_Vulkan_Negative_Parameters", - "Unit_hipDestroyExternalSemaphore_Vulkan_Negative_Parameters" + "Unit_hipExternalMemoryGetMappedBuffer_Vulkan_Positive_Read_Write", + "Unit_hipExternalMemoryGetMappedBuffer_Vulkan_Negative_Parameters", + "Unit_hipImportExternalMemory_Vulkan_Negative_Parameters", + "Unit_hipWaitExternalSemaphoresAsync_Vulkan_Positive_Binary_Semaphore", + "Unit_hipWaitExternalSemaphoresAsync_Vulkan_Positive_Multiple_Semaphores", + "Unit_hipWaitExternalSemaphoresAsync_Vulkan_Negative_Parameters", + "Unit_hipSignalExternalSemaphoresAsync_Vulkan_Positive_Binary_Semaphore", + "Unit_hipSignalExternalSemaphoresAsync_Vulkan_Positive_Multiple_Semaphores", + "Unit_hipSignalExternalSemaphoresAsync_Vulkan_Negative_Parameters", + "Unit_hipImportExternalSemaphore_Vulkan_Negative_Parameters", + "Unit_hipDestroyExternalSemaphore_Vulkan_Negative_Parameters" ] } From b39c25b32bb5908a2f1070ed5e7e4224e84aeeee Mon Sep 17 00:00:00 2001 From: music-dino <111048524+music-dino@users.noreply.github.com> Date: Tue, 11 Jul 2023 05:58:26 +0200 Subject: [PATCH 18/25] EXSWHTEC-75 - Implement tests for hipMemcpyAsync and derivatives (#18) - Basic positive tests - Negative parameter tests - Disable tests failing on CI [ROCm/hip-tests commit: 3f9c1dd5b37b88901554269921e9dfd7099a9813] --- .../config/config_amd_linux_common.json | 7 +- .../config/config_amd_windows_common.json | 7 +- .../catch/unit/memory/CMakeLists.txt | 2 + .../catch/unit/memory/hipMemcpyAsync.cc | 499 +++++------------- .../unit/memory/hipMemcpyAsync_derivatives.cc | 175 ++++++ .../catch/unit/memory/hipMemcpyAsync_old.cc | 408 ++++++++++++++ 6 files changed, 724 insertions(+), 374 deletions(-) create mode 100644 projects/hip-tests/catch/unit/memory/hipMemcpyAsync_derivatives.cc create mode 100644 projects/hip-tests/catch/unit/memory/hipMemcpyAsync_old.cc diff --git a/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json b/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json index b81d7a3d2a..2ba59aac81 100644 --- a/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json +++ b/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json @@ -110,6 +110,11 @@ "Unit_ChannelDescriptor_Positive_Basic_2D - long2", "Unit_ChannelDescriptor_Positive_Basic_4D - ulong4", "Unit_ChannelDescriptor_Positive_Basic_4D - long4", - "Unit_hipExtModuleLaunchKernel_NonUniformWorkGroup" + "Unit_hipExtModuleLaunchKernel_NonUniformWorkGroup", + "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/18 ===", + "Unit_hipMemcpyAsync_Negative_Parameters", + "Unit_hipMemcpyDtoHAsync_Negative_Parameters", + "Unit_hipMemcpyHtoDAsync_Negative_Parameters", + "Unit_hipMemcpyDtoDAsync_Negative_Parameters" ] } diff --git a/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json b/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json index db470678d9..80401608ef 100644 --- a/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json +++ b/projects/hip-tests/catch/hipTestMain/config/config_amd_windows_common.json @@ -200,6 +200,11 @@ "Unit_ChannelDescriptor_Positive_Basic_3D - long3", "Unit_ChannelDescriptor_Positive_Basic_4D - ulong4", "Unit_ChannelDescriptor_Positive_Basic_4D - long4", - "Unit_hipExtModuleLaunchKernel_NonUniformWorkGroup" + "Unit_hipExtModuleLaunchKernel_NonUniformWorkGroup", + "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/18 ===", + "Unit_hipMemcpyAsync_Negative_Parameters", + "Unit_hipMemcpyDtoHAsync_Negative_Parameters", + "Unit_hipMemcpyHtoDAsync_Negative_Parameters", + "Unit_hipMemcpyDtoDAsync_Negative_Parameters" ] } diff --git a/projects/hip-tests/catch/unit/memory/CMakeLists.txt b/projects/hip-tests/catch/unit/memory/CMakeLists.txt index f09f0579f4..ff9eaa4f71 100644 --- a/projects/hip-tests/catch/unit/memory/CMakeLists.txt +++ b/projects/hip-tests/catch/unit/memory/CMakeLists.txt @@ -83,6 +83,8 @@ set(TEST_SRC hipMemcpy_old.cc hipMemcpy_derivatives.cc hipMemcpyAsync.cc + hipMemcpyAsync_old.cc + hipMemcpyAsync_derivatives.cc hipMemsetFunctional.cc hipMalloc.cc hipMallocPitch.cc diff --git a/projects/hip-tests/catch/unit/memory/hipMemcpyAsync.cc b/projects/hip-tests/catch/unit/memory/hipMemcpyAsync.cc index 4c4e08ec2d..cd88356408 100644 --- a/projects/hip-tests/catch/unit/memory/hipMemcpyAsync.cc +++ b/projects/hip-tests/catch/unit/memory/hipMemcpyAsync.cc @@ -1,13 +1,15 @@ /* -Copyright (c) 2022 - present Advanced Micro Devices, Inc. All rights reserved. +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 @@ -17,392 +19,145 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* -This testcase verifies the following scenarios -1. hipMemcpyAsync with kernel launch -2. H2D-D2D-D2H-H2PinnMem and device context change scenarios -3. This test launches multiple threads which uses same stream to deploy kernel - and also launch hipMemcpyAsync() api. This test case is simulate the scenario - reported in SWDEV-181598. -*/ - #include -#include -#include -#include +#include +#include +#include +#include -#define NUM_THREADS 16 +TEST_CASE("Unit_hipMemcpyAsync_Positive_Basic") { + using namespace std::placeholders; + const auto stream_type = GENERATE(Streams::nullstream, Streams::perThread, Streams::created); + const StreamGuard stream_guard(stream_type); + const hipStream_t stream = stream_guard.stream(); -static constexpr auto NUM_ELM{1024 * 1024}; - - - -static constexpr size_t N_ELMTS{32 * 1024}; -std::atomic Thread_count { 0 }; -static unsigned blocksPerCU{6}; // to hide latency -static unsigned threadsPerBlock{256}; - -template -void Thread_func(T *A_d, T *B_d, T* C_d, T* C_h, size_t Nbytes, - hipStream_t mystream) { - unsigned blocks = HipTest::setNumBlocks(blocksPerCU, - threadsPerBlock, N_ELMTS); - hipLaunchKernelGGL(HipTest::vector_square, dim3(blocks), - dim3(threadsPerBlock), 0, - mystream, A_d, C_d, N_ELMTS); - HIP_CHECK(hipGetLastError()); - HIP_CHECK(hipMemcpyAsync(C_h, C_d, Nbytes, hipMemcpyDeviceToHost, mystream)); - // The following two MemcpyAsync calls are for sole - // purpose of loading stream with multiple async calls - HIP_CHECK(hipMemcpyAsync(B_d, A_d, Nbytes, - hipMemcpyDeviceToDevice, mystream)); - HIP_CHECK(hipMemcpyAsync(B_d, A_d, Nbytes, - hipMemcpyDeviceToDevice, mystream)); - Thread_count++; + MemcpyWithDirectionCommonTests(std::bind(hipMemcpyAsync, _1, _2, _3, _4, stream)); } -template -void Thread_func_MultiStream() { - int Data_mismatch = 0; - T *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr}; - T *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr}; - size_t Nbytes = N_ELMTS * sizeof(T); - unsigned blocks = HipTest::setNumBlocks(blocksPerCU, - threadsPerBlock, N_ELMTS); - HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, N_ELMTS, false); - hipStream_t mystream; - HIP_CHECK(hipStreamCreateWithFlags(&mystream, hipStreamNonBlocking)); - HIP_CHECK(hipMemcpyAsync(A_d, A_h, Nbytes, hipMemcpyHostToDevice, mystream)); - hipLaunchKernelGGL((HipTest::vector_square), dim3(blocks), - dim3(threadsPerBlock), 0, - mystream, A_d, C_d, N_ELMTS); - HIP_CHECK(hipGetLastError()); - HIP_CHECK(hipMemcpyAsync(C_h, C_d, Nbytes, hipMemcpyDeviceToHost, mystream)); - // The following hipMemcpyAsync() is called only to - // load stream with multiple Async calls - HIP_CHECK(hipMemcpyAsync(B_d, A_d, Nbytes, - hipMemcpyDeviceToDevice, mystream)); - Thread_count++; +TEST_CASE("Unit_hipMemcpyAsync_Positive_Synchronization_Behavior") { + using namespace std::placeholders; + HIP_CHECK(hipDeviceSynchronize()); - HIP_CHECK(hipStreamSynchronize(mystream)); - HIP_CHECK(hipStreamDestroy(mystream)); - // Verifying result of the kernel computation - for (size_t i = 0; i < N_ELMTS; i++) { - if (C_h[i] != A_h[i] * A_h[i]) { - Data_mismatch++; - } - } - // Releasing resources - HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false); - REQUIRE(Data_mismatch == 0); -} - -/* -This testcase verifies hipMemcpyAsync API -Initializes device variables -Launches kernel and performs the sum of device variables -copies the result to host variable and validates the result. -*/ -TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_KernelLaunch", "", int, float, - double) { - size_t Nbytes = NUM_ELM * sizeof(TestType); - - TestType *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr}; - TestType *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr}; - HIP_CHECK(hipSetDevice(0)); - hipStream_t stream; - HIP_CHECK(hipStreamCreate(&stream)); - - HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, NUM_ELM, false); - - HIP_CHECK(hipMemcpyAsync(A_d, A_h, Nbytes, hipMemcpyHostToDevice, stream)); - HIP_CHECK(hipMemcpyAsync(B_d, B_h, Nbytes, hipMemcpyHostToDevice, stream)); - HIP_CHECK(hipStreamSynchronize(stream)); - - hipLaunchKernelGGL(HipTest::vectorADD, dim3(1), dim3(1), 0, 0, - static_cast(A_d), - static_cast(B_d), C_d, NUM_ELM); - HIP_CHECK(hipGetLastError()); - HIP_CHECK(hipMemcpyAsync(C_h, C_d, Nbytes, hipMemcpyDeviceToHost, stream)); - HIP_CHECK(hipStreamSynchronize(stream)); - HIP_CHECK(hipStreamDestroy(stream)); - - HipTest::checkVectorADD(A_h, B_h, C_h, NUM_ELM); - - HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false); -} -/* -This testcase verifies the following scenarios -1. H2H,H2PinMem and PinnedMem2Host -2. H2D-D2D-D2H in same GPU -3. Pinned Host Memory to device variables in same GPU -4. Device context change -5. H2D-D2D-D2H peer GPU -*/ -TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_H2H-H2D-D2H-H2PinMem", "", char, int, - float, double) { - TestType *A_d{nullptr}, *B_d{nullptr}; - TestType *A_h{nullptr}, *B_h{nullptr}; - TestType *A_Ph{nullptr}, *B_Ph{nullptr}; - HIP_CHECK(hipSetDevice(0)); - hipStream_t stream; - HIP_CHECK(hipStreamCreate(&stream)); - HipTest::initArrays(&A_d, &B_d, nullptr, - &A_h, &B_h, nullptr, - NUM_ELM*sizeof(TestType)); - HipTest::initArrays(nullptr, nullptr, nullptr, - &A_Ph, &B_Ph, nullptr, - NUM_ELM*sizeof(TestType), true); - - SECTION("H2H, H2PinMem and PinMem2H") { - HIP_CHECK(hipMemcpyAsync(B_h, A_h, NUM_ELM*sizeof(TestType), - hipMemcpyHostToHost, stream)); - HIP_CHECK(hipMemcpyAsync(A_Ph, B_h, NUM_ELM*sizeof(TestType), - hipMemcpyHostToHost, stream)); - HIP_CHECK(hipMemcpyAsync(B_Ph, A_Ph, NUM_ELM*sizeof(TestType), - hipMemcpyHostToHost, stream)); - HIP_CHECK(hipStreamSynchronize(stream)); - HipTest::checkTest(A_h, B_Ph, NUM_ELM); + SECTION("Host memory to device memory") { + // This behavior differs on NVIDIA and AMD, on AMD the hipMemcpy calls is synchronous with + // respect to the host +#if HT_AMD + HipTest::HIP_SKIP_TEST( + "EXSWCPHIPT-127 - MemcpyAsync from host to device memory behavior differs on AMD and " + "Nvidia"); + return; +#endif + MemcpyHtoDSyncBehavior(std::bind(hipMemcpyAsync, _1, _2, _3, hipMemcpyHostToDevice, nullptr), + false); } - SECTION("H2D-D2D-D2H-SameGPU") { - HIP_CHECK(hipMemcpyAsync(A_d, A_h, NUM_ELM*sizeof(TestType), - hipMemcpyHostToDevice, stream)); - HIP_CHECK(hipMemcpyAsync(B_d, A_d, NUM_ELM*sizeof(TestType), - hipMemcpyDeviceToDevice, stream)); - HIP_CHECK(hipMemcpyAsync(B_h, B_d, NUM_ELM*sizeof(TestType), - hipMemcpyDeviceToHost, stream)); - HIP_CHECK(hipStreamSynchronize(stream)); - HipTest::checkTest(A_h, B_h, NUM_ELM); + SECTION("Device memory to pageable host memory") { + MemcpyDtoHPageableSyncBehavior( + std::bind(hipMemcpyAsync, _1, _2, _3, hipMemcpyDeviceToHost, nullptr), true); } - SECTION("pH2D-D2D-D2pH-SameGPU") { - HIP_CHECK(hipMemcpyAsync(A_d, A_Ph, NUM_ELM*sizeof(TestType), - hipMemcpyHostToDevice, stream)); - HIP_CHECK(hipMemcpyAsync(B_d, A_d, NUM_ELM*sizeof(TestType), - hipMemcpyDeviceToDevice, stream)); - HIP_CHECK(hipMemcpyAsync(B_Ph, B_d, NUM_ELM*sizeof(TestType), - hipMemcpyDeviceToHost, stream)); - HIP_CHECK(hipStreamSynchronize(stream)); - HipTest::checkTest(A_Ph, B_Ph, NUM_ELM); - } - SECTION("H2D-D2D-D2H-DeviceContextChange") { - int deviceCount = 0; - HIP_CHECK(hipGetDeviceCount(&deviceCount)); - if (deviceCount < 2) { - SUCCEED("deviceCount less then 2"); - } else { - int canAccessPeer = 0; - HIP_CHECK(hipDeviceCanAccessPeer(&canAccessPeer, 0, 1)); - if (canAccessPeer) { - HIP_CHECK(hipSetDevice(1)); - HIP_CHECK(hipMemcpyAsync(A_d, A_h, NUM_ELM*sizeof(TestType), - hipMemcpyHostToDevice, stream)); - HIP_CHECK(hipMemcpyAsync(B_d, A_d, NUM_ELM*sizeof(TestType), - hipMemcpyDeviceToDevice, stream)); - HIP_CHECK(hipMemcpyAsync(B_h, B_d, NUM_ELM*sizeof(TestType), - hipMemcpyDeviceToHost, stream)); - HIP_CHECK(hipStreamSynchronize(stream)); - HipTest::checkTest(A_h, B_h, NUM_ELM); - - } else { - SUCCEED("P2P capability is not present"); - } - } + SECTION("Device memory to pinned host memory") { + MemcpyDtoHPinnedSyncBehavior( + std::bind(hipMemcpyAsync, _1, _2, _3, hipMemcpyDeviceToHost, nullptr), false); } - SECTION("H2D-D2D-D2H-PeerGPU") { - int deviceCount = 0; - HIP_CHECK(hipGetDeviceCount(&deviceCount)); - if (deviceCount < 2) { - SUCCEED("deviceCount less then 2"); - } else { - int canAccessPeer = 0; - HIP_CHECK(hipDeviceCanAccessPeer(&canAccessPeer, 0, 1)); - if (canAccessPeer) { - HIP_CHECK(hipSetDevice(1)); - TestType *C_d{nullptr}; - HipTest::initArrays(nullptr, nullptr, &C_d, - nullptr, nullptr, nullptr, - NUM_ELM*sizeof(TestType)); - HIP_CHECK(hipMemcpyAsync(A_d, A_h, NUM_ELM*sizeof(TestType), - hipMemcpyHostToDevice, stream)); - HIP_CHECK(hipMemcpyAsync(C_d, A_d, NUM_ELM*sizeof(TestType), - hipMemcpyDeviceToDevice, stream)); - HIP_CHECK(hipMemcpyAsync(B_h, C_d, NUM_ELM*sizeof(TestType), - hipMemcpyDeviceToHost, stream)); - HIP_CHECK(hipStreamSynchronize(stream)); - HipTest::checkTest(A_h, B_h, NUM_ELM); - HIP_CHECK(hipFree(C_d)); - - } else { - SUCCEED("P2P capability is not present"); - } - } + SECTION("Device memory to device memory") { + MemcpyDtoDSyncBehavior(std::bind(hipMemcpyAsync, _1, _2, _3, hipMemcpyDeviceToDevice, nullptr), + false); } - HIP_CHECK(hipStreamDestroy(stream)); - - HipTest::freeArrays(A_d, B_d, nullptr, A_h, B_h, nullptr, false); - HipTest::freeArrays(nullptr, nullptr, nullptr, A_Ph, - B_Ph, nullptr, true); -} - -// This test launches multiple threads which uses same stream to deploy kernel -// and also launch hipMemcpyAsync() api. This test case is simulate the scenario -// reported in SWDEV-181598 - -TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_hipMultiMemcpyMultiThread", "", - int, float, double) { - size_t Nbytes = N_ELMTS * sizeof(TestType); - - int Data_mismatch = 0; - hipStream_t mystream; - TestType *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr}; - TestType *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr}; - - HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, N_ELMTS, false); - - HIP_CHECK(hipStreamCreateWithFlags(&mystream, hipStreamNonBlocking)); - HIP_CHECK(hipMemcpyAsync(A_d, A_h, Nbytes, hipMemcpyHostToDevice, mystream)); - - std::thread T[NUM_THREADS]; - for (int i = 0; i < NUM_THREADS; i++) { - T[i] = std::thread(Thread_func, A_d, B_d, C_d, - C_h, Nbytes, mystream); - } - - // Wait until all the threads finish their execution - for (int i = 0; i < NUM_THREADS; i++) { - T[i].join(); - } - - HIP_CHECK(hipStreamSynchronize(mystream)); - HIP_CHECK(hipStreamDestroy(mystream)); - - // Verifying the result of the kernel computation - for (size_t i = 0; i < N_ELMTS; i++) { - if (C_h[i] != A_h[i] * A_h[i]) { - Data_mismatch++; - } - } - REQUIRE(Thread_count.load() == NUM_THREADS); - REQUIRE(Data_mismatch == 0); - HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false); - Thread_count.exchange(0); -} - -TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_hipMultiMemcpyMultiThreadMultiStream", - "", int, float, double) { - std::thread T[NUM_THREADS]; - for (int i = 0; i < NUM_THREADS; i++) { - T[i] = std::thread(Thread_func_MultiStream); - } - - // Wait until all the threads finish their execution - for (int i = 0; i < NUM_THREADS; i++) { - T[i].join(); - } - - REQUIRE(Thread_count.load() == NUM_THREADS); - Thread_count.exchange(0); -} - -/* -This testcase verifies hipMemcpy API with pinnedMemory and hostRegister -along with kernel launches -*/ - -TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_PinnedRegMemWithKernelLaunch", - "", int, float, double) { - int numDevices = 0; - HIP_CHECK(hipGetDeviceCount(&numDevices)); - if (numDevices < 2) { - SUCCEED("No of devices are less than 2"); - } else { - // 1 refers to pinned Memory - // 2 refers to register Memory - int MallocPinType = GENERATE(0, 1); - size_t Nbytes = NUM_ELM * sizeof(TestType); - unsigned blocks = HipTest::setNumBlocks(blocksPerCU, - threadsPerBlock, NUM_ELM); - - TestType *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr}; - TestType *X_d{nullptr}, *Y_d{nullptr}, *Z_d{nullptr}; - TestType *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr}; - if (MallocPinType) { - HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, NUM_ELM, true); - } else { - A_h = reinterpret_cast(malloc(Nbytes)); - HIP_CHECK(hipHostRegister(A_h, Nbytes, hipHostRegisterDefault)); - B_h = reinterpret_cast(malloc(Nbytes)); - HIP_CHECK(hipHostRegister(B_h, Nbytes, hipHostRegisterDefault)); - C_h = reinterpret_cast(malloc(Nbytes)); - HIP_CHECK(hipHostRegister(C_h, Nbytes, hipHostRegisterDefault)); - HipTest::initArrays(&A_d, &B_d, &C_d, nullptr, nullptr, - nullptr, NUM_ELM, false); - HipTest::setDefaultData(NUM_ELM, A_h, B_h, C_h); - } - HIP_CHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice)); - HIP_CHECK(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice)); - - hipLaunchKernelGGL(HipTest::vectorADD, dim3(blocks), dim3(threadsPerBlock), - 0, 0, static_cast(A_d), - static_cast(B_d), C_d, NUM_ELM); - HIP_CHECK(hipGetLastError()); - HIP_CHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); - HipTest::checkVectorADD(A_h, B_h, C_h, NUM_ELM); - - unsigned int seed = time(0); - HIP_CHECK(hipSetDevice(HipTest::RAND_R(&seed) % (numDevices-1)+1)); - - int device; - HIP_CHECK(hipGetDevice(&device)); - INFO("hipMemcpy is set to happen between device 0 and device " - << device); - HipTest::initArrays(&X_d, &Y_d, &Z_d, nullptr, - nullptr, nullptr, NUM_ELM, false); - - hipStream_t gpu1Stream; - HIP_CHECK(hipStreamCreate(&gpu1Stream)); - - for (int j = 0; j < NUM_ELM; j++) { - A_h[j] = 0; - B_h[j] = 0; - C_h[j] = 0; - } - - HIP_CHECK(hipMemcpy(A_h, A_d, Nbytes, hipMemcpyDeviceToHost)); - HIP_CHECK(hipMemcpyAsync(X_d, A_h, Nbytes, hipMemcpyHostToDevice, gpu1Stream)); - HIP_CHECK(hipMemcpy(B_h, B_d, Nbytes, hipMemcpyDeviceToHost)); - HIP_CHECK(hipMemcpyAsync(Y_d, B_h, Nbytes, hipMemcpyHostToDevice, gpu1Stream)); - - hipLaunchKernelGGL(HipTest::vectorADD, dim3(blocks), dim3(threadsPerBlock), - 0, 0, static_cast(X_d), - static_cast(Y_d), Z_d, NUM_ELM); - HIP_CHECK(hipGetLastError()); - HIP_CHECK(hipMemcpyAsync(C_h, Z_d, Nbytes, - hipMemcpyDeviceToHost, gpu1Stream)); - HIP_CHECK(hipStreamSynchronize(gpu1Stream)); - - HipTest::checkVectorADD(A_h, B_h, C_h, NUM_ELM); - - if (MallocPinType) { - HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, true); - } else { - HIP_CHECK(hipHostUnregister(A_h)); - free(A_h); - HIP_CHECK(hipHostUnregister(B_h)); - free(B_h); - HIP_CHECK(hipHostUnregister(C_h)); - free(C_h); - HipTest::freeArrays(A_d, B_d, C_d, nullptr, - nullptr, nullptr, false); - } - HipTest::freeArrays(X_d, Y_d, Z_d, nullptr, - nullptr, nullptr, false); - HIP_CHECK(hipStreamDestroy(gpu1Stream)); + SECTION("Host memory to host memory") { + MemcpyHtoHSyncBehavior(std::bind(hipMemcpyAsync, _1, _2, _3, hipMemcpyHostToHost, nullptr), + true); } } +TEST_CASE("Unit_hipMemcpyAsync_Negative_Parameters") { + using namespace std::placeholders; + constexpr auto InvalidStream = [] { + StreamGuard sg(Streams::created); + return sg.stream(); + }; + + SECTION("Host to device") { + LinearAllocGuard device_alloc(LinearAllocs::hipMalloc, kPageSize); + LinearAllocGuard host_alloc(LinearAllocs::hipHostMalloc, kPageSize); + + MemcpyCommonNegativeTests(std::bind(hipMemcpyAsync, _1, _2, _3, hipMemcpyHostToDevice, nullptr), + device_alloc.ptr(), host_alloc.ptr(), kPageSize); + + SECTION("Invalid MemcpyKind") { + HIP_CHECK_ERROR(hipMemcpyAsync(device_alloc.ptr(), host_alloc.ptr(), kPageSize, + static_cast(-1), nullptr), + hipErrorInvalidMemcpyDirection); + } + + SECTION("Invalid stream") { + HIP_CHECK_ERROR(hipMemcpyAsync(device_alloc.ptr(), host_alloc.ptr(), kPageSize, + hipMemcpyHostToDevice, InvalidStream()), + hipErrorContextIsDestroyed); + } + } + + SECTION("Device to host") { + LinearAllocGuard device_alloc(LinearAllocs::hipMalloc, kPageSize); + LinearAllocGuard host_alloc(LinearAllocs::hipHostMalloc, kPageSize); + + MemcpyCommonNegativeTests(std::bind(hipMemcpyAsync, _1, _2, _3, hipMemcpyDeviceToHost, nullptr), + host_alloc.ptr(), device_alloc.ptr(), kPageSize); + + SECTION("Invalid MemcpyKind") { + HIP_CHECK_ERROR(hipMemcpyAsync(host_alloc.ptr(), device_alloc.ptr(), kPageSize, + static_cast(-1), nullptr), + hipErrorInvalidMemcpyDirection); + } + + SECTION("Invalid stream") { + HIP_CHECK_ERROR(hipMemcpyAsync(host_alloc.ptr(), device_alloc.ptr(), kPageSize, + hipMemcpyDeviceToHost, InvalidStream()), + hipErrorContextIsDestroyed); + } + } + + SECTION("Host to host") { + LinearAllocGuard src_alloc(LinearAllocs::hipHostMalloc, kPageSize); + LinearAllocGuard dst_alloc(LinearAllocs::hipHostMalloc, kPageSize); + + MemcpyCommonNegativeTests(std::bind(hipMemcpyAsync, _1, _2, _3, hipMemcpyHostToHost, nullptr), + dst_alloc.ptr(), src_alloc.ptr(), kPageSize); + + SECTION("Invalid MemcpyKind") { + HIP_CHECK_ERROR(hipMemcpyAsync(dst_alloc.ptr(), src_alloc.ptr(), kPageSize, + static_cast(-1), nullptr), + hipErrorInvalidMemcpyDirection); + } + + SECTION("Invalid stream") { + HIP_CHECK_ERROR(hipMemcpyAsync(dst_alloc.ptr(), src_alloc.ptr(), kPageSize, + hipMemcpyHostToHost, InvalidStream()), + hipErrorContextIsDestroyed); + } + } + + SECTION("Device to device") { + LinearAllocGuard src_alloc(LinearAllocs::hipMalloc, kPageSize); + LinearAllocGuard dst_alloc(LinearAllocs::hipMalloc, kPageSize); + + MemcpyCommonNegativeTests( + std::bind(hipMemcpyAsync, _1, _2, _3, hipMemcpyDeviceToDevice, nullptr), dst_alloc.ptr(), + src_alloc.ptr(), kPageSize); + + SECTION("Invalid MemcpyKind") { + HIP_CHECK_ERROR(hipMemcpyAsync(src_alloc.ptr(), dst_alloc.ptr(), kPageSize, + static_cast(-1), nullptr), + hipErrorInvalidMemcpyDirection); + } + + SECTION("Invalid stream") { + HIP_CHECK_ERROR(hipMemcpyAsync(dst_alloc.ptr(), src_alloc.ptr(), kPageSize, + hipMemcpyDeviceToDevice, InvalidStream()), + hipErrorContextIsDestroyed); + } + } +} diff --git a/projects/hip-tests/catch/unit/memory/hipMemcpyAsync_derivatives.cc b/projects/hip-tests/catch/unit/memory/hipMemcpyAsync_derivatives.cc new file mode 100644 index 0000000000..251c630d52 --- /dev/null +++ b/projects/hip-tests/catch/unit/memory/hipMemcpyAsync_derivatives.cc @@ -0,0 +1,175 @@ +/* +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 + +static hipStream_t InvalidStream() { + StreamGuard sg(Streams::created); + return sg.stream(); +} + +TEST_CASE("Unit_hipMemcpyDtoHAsync_Positive_Basic") { + const auto stream_type = GENERATE(Streams::nullstream, Streams::perThread, Streams::created); + const StreamGuard stream_guard(stream_type); + + const auto f = [stream = stream_guard.stream()](void* dst, void* src, size_t count) { + return hipMemcpyDtoHAsync(dst, reinterpret_cast(src), count, stream); + }; + MemcpyDeviceToHostShell(f, stream_guard.stream()); +} + +TEST_CASE("Unit_hipMemcpyDtoHAsync_Positive_Synchronization_Behavior") { + HIP_CHECK(hipDeviceSynchronize()); + + SECTION("Device memory to pageable host memory") { + MemcpyDtoHPageableSyncBehavior( + [](void* dst, void* src, size_t count) { + return hipMemcpyDtoHAsync(dst, reinterpret_cast(src), count, nullptr); + }, + true); + } + + SECTION("Device memory to pinned host memory") { + MemcpyDtoHPinnedSyncBehavior( + [](void* dst, void* src, size_t count) { + return hipMemcpyDtoHAsync(dst, reinterpret_cast(src), count, nullptr); + }, + false); + } +} + +TEST_CASE("Unit_hipMemcpyDtoHAsync_Negative_Parameters") { + using namespace std::placeholders; + LinearAllocGuard device_alloc(LinearAllocs::hipMalloc, kPageSize); + LinearAllocGuard host_alloc(LinearAllocs::hipHostMalloc, kPageSize); + + MemcpyCommonNegativeTests( + [](void* dst, void* src, size_t count) { + return hipMemcpyDtoHAsync(dst, reinterpret_cast(src), count, nullptr); + }, + host_alloc.ptr(), device_alloc.ptr(), kPageSize); + + SECTION("Invalid stream") { + HIP_CHECK_ERROR( + hipMemcpyDtoHAsync(host_alloc.ptr(), reinterpret_cast(device_alloc.ptr()), + kPageSize, InvalidStream()), + hipErrorContextIsDestroyed); + } +} + +TEST_CASE("Unit_hipMemcpyHtoDAsync_Positive_Basic") { + const auto stream_type = GENERATE(Streams::nullstream, Streams::perThread, Streams::created); + const StreamGuard stream_guard(stream_type); + + const auto f = [stream = stream_guard.stream()](void* dst, void* src, size_t count) { + return hipMemcpyHtoDAsync(reinterpret_cast(dst), src, count, stream); + }; + MemcpyHostToDeviceShell(f, stream_guard.stream()); +} + +TEST_CASE("Unit_hipMemcpyHtoDAsync_Positive_Synchronization_Behavior") { + // This behavior differs on NVIDIA and AMD, on AMD the hipMemcpy calls is synchronous with + // respect to the host +#if HT_AMD + HipTest::HIP_SKIP_TEST( + "EXSWCPHIPT-127 - MemcpyAsync from host to device memory behavior differs on AMD and " + "Nvidia"); + return; +#endif + MemcpyHtoDSyncBehavior( + [](void* dst, void* src, size_t count) { + return hipMemcpyHtoDAsync(reinterpret_cast(dst), src, count, nullptr); + }, + false); +} + +TEST_CASE("Unit_hipMemcpyHtoDAsync_Negative_Parameters") { + using namespace std::placeholders; + LinearAllocGuard device_alloc(LinearAllocs::hipMalloc, kPageSize); + LinearAllocGuard host_alloc(LinearAllocs::hipHostMalloc, kPageSize); + + MemcpyCommonNegativeTests( + [](void* dst, void* src, size_t count) { + return hipMemcpyHtoDAsync(reinterpret_cast(dst), src, count, nullptr); + }, + device_alloc.ptr(), host_alloc.ptr(), kPageSize); + + SECTION("Invalid stream") { + HIP_CHECK_ERROR(hipMemcpyHtoDAsync(reinterpret_cast(device_alloc.ptr()), + host_alloc.ptr(), kPageSize, InvalidStream()), + hipErrorContextIsDestroyed); + } +} + +TEST_CASE("Unit_hipMemcpyDtoDAsync_Positive_Basic") { + const auto stream_type = GENERATE(Streams::nullstream, Streams::perThread, Streams::created); + const StreamGuard stream_guard(stream_type); + + SECTION("Device to device") { + SECTION("Peer access enabled") { + MemcpyDeviceToDeviceShell( + [stream = stream_guard.stream()](void* dst, void* src, size_t count) { + return hipMemcpyDtoDAsync(reinterpret_cast(dst), + reinterpret_cast(src), count, stream); + }); + } + SECTION("Peer access disabled") { + MemcpyDeviceToDeviceShell( + [stream = stream_guard.stream()](void* dst, void* src, size_t count) { + return hipMemcpyDtoDAsync(reinterpret_cast(dst), + reinterpret_cast(src), count, stream); + }); + } + } +} + +TEST_CASE("Unit_hipMemcpyDtoDAsync_Positive_Synchronization_Behavior") { + MemcpyDtoDSyncBehavior( + [](void* dst, void* src, size_t count) { + return hipMemcpyDtoDAsync(reinterpret_cast(dst), + reinterpret_cast(src), count, nullptr); + }, + false); +} + +TEST_CASE("Unit_hipMemcpyDtoDAsync_Negative_Parameters") { + using namespace std::placeholders; + LinearAllocGuard src_alloc(LinearAllocs::hipMalloc, kPageSize); + LinearAllocGuard dst_alloc(LinearAllocs::hipMalloc, kPageSize); + + MemcpyCommonNegativeTests( + [](void* dst, void* src, size_t count) { + return hipMemcpyDtoDAsync(reinterpret_cast(dst), + reinterpret_cast(src), count, nullptr); + }, + dst_alloc.ptr(), src_alloc.ptr(), kPageSize); + + SECTION("Invalid stream") { + HIP_CHECK_ERROR(hipMemcpyDtoDAsync(reinterpret_cast(dst_alloc.ptr()), + reinterpret_cast(src_alloc.ptr()), kPageSize, + InvalidStream()), + hipErrorContextIsDestroyed); + } +} \ No newline at end of file diff --git a/projects/hip-tests/catch/unit/memory/hipMemcpyAsync_old.cc b/projects/hip-tests/catch/unit/memory/hipMemcpyAsync_old.cc new file mode 100644 index 0000000000..4c4e08ec2d --- /dev/null +++ b/projects/hip-tests/catch/unit/memory/hipMemcpyAsync_old.cc @@ -0,0 +1,408 @@ +/* +Copyright (c) 2022 - present 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. +*/ + +/* +This testcase verifies the following scenarios +1. hipMemcpyAsync with kernel launch +2. H2D-D2D-D2H-H2PinnMem and device context change scenarios +3. This test launches multiple threads which uses same stream to deploy kernel + and also launch hipMemcpyAsync() api. This test case is simulate the scenario + reported in SWDEV-181598. +*/ + +#include +#include +#include +#include + +#define NUM_THREADS 16 + +static constexpr auto NUM_ELM{1024 * 1024}; + + + +static constexpr size_t N_ELMTS{32 * 1024}; +std::atomic Thread_count { 0 }; +static unsigned blocksPerCU{6}; // to hide latency +static unsigned threadsPerBlock{256}; + +template +void Thread_func(T *A_d, T *B_d, T* C_d, T* C_h, size_t Nbytes, + hipStream_t mystream) { + unsigned blocks = HipTest::setNumBlocks(blocksPerCU, + threadsPerBlock, N_ELMTS); + hipLaunchKernelGGL(HipTest::vector_square, dim3(blocks), + dim3(threadsPerBlock), 0, + mystream, A_d, C_d, N_ELMTS); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipMemcpyAsync(C_h, C_d, Nbytes, hipMemcpyDeviceToHost, mystream)); + // The following two MemcpyAsync calls are for sole + // purpose of loading stream with multiple async calls + HIP_CHECK(hipMemcpyAsync(B_d, A_d, Nbytes, + hipMemcpyDeviceToDevice, mystream)); + HIP_CHECK(hipMemcpyAsync(B_d, A_d, Nbytes, + hipMemcpyDeviceToDevice, mystream)); + Thread_count++; +} + +template +void Thread_func_MultiStream() { + int Data_mismatch = 0; + T *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr}; + T *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr}; + size_t Nbytes = N_ELMTS * sizeof(T); + unsigned blocks = HipTest::setNumBlocks(blocksPerCU, + threadsPerBlock, N_ELMTS); + + HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, N_ELMTS, false); + hipStream_t mystream; + HIP_CHECK(hipStreamCreateWithFlags(&mystream, hipStreamNonBlocking)); + HIP_CHECK(hipMemcpyAsync(A_d, A_h, Nbytes, hipMemcpyHostToDevice, mystream)); + hipLaunchKernelGGL((HipTest::vector_square), dim3(blocks), + dim3(threadsPerBlock), 0, + mystream, A_d, C_d, N_ELMTS); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipMemcpyAsync(C_h, C_d, Nbytes, hipMemcpyDeviceToHost, mystream)); + // The following hipMemcpyAsync() is called only to + // load stream with multiple Async calls + HIP_CHECK(hipMemcpyAsync(B_d, A_d, Nbytes, + hipMemcpyDeviceToDevice, mystream)); + Thread_count++; + + HIP_CHECK(hipStreamSynchronize(mystream)); + HIP_CHECK(hipStreamDestroy(mystream)); + // Verifying result of the kernel computation + for (size_t i = 0; i < N_ELMTS; i++) { + if (C_h[i] != A_h[i] * A_h[i]) { + Data_mismatch++; + } + } + // Releasing resources + HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false); + REQUIRE(Data_mismatch == 0); +} + +/* +This testcase verifies hipMemcpyAsync API +Initializes device variables +Launches kernel and performs the sum of device variables +copies the result to host variable and validates the result. +*/ +TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_KernelLaunch", "", int, float, + double) { + size_t Nbytes = NUM_ELM * sizeof(TestType); + + TestType *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr}; + TestType *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr}; + HIP_CHECK(hipSetDevice(0)); + hipStream_t stream; + HIP_CHECK(hipStreamCreate(&stream)); + + HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, NUM_ELM, false); + + HIP_CHECK(hipMemcpyAsync(A_d, A_h, Nbytes, hipMemcpyHostToDevice, stream)); + HIP_CHECK(hipMemcpyAsync(B_d, B_h, Nbytes, hipMemcpyHostToDevice, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + hipLaunchKernelGGL(HipTest::vectorADD, dim3(1), dim3(1), 0, 0, + static_cast(A_d), + static_cast(B_d), C_d, NUM_ELM); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipMemcpyAsync(C_h, C_d, Nbytes, hipMemcpyDeviceToHost, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + HIP_CHECK(hipStreamDestroy(stream)); + + HipTest::checkVectorADD(A_h, B_h, C_h, NUM_ELM); + + HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false); +} +/* +This testcase verifies the following scenarios +1. H2H,H2PinMem and PinnedMem2Host +2. H2D-D2D-D2H in same GPU +3. Pinned Host Memory to device variables in same GPU +4. Device context change +5. H2D-D2D-D2H peer GPU +*/ +TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_H2H-H2D-D2H-H2PinMem", "", char, int, + float, double) { + TestType *A_d{nullptr}, *B_d{nullptr}; + TestType *A_h{nullptr}, *B_h{nullptr}; + TestType *A_Ph{nullptr}, *B_Ph{nullptr}; + HIP_CHECK(hipSetDevice(0)); + hipStream_t stream; + HIP_CHECK(hipStreamCreate(&stream)); + HipTest::initArrays(&A_d, &B_d, nullptr, + &A_h, &B_h, nullptr, + NUM_ELM*sizeof(TestType)); + HipTest::initArrays(nullptr, nullptr, nullptr, + &A_Ph, &B_Ph, nullptr, + NUM_ELM*sizeof(TestType), true); + + SECTION("H2H, H2PinMem and PinMem2H") { + HIP_CHECK(hipMemcpyAsync(B_h, A_h, NUM_ELM*sizeof(TestType), + hipMemcpyHostToHost, stream)); + HIP_CHECK(hipMemcpyAsync(A_Ph, B_h, NUM_ELM*sizeof(TestType), + hipMemcpyHostToHost, stream)); + HIP_CHECK(hipMemcpyAsync(B_Ph, A_Ph, NUM_ELM*sizeof(TestType), + hipMemcpyHostToHost, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + HipTest::checkTest(A_h, B_Ph, NUM_ELM); + } + + SECTION("H2D-D2D-D2H-SameGPU") { + HIP_CHECK(hipMemcpyAsync(A_d, A_h, NUM_ELM*sizeof(TestType), + hipMemcpyHostToDevice, stream)); + HIP_CHECK(hipMemcpyAsync(B_d, A_d, NUM_ELM*sizeof(TestType), + hipMemcpyDeviceToDevice, stream)); + HIP_CHECK(hipMemcpyAsync(B_h, B_d, NUM_ELM*sizeof(TestType), + hipMemcpyDeviceToHost, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + HipTest::checkTest(A_h, B_h, NUM_ELM); + } + + SECTION("pH2D-D2D-D2pH-SameGPU") { + HIP_CHECK(hipMemcpyAsync(A_d, A_Ph, NUM_ELM*sizeof(TestType), + hipMemcpyHostToDevice, stream)); + HIP_CHECK(hipMemcpyAsync(B_d, A_d, NUM_ELM*sizeof(TestType), + hipMemcpyDeviceToDevice, stream)); + HIP_CHECK(hipMemcpyAsync(B_Ph, B_d, NUM_ELM*sizeof(TestType), + hipMemcpyDeviceToHost, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + HipTest::checkTest(A_Ph, B_Ph, NUM_ELM); + } + SECTION("H2D-D2D-D2H-DeviceContextChange") { + int deviceCount = 0; + HIP_CHECK(hipGetDeviceCount(&deviceCount)); + if (deviceCount < 2) { + SUCCEED("deviceCount less then 2"); + } else { + int canAccessPeer = 0; + HIP_CHECK(hipDeviceCanAccessPeer(&canAccessPeer, 0, 1)); + if (canAccessPeer) { + HIP_CHECK(hipSetDevice(1)); + HIP_CHECK(hipMemcpyAsync(A_d, A_h, NUM_ELM*sizeof(TestType), + hipMemcpyHostToDevice, stream)); + HIP_CHECK(hipMemcpyAsync(B_d, A_d, NUM_ELM*sizeof(TestType), + hipMemcpyDeviceToDevice, stream)); + HIP_CHECK(hipMemcpyAsync(B_h, B_d, NUM_ELM*sizeof(TestType), + hipMemcpyDeviceToHost, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + HipTest::checkTest(A_h, B_h, NUM_ELM); + + } else { + SUCCEED("P2P capability is not present"); + } + } + } + + SECTION("H2D-D2D-D2H-PeerGPU") { + int deviceCount = 0; + HIP_CHECK(hipGetDeviceCount(&deviceCount)); + if (deviceCount < 2) { + SUCCEED("deviceCount less then 2"); + } else { + int canAccessPeer = 0; + HIP_CHECK(hipDeviceCanAccessPeer(&canAccessPeer, 0, 1)); + if (canAccessPeer) { + HIP_CHECK(hipSetDevice(1)); + TestType *C_d{nullptr}; + HipTest::initArrays(nullptr, nullptr, &C_d, + nullptr, nullptr, nullptr, + NUM_ELM*sizeof(TestType)); + HIP_CHECK(hipMemcpyAsync(A_d, A_h, NUM_ELM*sizeof(TestType), + hipMemcpyHostToDevice, stream)); + HIP_CHECK(hipMemcpyAsync(C_d, A_d, NUM_ELM*sizeof(TestType), + hipMemcpyDeviceToDevice, stream)); + HIP_CHECK(hipMemcpyAsync(B_h, C_d, NUM_ELM*sizeof(TestType), + hipMemcpyDeviceToHost, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + HipTest::checkTest(A_h, B_h, NUM_ELM); + HIP_CHECK(hipFree(C_d)); + + } else { + SUCCEED("P2P capability is not present"); + } + } + } + + HIP_CHECK(hipStreamDestroy(stream)); + + HipTest::freeArrays(A_d, B_d, nullptr, A_h, B_h, nullptr, false); + HipTest::freeArrays(nullptr, nullptr, nullptr, A_Ph, + B_Ph, nullptr, true); +} + +// This test launches multiple threads which uses same stream to deploy kernel +// and also launch hipMemcpyAsync() api. This test case is simulate the scenario +// reported in SWDEV-181598 + +TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_hipMultiMemcpyMultiThread", "", + int, float, double) { + size_t Nbytes = N_ELMTS * sizeof(TestType); + + int Data_mismatch = 0; + hipStream_t mystream; + TestType *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr}; + TestType *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr}; + + HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, N_ELMTS, false); + + HIP_CHECK(hipStreamCreateWithFlags(&mystream, hipStreamNonBlocking)); + HIP_CHECK(hipMemcpyAsync(A_d, A_h, Nbytes, hipMemcpyHostToDevice, mystream)); + + std::thread T[NUM_THREADS]; + for (int i = 0; i < NUM_THREADS; i++) { + T[i] = std::thread(Thread_func, A_d, B_d, C_d, + C_h, Nbytes, mystream); + } + + // Wait until all the threads finish their execution + for (int i = 0; i < NUM_THREADS; i++) { + T[i].join(); + } + + HIP_CHECK(hipStreamSynchronize(mystream)); + HIP_CHECK(hipStreamDestroy(mystream)); + + // Verifying the result of the kernel computation + for (size_t i = 0; i < N_ELMTS; i++) { + if (C_h[i] != A_h[i] * A_h[i]) { + Data_mismatch++; + } + } + REQUIRE(Thread_count.load() == NUM_THREADS); + REQUIRE(Data_mismatch == 0); + HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false); + Thread_count.exchange(0); +} + +TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_hipMultiMemcpyMultiThreadMultiStream", + "", int, float, double) { + std::thread T[NUM_THREADS]; + for (int i = 0; i < NUM_THREADS; i++) { + T[i] = std::thread(Thread_func_MultiStream); + } + + // Wait until all the threads finish their execution + for (int i = 0; i < NUM_THREADS; i++) { + T[i].join(); + } + + REQUIRE(Thread_count.load() == NUM_THREADS); + Thread_count.exchange(0); +} + +/* +This testcase verifies hipMemcpy API with pinnedMemory and hostRegister +along with kernel launches +*/ + +TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_PinnedRegMemWithKernelLaunch", + "", int, float, double) { + int numDevices = 0; + HIP_CHECK(hipGetDeviceCount(&numDevices)); + if (numDevices < 2) { + SUCCEED("No of devices are less than 2"); + } else { + // 1 refers to pinned Memory + // 2 refers to register Memory + int MallocPinType = GENERATE(0, 1); + size_t Nbytes = NUM_ELM * sizeof(TestType); + unsigned blocks = HipTest::setNumBlocks(blocksPerCU, + threadsPerBlock, NUM_ELM); + + TestType *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr}; + TestType *X_d{nullptr}, *Y_d{nullptr}, *Z_d{nullptr}; + TestType *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr}; + if (MallocPinType) { + HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, NUM_ELM, true); + } else { + A_h = reinterpret_cast(malloc(Nbytes)); + HIP_CHECK(hipHostRegister(A_h, Nbytes, hipHostRegisterDefault)); + B_h = reinterpret_cast(malloc(Nbytes)); + HIP_CHECK(hipHostRegister(B_h, Nbytes, hipHostRegisterDefault)); + C_h = reinterpret_cast(malloc(Nbytes)); + HIP_CHECK(hipHostRegister(C_h, Nbytes, hipHostRegisterDefault)); + HipTest::initArrays(&A_d, &B_d, &C_d, nullptr, nullptr, + nullptr, NUM_ELM, false); + HipTest::setDefaultData(NUM_ELM, A_h, B_h, C_h); + } + HIP_CHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice)); + + hipLaunchKernelGGL(HipTest::vectorADD, dim3(blocks), dim3(threadsPerBlock), + 0, 0, static_cast(A_d), + static_cast(B_d), C_d, NUM_ELM); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + HipTest::checkVectorADD(A_h, B_h, C_h, NUM_ELM); + + unsigned int seed = time(0); + HIP_CHECK(hipSetDevice(HipTest::RAND_R(&seed) % (numDevices-1)+1)); + + int device; + HIP_CHECK(hipGetDevice(&device)); + INFO("hipMemcpy is set to happen between device 0 and device " + << device); + HipTest::initArrays(&X_d, &Y_d, &Z_d, nullptr, + nullptr, nullptr, NUM_ELM, false); + + hipStream_t gpu1Stream; + HIP_CHECK(hipStreamCreate(&gpu1Stream)); + + for (int j = 0; j < NUM_ELM; j++) { + A_h[j] = 0; + B_h[j] = 0; + C_h[j] = 0; + } + + HIP_CHECK(hipMemcpy(A_h, A_d, Nbytes, hipMemcpyDeviceToHost)); + HIP_CHECK(hipMemcpyAsync(X_d, A_h, Nbytes, hipMemcpyHostToDevice, gpu1Stream)); + HIP_CHECK(hipMemcpy(B_h, B_d, Nbytes, hipMemcpyDeviceToHost)); + HIP_CHECK(hipMemcpyAsync(Y_d, B_h, Nbytes, hipMemcpyHostToDevice, gpu1Stream)); + + hipLaunchKernelGGL(HipTest::vectorADD, dim3(blocks), dim3(threadsPerBlock), + 0, 0, static_cast(X_d), + static_cast(Y_d), Z_d, NUM_ELM); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipMemcpyAsync(C_h, Z_d, Nbytes, + hipMemcpyDeviceToHost, gpu1Stream)); + HIP_CHECK(hipStreamSynchronize(gpu1Stream)); + + HipTest::checkVectorADD(A_h, B_h, C_h, NUM_ELM); + + if (MallocPinType) { + HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, true); + } else { + HIP_CHECK(hipHostUnregister(A_h)); + free(A_h); + HIP_CHECK(hipHostUnregister(B_h)); + free(B_h); + HIP_CHECK(hipHostUnregister(C_h)); + free(C_h); + HipTest::freeArrays(A_d, B_d, C_d, nullptr, + nullptr, nullptr, false); + } + HipTest::freeArrays(X_d, Y_d, Z_d, nullptr, + nullptr, nullptr, false); + HIP_CHECK(hipStreamDestroy(gpu1Stream)); + } +} + From 983aee310ea25d63bda763402a50c9cc26f0ff22 Mon Sep 17 00:00:00 2001 From: Marko Veniger <91256249+marko-veniger@users.noreply.github.com> Date: Tue, 11 Jul 2023 10:36:37 +0200 Subject: [PATCH 19/25] EXSWHTEC-19 - hipMallocAsync negative tests (#37) - negative tests for hipMallocAsync: - nullptr for device pointer parameter - invalid stream for stream parameter - size required larger than size of available memoryr - Extend the PREDEFINED list to define all macro names to include #if and #ifdef sections in documentation - Resolve unresolved merge conflicts [ROCm/hip-tests commit: 6d62387c3405344c787ca8e2457e04226cf167f0] --- .../catch/unit/memory/CMakeLists.txt | 1 + .../catch/unit/memory/hipMallocAsync.cc | 47 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 projects/hip-tests/catch/unit/memory/hipMallocAsync.cc diff --git a/projects/hip-tests/catch/unit/memory/CMakeLists.txt b/projects/hip-tests/catch/unit/memory/CMakeLists.txt index ff9eaa4f71..46d8bdf994 100644 --- a/projects/hip-tests/catch/unit/memory/CMakeLists.txt +++ b/projects/hip-tests/catch/unit/memory/CMakeLists.txt @@ -108,6 +108,7 @@ set(TEST_SRC hipMemAdvise_old.cc hipMemAdvise.cc hipMemRangeGetAttributes.cc + hipMallocAsync.cc hipStreamAttachMemAsync.cc hipMemRangeGetAttributes_old.cc hipMemGetAddressRange.cc) diff --git a/projects/hip-tests/catch/unit/memory/hipMallocAsync.cc b/projects/hip-tests/catch/unit/memory/hipMallocAsync.cc new file mode 100644 index 0000000000..db74c99459 --- /dev/null +++ b/projects/hip-tests/catch/unit/memory/hipMallocAsync.cc @@ -0,0 +1,47 @@ +/* + 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 WARRANNTY OF ANY KIND, EXPRESS OR + IMPLIED, INNCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANNY CLAIM, DAMAGES OR OTHER + 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. + */ + +#include +#include + +#include + +TEST_CASE("Unit_hipMallocAsync_negative") { + HIP_CHECK(hipSetDevice(0)); + + void* p = nullptr; + size_t max_size = std::numeric_limits::max(); + hipStream_t stream{nullptr}; + HIP_CHECK(hipStreamCreate(&stream)); + + + SECTION("Device pointer is null") { REQUIRE(hipMallocAsync(nullptr, 100, stream) != hipSuccess); } + + SECTION("stream is invalid") { + REQUIRE(hipMallocAsync(static_cast(&p), 100, reinterpret_cast(-1)) != + hipSuccess); + } + + SECTION("out of memory") { + REQUIRE(hipMallocAsync(static_cast(&p), max_size, stream) != hipSuccess); + } + + HIP_CHECK(hipStreamSynchronize(stream)); + HIP_CHECK(hipStreamDestroy(stream)); +} From 047d0370cd49fbfaa1015bd95be9e5a5494a64f2 Mon Sep 17 00:00:00 2001 From: Marko Veniger <91256249+marko-veniger@users.noreply.github.com> Date: Tue, 11 Jul 2023 10:38:00 +0200 Subject: [PATCH 20/25] EXSWHTEC-20 - hipFreeAsync negative tests (#38) - Added negative tests for hipFreeAsync - nullptr check for pointer parameter - invalid stream handle for stream parameter - Update config_nvidia_linux_common.json [ROCm/hip-tests commit: bf50c2d2d86b6e84ea09a6f521617d69056483ef] --- .../config/config_nvidia_linux_common.json | 24 +++++----- .../catch/unit/memory/CMakeLists.txt | 1 + .../catch/unit/memory/hipFreeAsync.cc | 44 +++++++++++++++++++ 3 files changed, 58 insertions(+), 11 deletions(-) create mode 100644 projects/hip-tests/catch/unit/memory/hipFreeAsync.cc diff --git a/projects/hip-tests/catch/hipTestMain/config/config_nvidia_linux_common.json b/projects/hip-tests/catch/hipTestMain/config/config_nvidia_linux_common.json index 84df4337fb..baa25636a0 100644 --- a/projects/hip-tests/catch/hipTestMain/config/config_nvidia_linux_common.json +++ b/projects/hip-tests/catch/hipTestMain/config/config_nvidia_linux_common.json @@ -8,16 +8,18 @@ "=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/85 ===", "Unit_hipFuncSetAttribute_Negative_Parameters", "=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/215 ===", - "Unit_ChannelDescriptor_Positive_Basic_1D - long", - "Unit_ChannelDescriptor_Positive_Basic_1D - unsigned long", - "Unit_ChannelDescriptor_Positive_Basic_1D - ulong1", - "Unit_ChannelDescriptor_Positive_Basic_1D - signed long", - "Unit_ChannelDescriptor_Positive_Basic_1D - long1", - "Unit_ChannelDescriptor_Positive_Basic_2D - ulong2", - "Unit_ChannelDescriptor_Positive_Basic_2D - long2", - "Unit_ChannelDescriptor_Positive_Basic_3D - ulong3", - "Unit_ChannelDescriptor_Positive_Basic_3D - long3", - "Unit_ChannelDescriptor_Positive_Basic_4D - ulong4", - "Unit_ChannelDescriptor_Positive_Basic_4D - long4" + "Unit_ChannelDescriptor_Positive_Basic_1D - long", + "Unit_ChannelDescriptor_Positive_Basic_1D - unsigned long", + "Unit_ChannelDescriptor_Positive_Basic_1D - ulong1", + "Unit_ChannelDescriptor_Positive_Basic_1D - signed long", + "Unit_ChannelDescriptor_Positive_Basic_1D - long1", + "Unit_ChannelDescriptor_Positive_Basic_2D - ulong2", + "Unit_ChannelDescriptor_Positive_Basic_2D - long2", + "Unit_ChannelDescriptor_Positive_Basic_3D - ulong3", + "Unit_ChannelDescriptor_Positive_Basic_3D - long3", + "Unit_ChannelDescriptor_Positive_Basic_4D - ulong4", + "Unit_ChannelDescriptor_Positive_Basic_4D - long4", + "=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/38 ===", + "Unit_hipFreeAsync_negative" ] } diff --git a/projects/hip-tests/catch/unit/memory/CMakeLists.txt b/projects/hip-tests/catch/unit/memory/CMakeLists.txt index 46d8bdf994..1608574891 100644 --- a/projects/hip-tests/catch/unit/memory/CMakeLists.txt +++ b/projects/hip-tests/catch/unit/memory/CMakeLists.txt @@ -108,6 +108,7 @@ set(TEST_SRC hipMemAdvise_old.cc hipMemAdvise.cc hipMemRangeGetAttributes.cc + hipFreeAsync.cc hipMallocAsync.cc hipStreamAttachMemAsync.cc hipMemRangeGetAttributes_old.cc diff --git a/projects/hip-tests/catch/unit/memory/hipFreeAsync.cc b/projects/hip-tests/catch/unit/memory/hipFreeAsync.cc new file mode 100644 index 0000000000..6962189655 --- /dev/null +++ b/projects/hip-tests/catch/unit/memory/hipFreeAsync.cc @@ -0,0 +1,44 @@ +/* +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 + +TEST_CASE("Unit_hipFreeAsync_negative") { + HIP_CHECK(hipSetDevice(0)); + void* p = nullptr; + hipStream_t stream{nullptr}; + hipStreamCreate(&stream); + + SECTION("dev_ptr is nullptr") { REQUIRE(hipFreeAsync(nullptr, stream) != hipSuccess); } + + SECTION("invalid stream handle") { + HIP_CHECK(hipMallocAsync(static_cast(&p), 100, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + hipError_t error = hipFreeAsync(p, reinterpret_cast(-1)); + HIP_CHECK(hipFreeAsync(p, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + REQUIRE(error != hipSuccess); + } + + HIP_CHECK(hipStreamSynchronize(stream)); + HIP_CHECK(hipStreamDestroy(stream)); +} From 4314b86c1605aa952b141f4bd093ff6f8a2c4c4f Mon Sep 17 00:00:00 2001 From: milos-mozetic <118800401+milos-mozetic@users.noreply.github.com> Date: Tue, 11 Jul 2023 10:40:40 +0200 Subject: [PATCH 21/25] EXSWHTEC-223 - Update Coverage tool (#339) - Apply clang-format on Coverage tool and add blue color for deprecated Modules - Change color from blue to gray for deprecated modules - Adjust the color of green [ROCm/hip-tests commit: 0c7fa43b5e0490dca9609da48558f59463a4f1f8] --- projects/hip-tests/utils/coverage/Makefile | 10 +- .../coverageReportHTML/resources/coverage.css | 12 + .../utils/coverage/device_api_list.txt | 733 ++++++++++++++++++ projects/hip-tests/utils/coverage/hipAPI.cpp | 131 ++-- projects/hip-tests/utils/coverage/hipAPI.h | 13 +- .../utils/coverage/hipAPICoverageUtils.cpp | 192 ++++- .../utils/coverage/hipAPICoverageUtils.h | 8 +- .../hip-tests/utils/coverage/hipAPIGroup.cpp | 187 +++-- .../hip-tests/utils/coverage/hipAPIGroup.h | 5 +- .../hip-tests/utils/coverage/mainCoverage.cpp | 35 +- .../utils/coverage/reportGenerators.cpp | 261 +++++-- .../utils/coverage/reportGenerators.h | 9 +- 12 files changed, 1335 insertions(+), 261 deletions(-) create mode 100644 projects/hip-tests/utils/coverage/device_api_list.txt diff --git a/projects/hip-tests/utils/coverage/Makefile b/projects/hip-tests/utils/coverage/Makefile index ee590bb186..f81c71037d 100644 --- a/projects/hip-tests/utils/coverage/Makefile +++ b/projects/hip-tests/utils/coverage/Makefile @@ -30,9 +30,9 @@ all: ${SRC} ${CC} ${CPPFLAGS} $^ -o ${OBJ} clean: - rm ${OBJ} - rm *.xml - rm -r ./coverageReportHTML/testModules - rm -r ./coverageReportHTML/testAPIs - rm ./coverageReportHTML/*.html + rm -f ${OBJ} + rm -f *.xml + rm -fr ./coverageReportHTML/testModules + rm -fr ./coverageReportHTML/testAPIs + rm -f ./coverageReportHTML/*.html .PHONY : clean diff --git a/projects/hip-tests/utils/coverage/coverageReportHTML/resources/coverage.css b/projects/hip-tests/utils/coverage/coverageReportHTML/resources/coverage.css index 67a8a40b76..d92a870e3a 100644 --- a/projects/hip-tests/utils/coverage/coverageReportHTML/resources/coverage.css +++ b/projects/hip-tests/utils/coverage/coverageReportHTML/resources/coverage.css @@ -169,6 +169,18 @@ td.coverBarOutline background-color: #000000; } +/* Directory view/File view (all): line count entry for files with + deprecated functions */ +td.coverDeprecated +{ + text-align: center; + padding-left: 10px; + padding-right: 10px; + background-color: #d2d2d2; + white-space: nowrap; + font-family: sans-serif; +} + /* Directory view/File view (all): line count entry for files with high coverage rate */ td.coverNumHi diff --git a/projects/hip-tests/utils/coverage/device_api_list.txt b/projects/hip-tests/utils/coverage/device_api_list.txt new file mode 100644 index 0000000000..7588950886 --- /dev/null +++ b/projects/hip-tests/utils/coverage/device_api_list.txt @@ -0,0 +1,733 @@ +Atomics [ + atomicCAS + atomicCAS_system + atomicAdd + atomicAdd_system + unsafeAtomicAdd + safeAtomicAdd + atomicSub + atomicSub_system + atomicExch + atomicExch_system + atomicMin + atomicMin_system + unsafeAtomicMin + safeAtomicMin + atomicMax + atomicMax_system + unsafeAtomicMax + safeAtomicMax + atomicInc + atomicDec + atomicAnd + atomicAnd_system + atomicOr + atomicOr_system + atomicXor + atomicXor_system +] + +Builtin atomics [ + __hip_atomic_load + __hip_atomic_store + __hip_atomic_compare_exchange_weak + __hip_atomic_compare_exchange_strong + __hip_atomic_exchange + __hip_atomic_fetch_add + __hip_atomic_fetch_and + __hip_atomic_fetch_or + __hip_atomic_fetch_xor + __hip_atomic_fetch_min + __hip_atomic_fetch_max +] + +Cooperative groups [ + File restriction: cooperative_groups + Device groups: ( + coalesced_group_tile + coalesced_group + grid_group + multi_grid_group + thread_block_tile + thread_block + ) + size + thread_rank + group_index + thread_index + shfl + shfl_up + shfl_down + shfl_xor + sync +] + +Warp [ + File restriction: cooperative_groups + Device groups: ( + ballot + any + all + shfl_down + shfl_up + shfl + shfl_xor + ) + __ballot + __any + __all + __shfl_down + __shfl_up + __shfl + __shfl_xor +] + +Launch bounds [ + Device groups: ( + launch_bounds + ) + __launch_bounds__ +] + +Channel descriptor [ + hipCreateChannelDesc + hipCreateChannelDescHalf + hipCreateChannelDescHalf1 + hipCreateChannelDescHalf2 +] + +Device assert [ + assert + static_assert +] + +Device clock [ + Device groups: ( + clock + ) + clock + clock64 + wall_clock64 +] + +Device printf [ + printf +] + +HIP specific [ + Device groups: ( + hip_hc_8pk + ) + __hip_hc_add8pk + __hip_hc_sub8pk + __hip_hc_mul8pk +] + +Device synchronization [ + __syncthreads + __syncthreads_and + __syncthreads_count + __syncthreads_or +] + +Memory fence [ + __threadfence + __threadfence_block + __threadfence_system +] + +Device memory [ + memcpy + memset +] + +Device math [ + rsqrt + sqrt + cbrt + rcbrt + hypot + rhypot + norm3d + rnorm3d + norm4d + rnorm4d + norm + rnorm + rsqrtf + sqrtf + cbrtf + rcbrtf + hypotf + rhypotf + norm3df + rnorm3df + norm4df + rnorm4df + normf + rnormf + rsqrt + sqrt + cbrt + rcbrt + hypot + rhypot + norm3d + rnorm3d + norm4d + rnorm4d + norm + rnorm + expf + exp2f + exp10f + expm1f + frexpf + ldexpf + powf + powif + scalbnf + scalblnf + log + log2 + log10 + log1p + logb + ilogb + logf + log2f + log10f + log1pf + logbf + ilogbf + sin + cos + tan + sincos + sinpi + cospi + sincospi + asin + acos + atan + atan2 + sinh + cosh + tanh + asinh + acosh + atanh + sinf + cosf + tanf + sincosf + sinpif + cospif + sincospif + asinf + acosf + atanf + atan2f + sinhf + coshf + tanhf + asinhf + acoshf + atanhf + erf + erfc + erfinv + erfcinv + erfcx + normcdf + normcdfinv + lgamma + tgamma + j0 + j1 + jn + y0 + y1 + yn + cyl_bessel_i0 + cyl_bessel_i1 + erff + erfcf + erfinvf + erfcinvf + erfcxf + normcdff + normcdfinvf + lgammaf + tgammaf + j0f + j1f + jnf + y0f + y1f + ynf + cyl_bessel_i0f + cyl_bessel_i1f + fmod + remainder + remquo + modf + fdim + trunc + round + rint + nearbyint + ceil + floor + lrint + lround + llrint + llround + fmodf + remainderf + remquof + modff + fdimf + truncf + roundf + rintf + nearbyintf + ceilf + floorf + lrintf + lroundf + llrintf + llroundf + fma + abs + fabs + copysign + fmax + fmin + nan + nextafter + signbit + fmaf + abs + fabsf + copysignf + fdividef + fmaxf + fminf + isfinite + isinf + isnan + nanf + nextafterf + signbit + __brev + __brevll + __clz + __clzll + __ffs + __ffsll + __popc + __popcll + __mul24 + __umul24 + __dadd_rn + __dsub_rn + __dmul_rn + __fma_rn + __drcp_rn + __dsqrt_rn + __ddiv_rn + __fadd_rn + __fsub_rn + __fmul_rn + __fmaf_rn + __frcp_rn + __fsqrt_rn + __frsqrt_rn + __fdiv_rn + __fdividef + __expf + __exp10f + __logf + __log2f + __log10f + __sinf + __cosf + __sincosf + __tanf + __powf +] + +Device conversion functions [ + __double2float_rd + __double2float_rn + __double2float_ru + __double2float_rz + __double2hiint + __double2loint + __double2int_rd + __double2int_rn + __double2int_ru + __double2int_rz + __double2ll_rd + __double2ll_rn + __double2ll_ru + __double2ll_rz + __double2uint_rd + __double2uint_rn + __double2uint_ru + __double2uint_rz + __double2ull_rd + __double2ull_rn + __double2ull_ru + __double2ull_rz + __double_as_longlong + __float2int_rd + __float2int_rn + __float2int_ru + __float2int_rz + __float2ll_rd + __float2ll_rn + __float2ll_ru + __float2ll_rz + __float2uint_rd + __float2uint_rn + __float2uint_ru + __float2uint_rz + __float2ull_rd + __float2ull_rn + __float2ull_ru + __float2ull_rz + __float_as_int + __float_as_uint + __hiloint2double + __int2double_rn + __int2float_rd + __int2float_rn + __int2float_ru + __int2float_rz + __int_as_float + __ll2double_rd + __ll2double_rn + __ll2double_ru + __ll2double_rz + __ll2float_rd + __ll2float_rn + __ll2float_ru + __ll2float_rz + __longlong_as_double + __uint2double_rn + __uint2float_rd + __uint2float_rn + __uint2float_ru + __uint2float_rz + __uint_as_float + __ull2double_rd + __ull2double_rn + __ull2double_ru + __ull2double_rz + __ull2float_rd + __ull2float_rn + __ull2float_ru + __ull2float_rz +] + +Device complex type functions [ + hipCrealf + hipCimagf + make_hipFloatComplex + hipConjf + hipCsqabsf + hipCaddf + hipCsubf + hipCmulf + hipCdivf + hipCabsf + hipCreal + hipCimag + make_hipDoubleComplex + hipConj + hipCsqabs + hipCadd + hipCsub + hipCmul + hipCdiv + hipCabs + make_hipComplex + hipComplexDoubleToFloat + hipComplexFloatToDouble + hipCfmaf + hipCfma +] + +Device vector types [ + make_uchar1 + make_uchar2 + make_uchar3 + make_uchar4 + make_char1 + make_char2 + make_char3 + make_char4 + make_ushort1 + make_ushort2 + make_ushort3 + make_ushort4 + make_short1 + make_short2 + make_short3 + make_short4 + make_uint1 + make_uint2 + make_uint3 + make_uint4 + make_int1 + make_int2 + make_int3 + make_int4 + make_float1 + make_float2 + make_float3 + make_float4 + make_double1 + make_double2 + make_double3 + make_double4 + make_ulong1 + make_ulong2 + make_ulong3 + make_ulong4 + make_long1 + make_long2 + make_long3 + make_long4 + make_ulonglong1 + make_ulonglong2 + make_ulonglong3 + make_ulonglong4 + make_longlong1 + make_longlong2 + make_longlong3 + make_longlong4 +] + +Device surface functions [ + __hipGetPixelAddr + __hipMapToNativeFloat4 + __hipMapFromNativeFloat4 + surf1Dread + surf1Dwrite + surf2Dread + surf2Dwrite + surf3Dread + surf3Dwrite + surf1DLayeredread + surf1DLayeredwrite + surf2DLayeredread + surf2DLayeredwrite + surfCubemapread + surfCubemapwrite + surfCubemapLayeredread + surfCubemapLayeredwrite +] + +Device texture functions [ + tex1Dfetch + tex1D + tex2D + tex1DLayered + tex2DLayered + tex3D + texCubemap + tex1DLod + tex2DLod + tex1DLayeredLod + tex2DLayeredLod + tex3DLod + texCubemapLod + texCubemapLayered + texCubemapLayeredLod + texCubemapGrad + texCubemapLayeredGrad + tex1DGrad + tex2DGrad + tex1DLayeredGrad + tex2DLayeredGrad + tex3DGrad + tex2Dgather +] + +Device float16 functions [ + make_half2 + __low2half + __high2half + __half2half2 + __halves2half2 + __low2half2 + __high2half2 + __lows2half2 + __highs2half2 + __lowhigh2highlow + __half_as_short + __half_as_ushort + __short_as_half + __ushort_as_half + __float2half + __float2half_rn + __float2half_rz + __float2half_rd + __float2half_ru + __float2half2_rn + __floats2half2_rn + __float22half2_rn + __half2float + __low2float + __high2float + __half22float2 + __half2int_rn + __half2int_rz + __half2int_rd + __half2int_ru + __int2half_rn + __int2half_rz + __int2half_rd + __int2half_ru + __half2short_rn + __half2short_rz + __half2short_rd + __half2short_ru + __short2half_rn + __short2half_rz + __short2half_rd + __short2half_ru + __half2ll_rn + __half2ll_rz + __half2ll_rd + __half2ll_ru + __ll2half_rn + __ll2half_rz + __ll2half_rd + __ll2half_ru + __half2uint_rn + __half2uint_rz + __half2uint_rd + __half2uint_ru + __uint2half_rn + __uint2half_rz + __uint2half_rd + __uint2half_ru + __half2ushort_rn + __half2ushort_rz + __half2ushort_rd + __half2ushort_ru + __ushort2half_rn + __ushort2half_rz + __ushort2half_rd + __ushort2half_ru + __half2ull_rn + __half2ull_rz + __half2ull_rd + __half2ull_ru + __ull2half_rn + __ull2half_rz + __ull2half_rd + __ull2half_ru + __ldg + __ldcg + __ldca + __ldcs + __heq + __hne + __hle + __hge + __hlt + __hgt + __hequ + __hneu + __hleu + __hgeu + __hltu + __hgtu + __heq2 + __hne2 + __hle2 + __hge2 + __hlt2 + __hgt2 + __hequ2 + __hneu2 + __hleu2 + __hgeu2 + __hltu2 + __hgtu2 + __hbeq2 + __hbne2 + __hble2 + __hbge2 + __hblt2 + __hbgt2 + __hbequ2 + __hbneu2 + __hbleu2 + __hbgeu2 + __hbltu2 + __hbgtu2 + __clamp_01 + __hadd + __habs + __hsub + __hmul + __hadd_sat + __hsub_sat + __hmul_sat + __hfma + __hfma_sat + __hdiv + __hadd2 + __habs2 + __hsub2 + __hmul2 + __hadd2_sat + __hsub2_sat + __hmul2_sat + __hfma2 + __hfma2_sat + __h2div + amd_mixed_dot + htrunc + hceil + hfloor + hrint + hsin + hcos + hexp + hexp2 + hexp10 + hlog2 + hlog + hlog10 + hrcp + hrsqrt + hsqrt + __hisinf + __hisnan + __hneg + h2trunc + h2ceil + h2floor + h2rint + h2sin + h2cos + h2exp + h2exp2 + h2exp10 + h2log2 + h2log + h2log10 + h2rcp + h2rsqrt + h2sqrt + __hisinf2 + __hisnan2 + __hneg2 +] diff --git a/projects/hip-tests/utils/coverage/hipAPI.cpp b/projects/hip-tests/utils/coverage/hipAPI.cpp index 39ef99e4a2..5fa1c96798 100644 --- a/projects/hip-tests/utils/coverage/hipAPI.cpp +++ b/projects/hip-tests/utils/coverage/hipAPI.cpp @@ -22,11 +22,20 @@ THE SOFTWARE. #include "hipAPI.h" -FileOccurrence::FileOccurrence(std::string file_name, int line_number): - file_name{file_name}, line_number{line_number} {} +FileOccurrence::FileOccurrence(std::string file_name, int line_number) + : file_name{file_name}, line_number{line_number} {} -TestCaseOccurrence::TestCaseOccurrence(std::string test_case_name, std::string file_name, int line_number): - FileOccurrence{file_name, line_number}, test_case_name{test_case_name} {} +TestCaseOccurrence::TestCaseOccurrence(std::string test_case_name, std::string file_name, + int line_number) + : FileOccurrence{file_name, line_number}, test_case_name{test_case_name} {} + +bool operator==(const TestCaseOccurrence& l_test, const TestCaseOccurrence& r_test) { + return l_test.test_case_name == r_test.test_case_name; +} + +bool operator<(const TestCaseOccurrence& l_test, const TestCaseOccurrence& r_test) { + return l_test.test_case_name < r_test.test_case_name; +} bool operator==(const HipAPI& l_hip_api, const HipAPI& r_hip_api) { return l_hip_api.api_name == r_hip_api.api_name; @@ -36,54 +45,53 @@ bool operator<(const HipAPI& l_hip_api, const HipAPI& r_hip_api) { return l_hip_api.api_name < r_hip_api.api_name; } -HipAPI::HipAPI(std::string api_name, bool deprecated_flag, std::string api_group_name): - api_name{api_name}, deprecated{deprecated_flag}, api_group_name{api_group_name} {} - -std::string HipAPI::getName() const { - return api_name; +HipAPI::HipAPI(std::string api_name, bool deprecated_flag, std::string api_group_name, + std::string file_restriction) + : api_name{api_name}, + deprecated{deprecated_flag}, + api_group_name{api_group_name}, + file_restriction{file_restriction} { + test_cases.clear(); } -std::string HipAPI::getGroupName() const { - return api_group_name; -} +std::string HipAPI::getName() const { return api_name; } -int HipAPI::getNumberOfCalls() const { - return file_occurrences.size(); -} +std::string HipAPI::getGroupName() const { return api_group_name; } -int HipAPI::getNumberOfTestCases() const { - return test_cases.size(); -} +int HipAPI::getNumberOfCalls() const { return file_occurrences.size(); } + +std::vector HipAPI::getTestCases() const { return test_cases; } void HipAPI::addFileOccurrence(FileOccurrence file_occurrence) { file_occurrences.push_back(file_occurrence); } void HipAPI::addTestCase(TestCaseOccurrence test_case) { - test_cases.push_back(test_case); + if (std::find(test_cases.begin(), test_cases.end(), test_case) == test_cases.end()) { + test_cases.push_back(test_case); + } } -bool HipAPI::isDeprecated() const -{ - return deprecated; -} +bool HipAPI::isDeprecated() const { return deprecated; } -std::string HipAPI::getBasicStatsXML() const -{ +std::string HipAPI::getBasicStatsXML() const { std::stringstream xml_node; xml_node << "\t\t\n"; if (!deprecated) { xml_node << "\t\t\t" << api_name << "\n"; } else { - xml_node << "\t\t\t" << "[DEPRECATED] " << api_name << "\n"; + xml_node << "\t\t\t" + << "[DEPRECATED] " << api_name << "\n"; } if (!file_occurrences.empty()) { - xml_node << "\t\t\t" << file_occurrences.size() << "\n"; + xml_node << "\t\t\t" << file_occurrences.size() + << "\n"; xml_node << "\t\t\t\n"; - for (auto const& file_occurrence: file_occurrences) { - xml_node << "\t\t\t\t" << file_occurrence.file_name << ":" << file_occurrence.line_number << "\n"; + for (auto const& file_occurrence : file_occurrences) { + xml_node << "\t\t\t\t" << file_occurrence.file_name << ":" + << file_occurrence.line_number << "\n"; } xml_node << "\t\t\t\n"; } @@ -102,13 +110,20 @@ std::string HipAPI::createHTMLReport() const { std::string six_tabs{"\n\t\t\t\t\t\t"}; html_report << ""; - html_report << "" << one_tab << ""; - html_report << one_tab << "" << api_name << " Coverage report" << one_tab << "" << one_tab<< ""; - html_report << one_tab << "" << one_tab << ""; + html_report << "" << one_tab + << ""; + html_report << one_tab << "" << api_name << " Coverage report" << one_tab + << "" + << one_tab << ""; + html_report << one_tab << "" << one_tab + << "
"; html_report << two_tabs << ""; - html_report << two_tabs << "\n"; - html_report << two_tabs << "" << three_tabs << ""; html_report << two_tabs << ""; - for (auto const& test_case: test_cases) { + for (auto const& test_case : test_cases) { html_report << two_tabs << ""; - html_report << three_tabs << ""; + html_report << three_tabs << ""; html_report << three_tabs << ""; - html_report << three_tabs << ""; + html_report << three_tabs << ""; html_report << two_tabs << ""; } } else { html_report << two_tabs << ""; - html_report << three_tabs << ""; + html_report << three_tabs + << ""; html_report << two_tabs << ""; } html_report << one_tab << "
" << api_name << " Coverage report
" << four_tabs << "\n"; + html_report << two_tabs << "" << three_tabs << ""; html_report << two_tabs << ""; - html_report << two_tabs << "\n"; + html_report << two_tabs + << "\n"; html_report << one_tab << "
" << four_tabs + << ""; html_report << six_tabs << ""; @@ -124,7 +139,8 @@ std::string HipAPI::createHTMLReport() const { html_report << five_tabs << ""; html_report << six_tabs << ""; - html_report << six_tabs << ""; + html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; @@ -135,13 +151,16 @@ std::string HipAPI::createHTMLReport() const { html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; - - html_report << five_tabs << ""; + + html_report << five_tabs + << ""; html_report << four_tabs << "
"; html_report << six_tabs << "
Calls within test source files:" << file_occurrences.size() << "" << file_occurrences.size() + << "
"; html_report << three_tabs << "
"; html_report << one_tab << "
"; @@ -160,23 +179,29 @@ std::string HipAPI::createHTMLReport() const { html_report << three_tabs << "
Line number
" << test_case.test_case_name << "" << test_case.test_case_name + << "" << test_case.file_name << "" << test_case.line_number << "" << test_case.line_number + << "

There are no test cases detected within doxygen comments.

There are no test " + "cases detected within doxygen comments.
"; html_report << one_tab << "
"; html_report << one_tab << ""; - html_report << two_tabs << ""; + html_report + << two_tabs + << ""; html_report << one_tab << "
"; // Add info about API occurrences in the test files. @@ -192,15 +217,19 @@ std::string HipAPI::createHTMLReport() const { html_report << three_tabs << "Line number"; html_report << two_tabs << ""; - for (auto const& file_occurrence: file_occurrences) { + for (auto const& file_occurrence : file_occurrences) { html_report << two_tabs << ""; - html_report << three_tabs << "" << file_occurrence.file_name << ""; - html_report << three_tabs << "" << file_occurrence.line_number << ""; + html_report << three_tabs << "" << file_occurrence.file_name + << ""; + html_report << three_tabs << "" + << file_occurrence.line_number << ""; html_report << two_tabs << ""; } } else { html_report << two_tabs << ""; - html_report << three_tabs << "
There are no occurrences within test source files."; + html_report << three_tabs + << "
There are no " + "occurrences within test source files."; html_report << two_tabs << ""; } html_report << one_tab << ""; @@ -208,7 +237,9 @@ std::string HipAPI::createHTMLReport() const { html_report << one_tab << "
"; html_report << one_tab << ""; - html_report << two_tabs << ""; + html_report + << two_tabs + << ""; time_t now{time(nullptr)}; std::string date{asctime(gmtime(&now))}; @@ -220,3 +251,5 @@ std::string HipAPI::createHTMLReport() const { return html_report.str(); } + +std::string HipAPI::getFileRestriction() const { return file_restriction; } diff --git a/projects/hip-tests/utils/coverage/hipAPI.h b/projects/hip-tests/utils/coverage/hipAPI.h index b14d3b7c6e..ffedf0ae44 100644 --- a/projects/hip-tests/utils/coverage/hipAPI.h +++ b/projects/hip-tests/utils/coverage/hipAPI.h @@ -23,6 +23,7 @@ THE SOFTWARE. #include #include #include +#include /* Helper class used to store information in what file has HIP API been detected, @@ -40,6 +41,9 @@ Helper class used to store information in what file has the API Test Case been d and on what line of code in that file. */ class TestCaseOccurrence : public FileOccurrence { + friend bool operator==(const TestCaseOccurrence& l_test, const TestCaseOccurrence& r_test); + friend bool operator<(const TestCaseOccurrence& l_test, const TestCaseOccurrence& r_test); + public: std::string test_case_name; TestCaseOccurrence(std::string test_case_name, std::string file_name, int line_number); @@ -55,18 +59,23 @@ class HipAPI { friend bool operator<(const HipAPI& l_hip_api, const HipAPI& r_hip_api); public: - HipAPI(std::string api_name, bool deprecated_flag, std::string api_group_name); + HipAPI(std::string api_name, bool deprecated_flag, std::string api_group_name, + std::string file_restriction = ""); std::string getName() const; std::string getGroupName() const; int getNumberOfCalls() const; - int getNumberOfTestCases() const; + std::vector getTestCases() const; void addFileOccurrence(FileOccurrence file_occurence); void addTestCase(TestCaseOccurrence test_case); bool isDeprecated() const; std::string getBasicStatsXML() const; std::string createHTMLReport() const; + std::string getFileRestriction() const; + std::vector device_groups; + private: std::string api_name; + std::string file_restriction; int number_of_calls; bool deprecated; std::string api_group_name; diff --git a/projects/hip-tests/utils/coverage/hipAPICoverageUtils.cpp b/projects/hip-tests/utils/coverage/hipAPICoverageUtils.cpp index 022815768c..aaf19dd906 100644 --- a/projects/hip-tests/utils/coverage/hipAPICoverageUtils.cpp +++ b/projects/hip-tests/utils/coverage/hipAPICoverageUtils.cpp @@ -42,13 +42,34 @@ void findAPICallInFile(HipAPI& hip_api, std::string test_module_file) { std::string api_call_with_assert{"(" + hip_api.getName() + "("}; std::string api_call_with_assignment{"= " + hip_api.getName() + "("}; std::string api_call_with_parameter{", " + hip_api.getName() + "("}; + std::string api_call_with_return{"return " + hip_api.getName() + "("}; + std::string api_call_in_line("{ " + hip_api.getName() + "("); + std::string api_member{"." + hip_api.getName() + "("}; + std::string api_newline{" " + hip_api.getName() + "("}; + std::string api_templated{" " + hip_api.getName() + "<"}; + + std::string api_restriction{hip_api.getFileRestriction()}; + bool found_restriction{false}; while (std::getline(test_module_file_handler, line)) { ++line_number; + + if (api_restriction != "" && line.find(api_restriction) != std::string::npos) { + found_restriction = true; + } + if ((line.find(api_call_with_assert) != std::string::npos) || (line.find(api_call_with_assignment) != std::string::npos) || - (line.find(api_call_with_parameter) != std::string::npos)) { - hip_api.addFileOccurrence(FileOccurrence(test_module_file, line_number)); + (line.find(api_call_with_parameter) != std::string::npos) || + (line.find(api_call_with_return) != std::string::npos) || + (line.find(api_call_in_line) != std::string::npos) || + (line.find(api_member) != std::string::npos) || + (line.find(api_newline) != std::string::npos) || + (line.find(hip_api.getName() + "(") == 0) || + (line.find(api_templated) != std::string::npos)) { + if (api_restriction == "" || found_restriction) { + hip_api.addFileOccurrence(FileOccurrence(test_module_file, line_number)); + } } } @@ -59,7 +80,7 @@ void findAPICallInFile(HipAPI& hip_api, std::string test_module_file) { Used to find all HIP API test cases within the passed test .cc files. Matching test case is detected when the HIP API in defined within doxygen comment. */ -void findAPITestCaseInFile(HipAPI& hip_api, std::string test_module_file) { +void findAPITestCaseInFileByDoxygen(HipAPI& hip_api, std::string test_module_file) { std::fstream test_module_file_handler; test_module_file_handler.open(test_module_file); @@ -80,7 +101,10 @@ void findAPITestCaseInFile(HipAPI& hip_api, std::string test_module_file) { } if (hip_api.getName() != current_api_name) { - continue; + if (std::find(hip_api.device_groups.begin(), hip_api.device_groups.end(), current_api_name) == + hip_api.device_groups.end()) { + continue; + } } if (line.find(ref_test_case) != std::string::npos) { @@ -99,15 +123,45 @@ void findAPITestCaseInFile(HipAPI& hip_api, std::string test_module_file) { test_module_file_handler.close(); } +/* +Used to find all HIP API test cases within the passed test .cc files. +Matching test case is detected when the HIP API in defined within doxygen comment. +*/ +void findAPITestCaseInFileByAPIName(HipAPI& hip_api, std::string test_module_file) { + std::fstream test_module_file_handler; + test_module_file_handler.open(test_module_file); + + int line_number{0}; + std::string line; + + std::string test_case_definition{"TEST_CASE("}; + std::string test_case{"None"}; + + while (std::getline(test_module_file_handler, line)) { + ++line_number; + + if (line.find(test_case_definition) != std::string::npos) { + test_case = line.substr(line.find("\"") + 1); + test_case = test_case.substr(0, test_case.find("\"")); + if (test_case.find("_" + hip_api.getName() + "_") != std::string::npos) { + hip_api.addTestCase(TestCaseOccurrence{test_case, test_module_file, line_number}); + } + } + } + + test_module_file_handler.close(); +} + /* Used to iterate through all passed test .cc files and search for passed HIP API instance. This instance shall be used to update occurrences. */ void searchForAPI(HipAPI& hip_api, std::vector& test_module_files) { std::cout << "Searching for " << hip_api.getName() << " in test module files." << std::endl; - for (auto const& test_module_file: test_module_files) { + for (auto const& test_module_file : test_module_files) { findAPICallInFile(hip_api, test_module_file); - findAPITestCaseInFile(hip_api, test_module_file); + findAPITestCaseInFileByDoxygen(hip_api, test_module_file); + findAPITestCaseInFileByAPIName(hip_api, test_module_file); } } @@ -115,7 +169,7 @@ void searchForAPI(HipAPI& hip_api, std::vector& test_module_files) Used to extract all HIP APIs from the passed header file. */ std::vector extractHipAPIs(std::string& hip_api_header_file, - std::vector& api_group_names, bool start_groups) { + std::vector& api_group_names, bool start_groups) { std::fstream hip_header_file_handler; hip_header_file_handler.open(hip_api_header_file); @@ -148,8 +202,9 @@ std::vector extractHipAPIs(std::string& hip_api_header_file, ++line_number; // Declarations of the HIP APIs start after the HIP API group has been defined. - if ((line.find(group_definition) != std::string::npos || line.find(add_group_definition) != std::string::npos) - && line.find(start_of_api_groups) != std::string::npos) { + if ((line.find(group_definition) != std::string::npos || + line.find(add_group_definition) != std::string::npos) && + line.find(start_of_api_groups) != std::string::npos) { api_group_names_start = true; continue; } @@ -167,24 +222,21 @@ std::vector extractHipAPIs(std::string& hip_api_header_file, /* If the API is deprecated, raise a flag and go to the next line where the API is declared. - */ + */ if (line.find(deprecated_line) != std::string::npos) { - std::getline(hip_header_file_handler, line); - ++line_number; deprecated_flag = true; - } else { - deprecated_flag = false; + continue; } if (line.find(group_definition) != std::string::npos) { - std::string group_name = line.substr(line.find(group_definition) + group_definition.length() + 1); + std::string group_name = + line.substr(line.find(group_definition) + group_definition.length() + 1); group_name = group_name.substr(group_name.find(' ') + 1); api_group_names.push_back(group_name); api_group_names_tracker.push_back(group_name); - } - else if (line.find(add_group_definition) != std::string::npos) - { - std::string group_name = line.substr(line.find(add_group_definition) + add_group_definition.length() + 1); + } else if (line.find(add_group_definition) != std::string::npos) { + std::string group_name = + line.substr(line.find(add_group_definition) + add_group_definition.length() + 1); group_name = group_name.substr(group_name.find(' ') + 1); api_group_names.push_back(group_name); api_group_names_tracker.push_back(group_name); @@ -196,7 +248,9 @@ std::vector extractHipAPIs(std::string& hip_api_header_file, to track the last defined group, because of the nested cases. */ if (line.find(end_group_definition) != std::string::npos) { - api_group_names_tracker.pop_back(); + if (!api_group_names_tracker.empty()) { + api_group_names_tracker.pop_back(); + } } /* @@ -207,16 +261,14 @@ std::vector extractHipAPIs(std::string& hip_api_header_file, - Extract the name from that substring by finding the last "hip". Avoid comments. */ - if (line.find(hip_api_prefix) != std::string::npos && - line.find("(") != std::string::npos && - line.find(" ") != 0 && - line.find(" *") != 0) { + if (line.find(hip_api_prefix) != std::string::npos && line.find("(") != std::string::npos && + line.find(" ") != 0 && line.find(" *") != 0) { std::string api_name_no_brackets{line.substr(0, line.find("("))}; /* If there is no hip substring, then there is no valid API in that line. */ if (api_name_no_brackets.rfind(hip_api_prefix) == std::string::npos) { - continue; + continue; } /* @@ -233,13 +285,15 @@ std::vector extractHipAPIs(std::string& hip_api_header_file, If the API is not present in the global list of HIP APIs, add it. */ HipAPI hip_api{api_name, deprecated_flag, api_group_names_tracker.back()}; - if(std::find(hip_apis.begin(), hip_apis.end(), hip_api) == hip_apis.end()) - { - hip_apis.push_back(hip_api); + if (std::find(hip_apis.begin(), hip_apis.end(), hip_api) == hip_apis.end()) { + hip_apis.push_back(hip_api); } } else { std::cout << "[SKIP_FROM_COV] Group not detected for \"" << api_name << "\" in file \"" - << hip_api_header_file << "\", line " << line_number << std::endl; + << hip_api_header_file << "\", line " << line_number << std::endl; + } + if (deprecated_flag) { + deprecated_flag = false; } } } @@ -248,14 +302,83 @@ std::vector extractHipAPIs(std::string& hip_api_header_file, return hip_apis; } +/* +Used to extract all HIP APIs from the passed header file. +*/ +std::vector extractDeviceAPIs(std::string& apis_list_file, + std::vector& api_group_names) { + std::fstream apis_list_file_handler; + apis_list_file_handler.open(apis_list_file); + + std::string line; + std::vector device_apis; + + /* + Each HIP API has prefix hip in the name. Groups are marked with @defgroup, and the + main group that shall be considered is HIP API. Before that group is defined, lines + of code shall not be considered. + */ + int line_number{0}; + bool group_start{false}; + bool device_groups_start{false}; + std::string restriction{""}; + std::string file_restriction_definition{"File restriction: "}; + std::string device_groups_definition{"Device groups: ("}; + std::vector device_groups; + + while (std::getline(apis_list_file_handler, line)) { + ++line_number; + + if (line.find("[") != std::string::npos) { + std::string group_name = line.substr(0, line.rfind(" ")); + api_group_names.push_back(group_name); + group_start = true; + continue; + } + + if (line.find("]") != std::string::npos) { + group_start = false; + device_groups.clear(); + restriction = ""; + continue; + } + + if (line.find(file_restriction_definition) != std::string::npos) { + restriction = + line.substr(line.find(file_restriction_definition) + file_restriction_definition.size()); + continue; + } + + if (line.find(device_groups_definition) != std::string::npos) { + std::getline(apis_list_file_handler, line); + while (line.find(")") == std::string::npos) { + std::string group_name = line; + group_name.erase(std::remove(group_name.begin(), group_name.end(), ' '), group_name.end()); + device_groups.push_back(group_name); + std::getline(apis_list_file_handler, line); + } + std::getline(apis_list_file_handler, line); + } + + if (group_start) { + std::string api_name = line.substr(line.rfind(" ") + 1); + HipAPI hip_api{api_name, false, api_group_names.back(), restriction}; + hip_api.device_groups = device_groups; + device_apis.push_back(hip_api); + } + } + + apis_list_file_handler.close(); + return device_apis; +} + /* Used to extract test .cc files from the passed tests root directory. Goes through all subdirectories and searches for .cc and .hh files for HIP API invocations. Implements BFS algorithm to avoid recursion. */ -std::vector extractTestModuleFiles(std::string& tests_root_directory) -{ +std::vector extractTestModuleFiles(std::string& tests_root_directory) { std::vector directory_queue; directory_queue.push_back(tests_root_directory); std::vector test_module_files; @@ -263,11 +386,11 @@ std::vector extractTestModuleFiles(std::string& tests_root_director while (!directory_queue.empty()) { std::string processed_entry = directory_queue.back(); directory_queue.pop_back(); - for (const auto& entry: std::filesystem::directory_iterator(processed_entry)) { + for (const auto& entry : std::filesystem::directory_iterator(processed_entry)) { if (std::filesystem::is_directory(entry.path())) { directory_queue.push_back(entry.path()); } else { - if (entry.path().string().find(".cc") != std::string::npos || + if (entry.path().string().find(".cc") != std::string::npos || entry.path().string().find(".hh") != std::string::npos) { test_module_files.push_back(entry.path()); } @@ -278,7 +401,6 @@ std::vector extractTestModuleFiles(std::string& tests_root_director return test_module_files; } -std::string findAbsolutePathOfFile(std::string file_path) -{ +std::string findAbsolutePathOfFile(std::string file_path) { return std::filesystem::canonical(std::filesystem::absolute(file_path)); } diff --git a/projects/hip-tests/utils/coverage/hipAPICoverageUtils.h b/projects/hip-tests/utils/coverage/hipAPICoverageUtils.h index 68454fd863..a62c9485d7 100644 --- a/projects/hip-tests/utils/coverage/hipAPICoverageUtils.h +++ b/projects/hip-tests/utils/coverage/hipAPICoverageUtils.h @@ -25,8 +25,12 @@ THE SOFTWARE. #include "hipAPIGroup.h" void findAPICallInFile(HipAPI& hip_api, std::string test_module_file); -void findAPITestCaseInFile(HipAPI& hip_api, std::string test_module_file); +void findAPITestCaseInFileByDoxygen(HipAPI& hip_api, std::string test_module_file); +void findAPITestCaseInFileByAPIName(HipAPI& hip_api, std::string test_module_file); void searchForAPI(HipAPI& hip_api, std::vector& test_module_files); -std::vector extractHipAPIs(std::string& hip_api_header_file, std::vector& api_group_names, bool start_groups); +std::vector extractHipAPIs(std::string& hip_api_header_file, + std::vector& api_group_names, bool start_groups); +std::vector extractDeviceAPIs(std::string& apis_list_file, + std::vector& api_group_names); std::vector extractTestModuleFiles(std::string& tests_root_directory); std::string findAbsolutePathOfFile(std::string file_path); diff --git a/projects/hip-tests/utils/coverage/hipAPIGroup.cpp b/projects/hip-tests/utils/coverage/hipAPIGroup.cpp index b24e2f1baa..5ec5174874 100644 --- a/projects/hip-tests/utils/coverage/hipAPIGroup.cpp +++ b/projects/hip-tests/utils/coverage/hipAPIGroup.cpp @@ -26,11 +26,14 @@ bool operator==(const HipAPIGroup& l_hip_api_group, const HipAPIGroup& r_hip_api return l_hip_api_group.group_name == r_hip_api_group.group_name; } -HipAPIGroup::HipAPIGroup(std::string group_name, std::vector& hip_apis): - group_name{group_name}, number_of_api_calls{0}, percentage_of_called_apis{0.f}, - total_number_of_apis{0}, number_of_test_cases{0} -{ - for (auto const& hip_api: hip_apis) { +HipAPIGroup::HipAPIGroup(std::string group_name, std::vector& hip_apis) + : group_name{group_name}, + number_of_api_calls{0}, + percentage_of_called_apis{0.f}, + total_number_of_apis{0}, + number_of_test_cases{0} { + std::vector test_cases; + for (auto const& hip_api : hip_apis) { if (hip_api.getGroupName() != group_name) { continue; } @@ -46,47 +49,43 @@ HipAPIGroup::HipAPIGroup(std::string group_name, std::vector& hip_apis): } number_of_api_calls += hip_api.getNumberOfCalls(); - number_of_test_cases += hip_api.getNumberOfTestCases(); + + std::vector api_test_cases = hip_api.getTestCases(); + test_cases.insert(test_cases.end(), api_test_cases.begin(), api_test_cases.end()); } + std::sort(test_cases.begin(), test_cases.end()); + auto last = std::unique(test_cases.begin(), test_cases.end()); + test_cases.erase(last, test_cases.end()); + number_of_test_cases = test_cases.size(); + total_number_of_apis = called_apis.size() + not_called_apis.size() + deprecated_apis.size(); if (not_called_apis.empty()) { percentage_of_called_apis = 100.f; } else { - percentage_of_called_apis = 100.f * called_apis.size() / (total_number_of_apis - deprecated_apis.size()); + percentage_of_called_apis = + 100.f * called_apis.size() / (total_number_of_apis - deprecated_apis.size()); } } -std::string HipAPIGroup::getName() const { - return group_name; -} +std::string HipAPIGroup::getName() const { return group_name; } -int HipAPIGroup::getTotalNumberOfAPIs() const { - return total_number_of_apis; -} +int HipAPIGroup::getTotalNumberOfAPIs() const { return total_number_of_apis; } -int HipAPIGroup::getTotalNumberOfCalls() const { - return number_of_api_calls; -} +int HipAPIGroup::getTotalNumberOfCalls() const { return number_of_api_calls; } -int HipAPIGroup::getTotalNumberOfTestCases() const { - return number_of_test_cases; -} +int HipAPIGroup::getTotalNumberOfTestCases() const { return number_of_test_cases; } -int HipAPIGroup::getNumberOfCalledAPIs() const { - return called_apis.size(); -} +int HipAPIGroup::getNumberOfCalledAPIs() const { return called_apis.size(); } -int HipAPIGroup::getNumberOfNotCalledAPIs() const { - return not_called_apis.size(); -} +int HipAPIGroup::getNumberOfNotCalledAPIs() const { return not_called_apis.size(); } -int HipAPIGroup::getNumberOfDeprecatedAPIs() const { - return deprecated_apis.size(); -} +int HipAPIGroup::getNumberOfDeprecatedAPIs() const { return deprecated_apis.size(); } -float HipAPIGroup::getPercentageOfCalledAPIs() const { - return percentage_of_called_apis; +float HipAPIGroup::getPercentageOfCalledAPIs() const { return percentage_of_called_apis; } + +bool HipAPIGroup::isDeprecated() const { + return (deprecated_apis.size() == total_number_of_apis) ? true : false; } std::string HipAPIGroup::getBasicStatsXML() const { @@ -100,16 +99,18 @@ std::string HipAPIGroup::getBasicStatsXML() const { xml_node << "\n\t"; xml_node << "\n\t\t" << total_number_of_apis << ""; - xml_node << "\n\t\t" << number_of_api_calls << ""; + xml_node << "\n\t\t" << number_of_api_calls + << ""; xml_node << "\n\t\t" << called_apis.size() << ""; xml_node << "\n\t\t" << not_called_apis.size() << ""; xml_node << "\n\t\t" << deprecated_apis.size() << ""; - xml_node << "\n\t\t" << percentage_of_called_apis << "%"; + xml_node << "\n\t\t" << percentage_of_called_apis + << "%"; xml_node << "\n\t"; if (!called_apis.empty()) { xml_node << "\n\t\n"; - for (auto const& hip_api: called_apis) { + for (auto const& hip_api : called_apis) { xml_node << hip_api.getBasicStatsXML(); } xml_node << "\t"; @@ -117,7 +118,7 @@ std::string HipAPIGroup::getBasicStatsXML() const { if (!not_called_apis.empty()) { xml_node << "\n\t\n"; - for (auto const& hip_api: not_called_apis) { + for (auto const& hip_api : not_called_apis) { xml_node << hip_api.getBasicStatsXML(); } xml_node << "\t"; @@ -125,7 +126,7 @@ std::string HipAPIGroup::getBasicStatsXML() const { if (!deprecated_apis.empty()) { xml_node << "\n\t\n"; - for (auto const& hip_api: deprecated_apis) { + for (auto const& hip_api : deprecated_apis) { xml_node << hip_api.getBasicStatsXML(); } xml_node << "\t"; @@ -135,8 +136,7 @@ std::string HipAPIGroup::getBasicStatsXML() const { return xml_node.str(); } -std::string HipAPIGroup::getBasicStatsHTML() const -{ +std::string HipAPIGroup::getBasicStatsHTML() const { std::stringstream html_object; std::string two_tabs{"\n\t\t"}; std::string three_tabs{"\n\t\t\t"}; @@ -158,29 +158,42 @@ std::string HipAPIGroup::getBasicStatsHTML() const color_bar = "resources/emerald.png"; } + if (isDeprecated()) { + font_class = "coverDeprecated"; + } + html_object << two_tabs << ""; - html_object << three_tabs << ""; - html_object << three_tabs << ""; - html_object << three_tabs << ""; - html_object << three_tabs << ""; - html_object << three_tabs << ""; - html_object << three_tabs << ""; - html_object << three_tabs << ""; - html_object << three_tabs << ""; + html_object << three_tabs << ""; + html_object << three_tabs << ""; + html_object << three_tabs << ""; + html_object << three_tabs << ""; + html_object << three_tabs << ""; + html_object << three_tabs << ""; + html_object << three_tabs << ""; + html_object << three_tabs << ""; html_object << three_tabs << "
" << group_name << "" << total_number_of_apis << "" << number_of_api_calls << "" << number_of_test_cases << "" << called_apis.size() << "" << not_called_apis.size() << "" << deprecated_apis.size() << "" << std::fixed << std::setprecision(2) << percentage_of_called_apis << "%" << group_name << "" << total_number_of_apis + << "" << number_of_api_calls + << "" << number_of_test_cases + << "" << called_apis.size() + << "" << not_called_apis.size() + << "" << deprecated_apis.size() + << "" << std::fixed + << std::setprecision(2) << percentage_of_called_apis << "%"; html_object << four_tabs << ""; html_object << five_tabs << "
\"""; - html_object << "\""
"; + html_object << color_bar << "\" width=" << percentage_of_called_apis << " height=10 alt=\"" + << percentage_of_called_apis << "%\">"; + html_object << "\""
"; html_object << four_tabs << ""; html_object << three_tabs << ""; return html_object.str(); } -std::string HipAPIGroup::createHTMLReport() const -{ +std::string HipAPIGroup::createHTMLReport() const { std::stringstream html_report; std::string one_tab{"\n\t"}; std::string two_tabs{"\n\t\t"}; @@ -190,14 +203,22 @@ std::string HipAPIGroup::createHTMLReport() const std::string six_tabs{"\n\t\t\t\t\t\t"}; html_report << ""; - html_report << "" << one_tab << ""; + html_report << "" << one_tab + << ""; html_report << one_tab << "" << group_name << " Coverage report"; - html_report << one_tab << "" << one_tab<< ""; - html_report << one_tab << "" << one_tab << ""; - html_report << two_tabs << ""; - html_report << two_tabs << "\n"; - html_report << two_tabs << "" << three_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; - for (auto const& hip_api: called_apis) { + for (auto const& hip_api : called_apis) { html_report << five_tabs << ""; - html_report << six_tabs << ""; + html_report << six_tabs << ""; html_report << five_tabs << ""; } @@ -293,9 +328,10 @@ std::string HipAPIGroup::createHTMLReport() const html_report << five_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; - for (auto const& hip_api: not_called_apis) { + for (auto const& hip_api : not_called_apis) { html_report << five_tabs << ""; - html_report << six_tabs << ""; + html_report << six_tabs << ""; html_report << five_tabs << ""; } html_report << four_tabs << "
" << group_name << " Coverage report
" << four_tabs << "" + << one_tab << ""; + html_report << one_tab << "" << one_tab + << "
"; + html_report << two_tabs << ""; + html_report << two_tabs + << "\n"; + html_report << two_tabs << "" << three_tabs << ""; html_report << two_tabs << ""; - html_report << two_tabs << "\n"; + html_report << two_tabs + << "\n"; html_report << one_tab << "
" << group_name + << " Coverage report
" << four_tabs + << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; @@ -206,37 +227,44 @@ std::string HipAPIGroup::createHTMLReport() const html_report << five_tabs << ""; html_report << six_tabs << ""; - html_report << six_tabs << ""; + html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; html_report << five_tabs << ""; - html_report << six_tabs << ""; + html_report << six_tabs + << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; html_report << five_tabs << ""; html_report << six_tabs << ""; - html_report << six_tabs << ""; + html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; html_report << five_tabs << ""; - html_report << six_tabs << ""; + html_report << six_tabs + << ""; html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; html_report << five_tabs << ""; html_report << six_tabs << ""; - html_report << six_tabs << ""; + html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; html_report << five_tabs << ""; - html_report << six_tabs << ""; - html_report << six_tabs << ""; + html_report << six_tabs + << ""; + html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; @@ -251,17 +279,23 @@ std::string HipAPIGroup::createHTMLReport() const } html_report << five_tabs << ""; - html_report << six_tabs << ""; - html_report << six_tabs << ""; + html_report + << six_tabs + << ""; + html_report << six_tabs << ""; html_report << six_tabs << ""; html_report << five_tabs << ""; - html_report << five_tabs << ""; + html_report << five_tabs + << ""; html_report << four_tabs << "
Value
Total number of detected HIP APIs:" << total_number_of_apis << "" << total_number_of_apis + << "
HIP API calls within test source files:HIP API calls within test source files:" << number_of_api_calls << "
Total number of test cases:" << number_of_test_cases << "" << number_of_test_cases + << "
HIP APIs that are called at least once:HIP APIs that are called at least once:" << called_apis.size() << "
HIP APIs that are not called at all:" << not_called_apis.size() << "" << not_called_apis.size() + << "
HIP APIs that are marked as deprecated:" << deprecated_apis.size() << "HIP APIs that are marked as deprecated:" << deprecated_apis.size() + << "
Test coverage by implemented tests for the HIP APIs:" << std::fixed << std::setprecision(2) << percentage_of_called_apis << "%Test coverage by implemented tests for the HIP APIs:" << std::fixed + << std::setprecision(2) << percentage_of_called_apis << "%
"; html_report << three_tabs << "
"; // Add info about Test module APIs. @@ -279,9 +313,10 @@ std::string HipAPIGroup::createHTMLReport() const html_report << five_tabs << "
Called APIs
" << hip_api.getName() << "" << hip_api.getName() << "
Not called APIs
" << hip_api.getName() << "" << hip_api.getName() << "
"; @@ -306,9 +342,10 @@ std::string HipAPIGroup::createHTMLReport() const html_report << five_tabs << ""; html_report << six_tabs << "Deprecated APIs"; html_report << five_tabs << ""; - for (auto const& hip_api: deprecated_apis) { + for (auto const& hip_api : deprecated_apis) { html_report << five_tabs << ""; - html_report << six_tabs << "" << hip_api.getName() << ""; + html_report << six_tabs << "" << hip_api.getName() << ""; html_report << five_tabs << ""; } html_report << four_tabs << ""; @@ -321,7 +358,9 @@ std::string HipAPIGroup::createHTMLReport() const html_report << one_tab << "
"; html_report << one_tab << ""; - html_report << two_tabs << ""; + html_report + << two_tabs + << ""; time_t now{time(nullptr)}; std::string date{asctime(gmtime(&now))}; diff --git a/projects/hip-tests/utils/coverage/hipAPIGroup.h b/projects/hip-tests/utils/coverage/hipAPIGroup.h index c9b07b8656..7687f623ac 100644 --- a/projects/hip-tests/utils/coverage/hipAPIGroup.h +++ b/projects/hip-tests/utils/coverage/hipAPIGroup.h @@ -21,10 +21,9 @@ THE SOFTWARE. */ #include "hipAPI.h" -#include #include -class HipAPIGroup{ +class HipAPIGroup { friend bool operator==(const HipAPIGroup& l_hip_api_group, const HipAPIGroup& r_hip_api_group); public: @@ -40,6 +39,8 @@ class HipAPIGroup{ std::string getBasicStatsXML() const; std::string getBasicStatsHTML() const; std::string createHTMLReport() const; + bool isDeprecated() const; + private: std::string group_name; int total_number_of_apis; diff --git a/projects/hip-tests/utils/coverage/mainCoverage.cpp b/projects/hip-tests/utils/coverage/mainCoverage.cpp index 65de5890a8..cc35cab075 100644 --- a/projects/hip-tests/utils/coverage/mainCoverage.cpp +++ b/projects/hip-tests/utils/coverage/mainCoverage.cpp @@ -22,10 +22,11 @@ THE SOFTWARE. #include "reportGenerators.h" -int main(int argc, char** argv) -{ +int main(int argc, char** argv) { if (argc != 2) { - std::cout << "Please provide the path to the cloned HIP/include/ directory as an argument! Only one argument supported." << std::endl; + std::cout << "Please provide the path to the cloned HIP/include/ directory as an argument! " + "Only one argument supported." + << std::endl; std::cout << "\tExample: ./generateHipAPICoverage /workspace/user1/HIP/include/" << std::endl; return -1; } @@ -34,33 +35,44 @@ int main(int argc, char** argv) Relative paths to all needed files, as it is expected that the application is called from the HIP/tests/catch/coverage directory. */ - std::string hip_api_header_file{findAbsolutePathOfFile(hip_include_path + "/hip/hip_runtime_api.h")}; + std::string hip_api_header_file{ + findAbsolutePathOfFile(hip_include_path + "/hip/hip_runtime_api.h")}; std::string hip_rtc_header_file{findAbsolutePathOfFile(hip_include_path + "/hip/hiprtc.h")}; std::string tests_root_directory{findAbsolutePathOfFile("../../catch")}; + std::string device_api_file{"device_api_list.txt"}; std::vector api_group_names; // Extract all HIP API declarations from the HIP API header file. std::vector hip_apis{extractHipAPIs(hip_api_header_file, api_group_names, false)}; - std::cout << "Number of detected HIP APIs from " << hip_api_header_file << ": " << hip_apis.size() << std::endl; + std::cout << "Number of detected HIP APIs from " << hip_api_header_file << ": " << hip_apis.size() + << std::endl; std::vector hip_rtc_apis{extractHipAPIs(hip_rtc_header_file, api_group_names, true)}; - std::cout << "Number of detected HIP APIs from " << hip_rtc_header_file << ": " << hip_rtc_apis.size() << std::endl; + std::cout << "Number of detected HIP APIs from " << hip_rtc_header_file << ": " + << hip_rtc_apis.size() << std::endl; hip_apis.insert(hip_apis.end(), hip_rtc_apis.begin(), hip_rtc_apis.end()); + std::vector device_apis{extractDeviceAPIs(device_api_file, api_group_names)}; + std::cout << "Number of detected device APIs from " << device_api_file << ": " + << device_apis.size() << std::endl; + hip_apis.insert(hip_apis.end(), device_apis.begin(), device_apis.end()); + // Extract all test module .cc files that shall be used for API searching. - std::cout << "Searching for HIP API calls in source files within " << tests_root_directory << "." << std::endl; + std::cout << "Searching for HIP API calls in source files within " << tests_root_directory << "." + << std::endl; std::vector test_module_files{extractTestModuleFiles(tests_root_directory)}; // Search for each HIP API in the extracted test .cc files. - for(HipAPI& hip_api: hip_apis) { + for (HipAPI& hip_api : hip_apis) { searchForAPI(hip_api, test_module_files); } std::vector hip_api_groups; - for (auto const& api_group_name: api_group_names) { + for (auto const& api_group_name : api_group_names) { HipAPIGroup hip_api_group{api_group_name, hip_apis}; // Avoid having duplicated groups. - if (std::find(hip_api_groups.begin(), hip_api_groups.end(), hip_api_group) == hip_api_groups.end()) { + if (std::find(hip_api_groups.begin(), hip_api_groups.end(), hip_api_group) == + hip_api_groups.end()) { hip_api_groups.push_back(hip_api_group); } } @@ -68,7 +80,8 @@ int main(int argc, char** argv) std::cout << "Generating XML report files." << std::endl; generateXMLReportFiles(hip_apis, hip_api_groups); std::cout << "Generating HTML report files." << std::endl; - generateHTMLReportFiles(hip_apis, hip_api_groups, tests_root_directory, hip_api_header_file, hip_rtc_header_file); + generateHTMLReportFiles(hip_apis, hip_api_groups, tests_root_directory, hip_api_header_file, + hip_rtc_header_file); return 0; } diff --git a/projects/hip-tests/utils/coverage/reportGenerators.cpp b/projects/hip-tests/utils/coverage/reportGenerators.cpp index 7b74282929..f086aee536 100644 --- a/projects/hip-tests/utils/coverage/reportGenerators.cpp +++ b/projects/hip-tests/utils/coverage/reportGenerators.cpp @@ -22,38 +22,43 @@ THE SOFTWARE. #include "reportGenerators.h" -BasicAPIStats::BasicAPIStats(std::vector& hip_api_groups): - number_of_called_apis{0}, number_of_not_called_apis{0}, - number_of_deprecated_apis{0}, total_number_of_api_calls{0}, - total_number_of_test_cases{0} -{ - for (auto const& hip_api_group: hip_api_groups) { +BasicAPIStats::BasicAPIStats(std::vector& hip_api_groups) + : number_of_called_apis{0}, + number_of_not_called_apis{0}, + number_of_deprecated_apis{0}, + total_number_of_api_calls{0}, + total_number_of_test_cases{0} { + for (auto const& hip_api_group : hip_api_groups) { number_of_called_apis += hip_api_group.getNumberOfCalledAPIs(); number_of_not_called_apis += hip_api_group.getNumberOfNotCalledAPIs(); number_of_deprecated_apis += hip_api_group.getNumberOfDeprecatedAPIs(); total_number_of_api_calls += hip_api_group.getTotalNumberOfCalls(); total_number_of_test_cases += hip_api_group.getTotalNumberOfTestCases(); } - total_number_of_apis = number_of_called_apis + number_of_not_called_apis + number_of_deprecated_apis; - tests_coverage_percentage = 100.f * number_of_called_apis / (number_of_called_apis + number_of_not_called_apis); + total_number_of_apis = + number_of_called_apis + number_of_not_called_apis + number_of_deprecated_apis; + tests_coverage_percentage = + 100.f * number_of_called_apis / (number_of_called_apis + number_of_not_called_apis); } -float BasicAPIStats::getLowCoverageLimit() const { - return 40.f; -} +float BasicAPIStats::getLowCoverageLimit() const { return 40.f; } -float BasicAPIStats::getMediumCoverageLimit() const { - return 80.f; -} +float BasicAPIStats::getMediumCoverageLimit() const { return 80.f; } -void generateXMLReportFiles(std::vector& hip_apis, std::vector& hip_api_groups) { +void generateXMLReportFiles(std::vector& hip_apis, + std::vector& hip_api_groups) { BasicAPIStats basic_stats{hip_api_groups}; - std::cout << "Total number of HIP API calls: " << basic_stats.total_number_of_api_calls << std::endl; - std::cout << "Number of the HIP APIs that are called at least once: " << basic_stats.number_of_called_apis << std::endl; - std::cout << "Number of the HIP APIs that are not called at all: " << basic_stats.number_of_not_called_apis << std::endl; - std::cout << "Number of the HIP APIs that are marked as deprecated: " << basic_stats.number_of_deprecated_apis << std::endl; - std::cout << "Test coverage by implemented tests, for the HIP APIs that are not marked as deprecated: "; + std::cout << "Total number of HIP API calls: " << basic_stats.total_number_of_api_calls + << std::endl; + std::cout << "Number of the HIP APIs that are called at least once: " + << basic_stats.number_of_called_apis << std::endl; + std::cout << "Number of the HIP APIs that are not called at all: " + << basic_stats.number_of_not_called_apis << std::endl; + std::cout << "Number of the HIP APIs that are marked as deprecated: " + << basic_stats.number_of_deprecated_apis << std::endl; + std::cout + << "Test coverage by implemented tests, for the HIP APIs that are not marked as deprecated: "; std::cout << basic_stats.tests_coverage_percentage << "%" << std::endl; /* @@ -71,36 +76,51 @@ void generateXMLReportFiles(std::vector& hip_apis, std::vector\n"; - coverage_report << "\t\n\t\tTotal number of detected HIP APIs."; - coverage_report << "\n\t\t" << hip_apis.size() << "\n\t\n"; + coverage_report << "\t\n\t\tTotal number of detected HIP " + "APIs."; + coverage_report << "\n\t\t" << hip_apis.size() + << "\n\t\n"; - coverage_report << "\t\n\t\tTotal number of HIP API calls within test source files."; - coverage_report << "\n\t\t" << basic_stats.total_number_of_api_calls << "\n\t\n"; + coverage_report << "\t\n\t\tTotal number of HIP API " + "calls within test source files."; + coverage_report << "\n\t\t" << basic_stats.total_number_of_api_calls + << "\n\t\n"; - coverage_report << "\t\n\t\tNumber of the HIP APIs that are called at least once."; - coverage_report << "\n\t\t" << basic_stats.number_of_called_apis << "\n\t\n"; + coverage_report << "\t\n\t\tNumber of the HIP APIs that are called at " + "least once."; + coverage_report << "\n\t\t" << basic_stats.number_of_called_apis + << "\n\t\n"; - coverage_report << "\t\n\t\tNumber of the HIP APIs that are not called at all."; - coverage_report << "\n\t\t" << basic_stats.number_of_not_called_apis << "\n\t\n"; + coverage_report << "\t\n\t\tNumber of the HIP APIs that are not " + "called at all."; + coverage_report << "\n\t\t" << basic_stats.number_of_not_called_apis + << "\n\t\n"; - coverage_report << "\t\n\t\tNumber of the HIP APIs that are marked as deprecated."; - coverage_report << "\n\t\t" << basic_stats.number_of_deprecated_apis << "\n\t\n"; + coverage_report << "\t\n\t\tNumber of the HIP APIs that are marked " + "as deprecated."; + coverage_report << "\n\t\t" << basic_stats.number_of_deprecated_apis + << "\n\t\n"; - coverage_report << "\t\n\t\tTest coverage by implemented tests for the HIP APIs that are not marked as deprecated."; - coverage_report << "\n\t\t" << basic_stats.tests_coverage_percentage << "%\n\t"; + coverage_report << "\t\n\t\tTest coverage by implemented tests " + "for the HIP APIs that are not marked as deprecated."; + coverage_report << "\n\t\t" << basic_stats.tests_coverage_percentage + << "%\n\t"; coverage_report << "\n"; - for (auto const& hip_api_group: hip_api_groups) { - coverage_report << hip_api_group.getBasicStatsHTML(); + for (auto const& hip_api_group : hip_api_groups) { + coverage_report << hip_api_group.getBasicStatsHTML(); } coverage_report.close(); - std::cout << "Generated XML report file " << findAbsolutePathOfFile(report_file_name) << std::endl; + std::cout << "Generated XML report file " << findAbsolutePathOfFile(report_file_name) + << std::endl; } -void generateHTMLReportFiles(std::vector& hip_apis, std::vector& hip_api_groups, - std::string tests_root_directory, std::string hipApiHeaderFile, std::string hip_rtc_header_file) { +void generateHTMLReportFiles(std::vector& hip_apis, + std::vector& hip_api_groups, + std::string tests_root_directory, std::string hipApiHeaderFile, + std::string hip_rtc_header_file) { BasicAPIStats basic_stats{hip_api_groups}; std::fstream coverage_report; @@ -130,17 +150,26 @@ void generateHTMLReportFiles(std::vector& hip_apis, std::vector"; - coverage_report << "" << one_tab << ""; + coverage_report << "" << one_tab + << ""; coverage_report << one_tab << "HIP API Coverage report"; - coverage_report << one_tab << "" << one_tab << ""; - coverage_report << one_tab << "" << one_tab << "
"; + coverage_report << one_tab + << "" + << one_tab << ""; + coverage_report << one_tab << "" << one_tab + << "
"; coverage_report << two_tabs << ""; - coverage_report << two_tabs << "\n"; - coverage_report << two_tabs << "" << three_tabs << ""; - coverage_report << three_tabs << ""; - coverage_report << three_tabs << ""; - coverage_report << three_tabs << ""; - coverage_report << three_tabs << ""; - coverage_report << three_tabs << ""; - coverage_report << three_tabs << ""; - coverage_report << three_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs << ""; coverage_report << three_tabs << ""; coverage_report << two_tabs << ""; @@ -282,7 +336,57 @@ void generateHTMLReportFiles(std::vector& hip_apis, std::vector"; coverage_report << one_tab << "
HIP API Coverage report
" << four_tabs << "\n"; + coverage_report << two_tabs << "" << three_tabs << ""; coverage_report << two_tabs << ""; - coverage_report << two_tabs << "\n"; + coverage_report + << two_tabs + << "\n"; coverage_report << one_tab << "
" << four_tabs + << ""; - coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; + coverage_report << six_tabs + << ""; + coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; @@ -150,15 +179,18 @@ void generateHTMLReportFiles(std::vector& hip_apis, std::vectorSource files included:"; coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; + coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; coverage_report << five_tabs << ""; coverage_report << five_tabs << ""; coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; + coverage_report << six_tabs + << ""; + coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; coverage_report << five_tabs << ""; @@ -166,31 +198,38 @@ void generateHTMLReportFiles(std::vector& hip_apis, std::vector"; coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; + coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; coverage_report << five_tabs << ""; coverage_report << five_tabs << ""; coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; + coverage_report << six_tabs + << ""; + coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; coverage_report << five_tabs << ""; coverage_report << five_tabs << ""; coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; + coverage_report << six_tabs + << ""; + coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; coverage_report << five_tabs << ""; coverage_report << five_tabs << ""; coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; + coverage_report << six_tabs + << ""; + coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; coverage_report << five_tabs << ""; @@ -198,29 +237,32 @@ void generateHTMLReportFiles(std::vector& hip_apis, std::vector"; coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; - coverage_report << six_tabs << ""; + coverage_report + << six_tabs + << ""; + coverage_report << six_tabs << ""; coverage_report << six_tabs << ""; coverage_report << five_tabs << ""; - - coverage_report << five_tabs << ""; + + coverage_report << five_tabs + << ""; coverage_report << four_tabs << "
Catch2 tests location:" << tests_root_directory << "Catch2 tests location:" << tests_root_directory + << "Value" << hipApiHeaderFile << "Total number of detected HIP APIs:" << basic_stats.total_number_of_apis << "" + << basic_stats.total_number_of_apis << "
" << hip_rtc_header_file << "HIP API calls within test source files:" << basic_stats.total_number_of_api_calls << "HIP API calls within test source files:" + << basic_stats.total_number_of_api_calls << "
Total number of test cases:" << basic_stats.total_number_of_test_cases << "" + << basic_stats.total_number_of_test_cases << "
HIP APIs that are called at least once:" << basic_stats.number_of_called_apis << "HIP APIs that are called at least once:" + << basic_stats.number_of_called_apis << "
HIP APIs that are not called at all:" << basic_stats.number_of_not_called_apis << "HIP APIs that are not called at all:" + << basic_stats.number_of_not_called_apis << "
HIP APIs that are marked as deprecated:" << basic_stats.number_of_deprecated_apis << "HIP APIs that are marked as deprecated:" + << basic_stats.number_of_deprecated_apis << "
Test coverage by implemented tests for the HIP APIs:" << - std::fixed << std::setprecision(2) << basic_stats.tests_coverage_percentage << "%Test coverage by implemented tests for the HIP APIs:" << std::fixed + << std::setprecision(2) << basic_stats.tests_coverage_percentage << "%
"; coverage_report << three_tabs << "
"; // Add info about HIP API Groups. @@ -254,11 +296,17 @@ void generateHTMLReportFiles(std::vector& hip_apis, std::vector& hip_apis, std::vector"; coverage_report << three_tabs << "
" << basic_stats.total_number_of_apis << "" << basic_stats.total_number_of_api_calls << "" << basic_stats.total_number_of_test_cases << "" << basic_stats.number_of_called_apis << "" << basic_stats.number_of_not_called_apis << "" << basic_stats.number_of_deprecated_apis << "" << - std::fixed << std::setprecision(2) << basic_stats.tests_coverage_percentage << "%" + << basic_stats.total_number_of_apis << "" + << basic_stats.total_number_of_api_calls << "" + << basic_stats.total_number_of_test_cases << "" + << basic_stats.number_of_called_apis << "" + << basic_stats.number_of_not_called_apis << "" + << basic_stats.number_of_deprecated_apis << "" << std::fixed + << std::setprecision(2) << basic_stats.tests_coverage_percentage << "%
"; - coverage_report << two_tabs << ""; + coverage_report + << two_tabs + << ""; + coverage_report << one_tab << "
"; + coverage_report << one_tab << "
"; + + coverage_report << one_tab << "
"; + coverage_report << one_tab << ""; + coverage_report << two_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << two_tabs << ""; + + coverage_report << two_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << two_tabs << ""; + + coverage_report << two_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << two_tabs << ""; + + coverage_report << two_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report + << three_tabs + << ""; + coverage_report << two_tabs << ""; + + coverage_report << two_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs + << ""; + coverage_report << two_tabs << ""; + + coverage_report << two_tabs << ""; + coverage_report << three_tabs << ""; + coverage_report << three_tabs + << ""; + coverage_report << two_tabs << ""; + + coverage_report << one_tab << "
Color legend
Module is deprecated
Percentage of called APIs within a module is less than 40%
Percentage of called APIs within a module is between " + "40% and 80%
Percentage of called APIs within a module is larger " + "than 80%
"; + coverage_report << one_tab << "
"; + coverage_report << one_tab << "
"; + + coverage_report << one_tab << ""; + coverage_report + << two_tabs + << ""; time_t now{time(nullptr)}; std::string date{asctime(gmtime(&now))}; @@ -295,7 +399,7 @@ void generateHTMLReportFiles(std::vector& hip_apis, std::vector& hip_apis, std::vector& hip_apis, std::vector& hip_api_groups); -void generateHTMLReportFiles(std::vector& hip_apis, std::vector& hip_api_groups, - std::string tests_root_directory, std::string hipApiHeaderFile, std::string hip_rtc_header_file); +void generateXMLReportFiles(std::vector& hip_apis, + std::vector& hip_api_groups); +void generateHTMLReportFiles(std::vector& hip_apis, + std::vector& hip_api_groups, + std::string tests_root_directory, std::string hipApiHeaderFile, + std::string hip_rtc_header_file); From 90bf5fe72d2e5650665b3776b2270f19022a3b38 Mon Sep 17 00:00:00 2001 From: Jatin Chaudhary <51944368+cjatin@users.noreply.github.com> Date: Tue, 11 Jul 2023 16:55:25 +0100 Subject: [PATCH 22/25] SWDEV-408621 - Memory tests are also getting the command-line too long error on windows. (#362) Change-Id: Ieffd7c20630b3d1eab6124b3b00cb62926b7c058 [ROCm/hip-tests commit: 2e029a85296ada9fea3bc247cbc3c88ac577476f] --- .../catch/unit/memory/CMakeLists.txt | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/projects/hip-tests/catch/unit/memory/CMakeLists.txt b/projects/hip-tests/catch/unit/memory/CMakeLists.txt index 1608574891..6f236ac229 100644 --- a/projects/hip-tests/catch/unit/memory/CMakeLists.txt +++ b/projects/hip-tests/catch/unit/memory/CMakeLists.txt @@ -18,9 +18,14 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +# Common Tests - Test independent of all platforms set(COMMON_SHARED_SRC DriverContext.cc) -# Common Tests - Test independent of all platforms +# FIXME: cjatin +# This is a temp hack to pass it on windows since it has a char limit for +# command line. Eventually we need to use rsp files with ninja on windows. +# But this exposes several problems with hipcc and build system on windows. +# While those are fixed, this hack should allow us to pass windows CI. set(TEST_SRC memset.cc malloc.cc @@ -63,7 +68,27 @@ set(TEST_SRC hipMemAdviseMmap.cc hipMallocManaged.cc hipMemRangeGetAttribute.cc - hipMemRangeGetAttribute_old.cc + hipMemRangeGetAttribute_old.cc) + +if(HIP_PLATFORM MATCHES "amd") + set(TEST_SRC + ${TEST_SRC} + hipMemPtrGetInfo.cc + hipPointerGetAttributes.cc + hipMemCoherencyTst.cc + hipExtMallocWithFlags.cc + hipMallocMngdMultiThread.cc + hipArray.cc + hipMemVmm.cc) +else() + set(TEST_SRC ${TEST_SRC} hipGetSymbolSizeAddress.cc) +endif() + +hip_add_exe_to_target(NAME MemoryTest1 + TEST_SRC ${TEST_SRC} + TEST_TARGET_NAME build_tests COMMON_SHARED_SRC ${COMMON_SHARED_SRC}) + +set(TEST_SRC hipMemcpyFromSymbol.cc hipPtrGetAttribute.cc hipMemPoolApi.cc @@ -114,20 +139,6 @@ set(TEST_SRC hipMemRangeGetAttributes_old.cc hipMemGetAddressRange.cc) -if(HIP_PLATFORM MATCHES "amd") - set(TEST_SRC - ${TEST_SRC} - hipMemPtrGetInfo.cc - hipPointerGetAttributes.cc - hipMemCoherencyTst.cc - hipExtMallocWithFlags.cc - hipMallocMngdMultiThread.cc - hipArray.cc - hipMemVmm.cc) -else() - set(TEST_SRC ${TEST_SRC} hipGetSymbolSizeAddress.cc) -endif() - -hip_add_exe_to_target(NAME MemoryTest +hip_add_exe_to_target(NAME MemoryTest2 TEST_SRC ${TEST_SRC} TEST_TARGET_NAME build_tests COMMON_SHARED_SRC ${COMMON_SHARED_SRC}) From 6647d396b221fb8f606709c13722520a92bed948 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Wed, 12 Jul 2023 00:07:23 +0530 Subject: [PATCH 23/25] SWDEV-403960 - [catch2][dtest] Enable xnack+ check condition (#364) Change-Id: I9627d75d0d3258cf261c8e4bfe6c7c3c35c8f9c1 [ROCm/hip-tests commit: 042234e0b2dab87e7275e85d2ec49540a5bf1de0] --- .../multiproc/hipMemCoherencyTstMProc.cc | 307 +++--------------- .../catch/unit/memory/CMakeLists.txt | 3 +- .../unit/memory/hipHmmOvrSubscriptionTst.cc | 104 ++++++ .../catch/unit/memory/hipMemAdvise_old.cc | 93 ++---- 4 files changed, 179 insertions(+), 328 deletions(-) create mode 100644 projects/hip-tests/catch/unit/memory/hipHmmOvrSubscriptionTst.cc diff --git a/projects/hip-tests/catch/multiproc/hipMemCoherencyTstMProc.cc b/projects/hip-tests/catch/multiproc/hipMemCoherencyTstMProc.cc index 576f8d8bc2..6098cf9e4c 100644 --- a/projects/hip-tests/catch/multiproc/hipMemCoherencyTstMProc.cc +++ b/projects/hip-tests/catch/multiproc/hipMemCoherencyTstMProc.cc @@ -81,13 +81,16 @@ static void TstCoherency(int *Ptr, bool HmmMem) { // Getting gpu frequency if (IsGfx11()) { - HIPCHECK(hipDeviceGetAttribute(&peak_clk, hipDeviceAttributeWallClockRate, 0)); + HIPCHECK(hipDeviceGetAttribute(&peak_clk, + hipDeviceAttributeWallClockRate, 0)); } else { - HIPCHECK(hipDeviceGetAttribute(&peak_clk, hipDeviceAttributeClockRate, 0)); + HIPCHECK(hipDeviceGetAttribute(&peak_clk, + hipDeviceAttributeClockRate, 0)); } if (!HmmMem) { - HIP_CHECK(hipHostGetDevicePointer(reinterpret_cast(&Dptr), Ptr, 0)); + HIP_CHECK(hipHostGetDevicePointer(reinterpret_cast(&Dptr), + Ptr, 0)); if (IsGfx11()) { CoherentTst_gfx11<<<1, 1, 0, strm>>>(Dptr, peak_clk); } else { @@ -122,58 +125,13 @@ static void TstCoherency(int *Ptr, bool HmmMem) { // The following test is failing on Nvidia platform hence disabled it for now #if HT_AMD TEST_CASE("Unit_malloc_CoherentTst") { - if ((setenv("HSA_XNACK", "1", 1)) != 0) { - WARN("Unable to turn on HSA_XNACK, hence terminating the Test case!"); - REQUIRE(false); - } - // The following code block is used to check for gfx906/8 so as to skip if - // any of the gpus available - int fd1[2]; // Used to store two ends of first pipe - pid_t p; - if (pipe(fd1) == -1) { - fprintf(stderr, "Pipe Failed"); - REQUIRE(false); - } - - /* GpuId[0] for gfx90a exists--> 1 for yes and 0 for no*/ - int GpuId[1] = {0}; - p = fork(); - - if (p < 0) { - fprintf(stderr, "fork Failed"); - REQUIRE(false); - } else if (p > 0) { // parent process - close(fd1[1]); // Close writing end of first pipe - // Wait for child to send a string - wait(NULL); - // Read string from child and close reading end. - read(fd1[0], GpuId, 2 * sizeof(int)); - close(fd1[0]); - if (GpuId[0] == 0) { - WARN("This test is applicable for MI200." - "Skipping the test!!"); - exit(0); - } - } else { // child process - close(fd1[0]); // Close read end of first pipe - hipDeviceProp_t prop; - HIPCHECK(hipGetDeviceProperties(&prop, 0)); - char *p = NULL; - - if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, prop.gcnArchName)) { - WARN("gfx90a gpu found on this system!!"); - GpuId[0] = 1; - } - - // Write concatenated string and close writing end - write(fd1[1], GpuId, 2 * sizeof(int)); - close(fd1[1]); - exit(0); - } - - // Test Case execution begins from here - int stat = 0; - if (fork() == 0) { + hipDeviceProp_t prop; + HIPCHECK(hipGetDeviceProperties(&prop, 0)); + char *p = NULL; + p = strstr(prop.gcnArchName, "xnack+"); + if (p) { + // Test Case execution begins from here + int stat = 0; int managed = 0; HIPCHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributeManagedMemory, 0)); @@ -185,23 +143,10 @@ TEST_CASE("Unit_malloc_CoherentTst") { Ptr = reinterpret_cast(malloc(SIZE)); TstCoherency(Ptr, HmmMem); free(Ptr); - if (YES_COHERENT) { - // exit() with code 10 which indicates pass - exit(10); - } else { - // exit() with code 9 which indicates fail - exit(9); - } - } else { - SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory " - "attribute. Hence skipping the testing with Pass result.\n"); - } + REQUIRE(YES_COHERENT); + } } else { - wait(&stat); - int Result = WEXITSTATUS(stat); - if (Result != 10) { - REQUIRE(false); - } + HipTest::HIP_SKIP_TEST("GPU is not xnack enabled hence skipping the test...\n"); } } #endif @@ -212,55 +157,12 @@ TEST_CASE("Unit_malloc_CoherentTst") { // The following test is failing on Nvidia platform hence disabling it for now #if HT_AMD TEST_CASE("Unit_malloc_CoherentTstWthAdvise") { - if ((setenv("HSA_XNACK", "1", 1)) != 0) { - WARN("Unable to turn on HSA_XNACK, hence terminating the Test case!"); - REQUIRE(false); - } - // The following code block is used to check for gfx906/8 so as to skip if - // any of the gpus available - int fd1[2]; // Used to store two ends of first pipe - pid_t p; - if (pipe(fd1) == -1) { - fprintf(stderr, "Pipe Failed"); - REQUIRE(false); - } - - /* GpuId[0] for gfx90a exists--> 1 for yes and 0 for no */ - int GpuId[1] = {0}; - p = fork(); - - if (p < 0) { - fprintf(stderr, "fork Failed"); - REQUIRE(false); - } else if (p > 0) { // parent process - close(fd1[1]); // Close writing end of first pipe - // Wait for child to send a string - wait(NULL); - // Read string from child and close reading end. - read(fd1[0], GpuId, 2 * sizeof(int)); - close(fd1[0]); - if (GpuId[0] == 0) { - WARN("This test is applicable for MI200." - "Skipping the test!!"); - exit(0); - } - } else { // child process - close(fd1[0]); // Close read end of first pipe - hipDeviceProp_t prop; - HIPCHECK(hipGetDeviceProperties(&prop, 0)); - char *p = NULL; - p = strstr(prop.gcnArchName, "gfx90a"); - if (p) { - WARN("gfx90a gpu found on this system!!"); - GpuId[0] = 1; - } - // Write concatenated string and close writing end - write(fd1[1], GpuId, 2 * sizeof(int)); - close(fd1[1]); - exit(0); - } - int stat = 0; - if (fork() == 0) { + hipDeviceProp_t prop; + HIPCHECK(hipGetDeviceProperties(&prop, 0)); + char *p = NULL; + p = strstr(prop.gcnArchName, "xnack+"); + if (p) { + int stat = 0; int managed = 0; HIP_CHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributeManagedMemory, 0)); @@ -275,25 +177,10 @@ TEST_CASE("Unit_malloc_CoherentTstWthAdvise") { SquareKrnl<<<1, 1, 0, strm>>>(Ptr); HIP_CHECK(hipStreamSynchronize(strm)); HIP_CHECK(hipStreamDestroy(strm)); - if (*Ptr == 16) { - // exit() with code 10 which indicates pass - free(Ptr); - exit(10); - } else { - // exit() with code 9 which indicates fail - free(Ptr); - exit(9); - } - } else { - SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory " - "attribute. Hence skipping the testing with Pass result.\n"); + REQUIRE (*Ptr == 16); } } else { - wait(&stat); - int Result = WEXITSTATUS(stat); - if (Result != 10) { - REQUIRE(false); - } + HipTest::HIP_SKIP_TEST("GPU is not xnack enabled hence skipping the test...\n"); } } #endif @@ -303,55 +190,12 @@ TEST_CASE("Unit_malloc_CoherentTstWthAdvise") { // The following test is failing on Nvidia platform hence disabling it for now #if HT_AMD TEST_CASE("Unit_mmap_CoherentTst") { - if ((setenv("HSA_XNACK", "1", 1)) != 0) { - WARN("Unable to turn on HSA_XNACK, hence terminating the Test case!"); - REQUIRE(false); - } - // The following code block is used to check for gfx906/8 so as to skip if - // any of the gpus available - int fd1[2]; // Used to store two ends of first pipe - pid_t p; - if (pipe(fd1) == -1) { - fprintf(stderr, "Pipe Failed"); - REQUIRE(false); - } - - /* GpuId[0] for gfx90a exists--> 1 for yes and 0 for no */ - int GpuId[1] = {0}; - p = fork(); - - if (p < 0) { - fprintf(stderr, "fork Failed"); - REQUIRE(false); - } else if (p > 0) { // parent process - close(fd1[1]); // Close writing end of first pipe - // Wait for child to send a string - wait(NULL); - // Read string from child and close reading end. - read(fd1[0], GpuId, 2 * sizeof(int)); - close(fd1[0]); - if (GpuId[0] == 0) { - WARN("This test is not applicable for MI200." - "Skipping the test!!"); - exit(0); - } - } else { // child process - close(fd1[0]); // Close read end of first pipe - hipDeviceProp_t prop; - HIPCHECK(hipGetDeviceProperties(&prop, 0)); - char *p = NULL; - p = strstr(prop.gcnArchName, "gfx90a"); - if (p) { - WARN("gfx90a gpu found on this system!!"); - GpuId[0] = 1; - } - // Write concatenated string and close writing end - write(fd1[1], GpuId, 2 * sizeof(int)); - close(fd1[1]); - exit(0); - } - int stat = 0; - if (fork() == 0) { + hipDeviceProp_t prop; + HIPCHECK(hipGetDeviceProperties(&prop, 0)); + char *p = NULL; + p = strstr(prop.gcnArchName, "xnack+"); + if (p) { + int stat = 0; int managed = 0; HIP_CHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributeManagedMemory, 0)); @@ -371,21 +215,10 @@ TEST_CASE("Unit_mmap_CoherentTst") { if (err != 0) { WARN("munmap failed\n"); } - if (YES_COHERENT) { - exit(10); - } else { - exit(9); - } - } else { - SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory " - "attribute. Hence skipping the testing with Pass result.\n"); - } + REQUIRE(YES_COHERENT); + } } else { - wait(&stat); - int Result = WEXITSTATUS(stat); - if (Result != 10) { - REQUIRE(false); - } + HipTest::HIP_SKIP_TEST("GPU is not xnack enabled hence skipping the test...\n"); } } #endif @@ -395,55 +228,12 @@ TEST_CASE("Unit_mmap_CoherentTst") { // The following test is failing on Nvidia platform hence disabling it for now #if HT_AMD TEST_CASE("Unit_mmap_CoherentTstWthAdvise") { - if ((setenv("HSA_XNACK", "1", 1)) != 0) { - WARN("Unable to turn on HSA_XNACK, hence terminating the Test case!"); - REQUIRE(false); - } - // The following code block is used to check for gfx906/8 so as to skip if - // any of the gpus available - int fd1[2]; // Used to store two ends of first pipe - pid_t p; - if (pipe(fd1) == -1) { - fprintf(stderr, "Pipe Failed"); - REQUIRE(false); - } - - /* GpuId[0] for gfx90a exists--> 1 for yes and 0 for no */ - int GpuId[1] = {0}; - p = fork(); - - if (p < 0) { - fprintf(stderr, "fork Failed"); - REQUIRE(false); - } else if (p > 0) { // parent process - close(fd1[1]); // Close writing end of first pipe - // Wait for child to send a string - wait(NULL); - // Read string from child and close reading end. - read(fd1[0], GpuId, 2 * sizeof(int)); - close(fd1[0]); - if (GpuId[0] == 0) { - WARN("This test is applicable for MI200." - "Skipping the test!!"); - exit(0); - } - } else { // child process - close(fd1[0]); // Close read end of first pipe - hipDeviceProp_t prop; - HIPCHECK(hipGetDeviceProperties(&prop, 0)); - char *p = NULL; - p = strstr(prop.gcnArchName, "gfx90a"); - if (p) { - WARN("gfx90a gpu found on this system!!"); - GpuId[0] = 1; - } - // Write concatenated string and close writing end - write(fd1[1], GpuId, 2 * sizeof(int)); - close(fd1[1]); - exit(0); - } - int stat = 0; - if (fork() == 0) { + hipDeviceProp_t prop; + HIPCHECK(hipGetDeviceProperties(&prop, 0)); + char *p = NULL; + p = strstr(prop.gcnArchName, "xnack+"); + if (p) { + int stat = 0; int managed = 0; HIP_CHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributeManagedMemory, 0)); @@ -466,26 +256,15 @@ TEST_CASE("Unit_mmap_CoherentTstWthAdvise") { bool IfTstPassed = false; if (*Ptr == 81) { IfTstPassed = true; - } + } int err = munmap(Ptr, SIZE); if (err != 0) { WARN("munmap failed\n"); } - if (IfTstPassed) { - exit(10); - } else { - exit(9); - } - } else { - SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory " - "attribute. Hence skipping the testing with Pass result.\n"); - } + REQUIRE(IfTstPassed); + } } else { - wait(&stat); - int Result = WEXITSTATUS(stat); - if (Result != 10) { - REQUIRE(false); - } + HipTest::HIP_SKIP_TEST("GPU is not xnack enabled hence skipping the test...\n"); } } #endif diff --git a/projects/hip-tests/catch/unit/memory/CMakeLists.txt b/projects/hip-tests/catch/unit/memory/CMakeLists.txt index 6f236ac229..f76ec2f9fe 100644 --- a/projects/hip-tests/catch/unit/memory/CMakeLists.txt +++ b/projects/hip-tests/catch/unit/memory/CMakeLists.txt @@ -137,7 +137,8 @@ set(TEST_SRC hipMallocAsync.cc hipStreamAttachMemAsync.cc hipMemRangeGetAttributes_old.cc - hipMemGetAddressRange.cc) + hipMemGetAddressRange.cc + hipHmmOvrSubscriptionTst.cc) hip_add_exe_to_target(NAME MemoryTest2 TEST_SRC ${TEST_SRC} diff --git a/projects/hip-tests/catch/unit/memory/hipHmmOvrSubscriptionTst.cc b/projects/hip-tests/catch/unit/memory/hipHmmOvrSubscriptionTst.cc new file mode 100644 index 0000000000..80a8e0d849 --- /dev/null +++ b/projects/hip-tests/catch/unit/memory/hipHmmOvrSubscriptionTst.cc @@ -0,0 +1,104 @@ +/* +Copyright (c) 2021-Present 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. +*/ + +/* Test Case Description: This test case tests the working of OverSubscription + feature which is part of HMM.*/ + +#include + +#define INIT_VAL 2.5 +#define NUM_ELMS 268435456 // 268435456 * 4 = 1GB +#define ITERATIONS 10 +#define ONE_GB 1024 * 1024 * 1024 + +// Kernel function +__global__ void Square(int n, float *x) { + int index = blockIdx.x * blockDim.x + threadIdx.x; + int stride = blockDim.x * gridDim.x; + for (int i = index; i < n; i += stride) { + x[i] = x[i] + 10; + } +} + +static void OneGBMemTest(int dev) { + int DataMismatch = 0; + float *HmmAG = nullptr; + hipStream_t strm; + HIP_CHECK(hipStreamCreate(&strm)); + // Testing hipMemAttachGlobal Flag + HIP_CHECK(hipMallocManaged(&HmmAG, NUM_ELMS * sizeof(float), + hipMemAttachGlobal)); + + // Initializing HmmAG memory + for (int i = 0; i < NUM_ELMS; i++) { + HmmAG[i] = INIT_VAL; + } + + int blockSize = 256; + int numBlocks = (NUM_ELMS + blockSize - 1) / blockSize; + dim3 dimGrid(numBlocks, 1, 1); + dim3 dimBlock(blockSize, 1, 1); + HIP_CHECK(hipSetDevice(dev)); + for (int i = 0; i < ITERATIONS; ++i) { + Square<<>>(NUM_ELMS, HmmAG); + } + HIP_CHECK(hipStreamSynchronize(strm)); + for (int j = 0; j < NUM_ELMS; ++j) { + if (HmmAG[j] != (INIT_VAL + ITERATIONS * 10)) { + DataMismatch++; + break; + } + } + if (DataMismatch != 0) { + WARN("Data Mismatch observed when kernel launched on device: " << dev); + REQUIRE(false); + } + HIP_CHECK(hipFree(HmmAG)); + HIP_CHECK(hipStreamDestroy(strm)); +} + +TEST_CASE("Unit_HMM_OverSubscriptionTst") { + // Checking if xnack is enabled + hipDeviceProp_t prop; + HIP_CHECK(hipGetDeviceProperties(&prop, 0)); + char *p = NULL; + p = strstr(prop.gcnArchName, "xnack+"); + if (p) { + size_t FreeMem, TotGpuMem; + HIP_CHECK(hipMemGetInfo(&FreeMem, &TotGpuMem)); + int NumGB = (TotGpuMem/(ONE_GB)); + int TotalThreads = (NumGB + 10); + WARN("Launching " << TotalThreads); + WARN(" processes to test OverSubscription."); + + std::thread Thrds[TotalThreads]; + + for (int k = 0; k < TotalThreads; ++k) { + Thrds[k] = std::thread(OneGBMemTest, 0); + } + for (int k = 0; k < TotalThreads; ++k) { + Thrds[k].join(); + } + } else { + HipTest::HIP_SKIP_TEST("GPU is not xnack enabled hence skipping the test...\n"); + } +} diff --git a/projects/hip-tests/catch/unit/memory/hipMemAdvise_old.cc b/projects/hip-tests/catch/unit/memory/hipMemAdvise_old.cc index 8b7350a7a6..62dcb81627 100644 --- a/projects/hip-tests/catch/unit/memory/hipMemAdvise_old.cc +++ b/projects/hip-tests/catch/unit/memory/hipMemAdvise_old.cc @@ -652,87 +652,54 @@ TEST_CASE("Unit_hipMemAdvise_TstAccessedByFlg4") { } } - /* Allocate memory using aligned_alloc(), assign PreferredLocation flag to the allocated memory and launch a kernel. Kernel should get executed successfully without hang or segfault*/ #if __linux__ && HT_AMD TEST_CASE("Unit_hipMemAdvise_TstAlignedAllocMem") { - if ((setenv("HSA_XNACK", "1", 1)) != 0) { - WARN("Unable to turn on HSA_XNACK, hence terminating the Test case!"); - REQUIRE(false); - } - // The following code block checks for gfx90a,940,941,942 so as to skip if the device is not - + // The following code block checks for xnack+ + // so as to skip if the device is not xnack+ hipDeviceProp_t prop; int device; HIP_CHECK(hipGetDevice(&device)); HIP_CHECK(hipGetDeviceProperties(&prop, device)); std::string gfxName(prop.gcnArchName); - if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_HMM, prop.gcnArchName)) { + if (gfxName.find("xnack+") != std::string::npos) { int stat = 0; - if (fork() == 0) { - // The below part should be inside fork - int managedMem = 0, pageMemAccess = 0; - HIP_CHECK(hipDeviceGetAttribute(&pageMemAccess, - hipDeviceAttributePageableMemoryAccess, 0)); - WARN("hipDeviceAttributePageableMemoryAccess:" << pageMemAccess); - - HIP_CHECK(hipDeviceGetAttribute(&managedMem, hipDeviceAttributeManagedMemory, 0)); - WARN("hipDeviceAttributeManagedMemory: " << managedMem); - if ((managedMem == 1) && (pageMemAccess == 1)) { - int *Mllc = nullptr, MemSz = 4096 * 4, NumElms = 4096, InitVal = 123; - // Mllc = reinterpret_cast<(int *)>(aligned_alloc(4096, MemSz)); - Mllc = reinterpret_cast(aligned_alloc(4096, 4096*4)); - for (int i = 0; i < NumElms; ++i) { - Mllc[i] = InitVal; - } - hipStream_t strm; - int DataMismatch = 0; - HIP_CHECK(hipStreamCreate(&strm)); - // The following hipMemAdvise() call is made to know if advise on - // aligned_alloc() is causing any issue - HIP_CHECK(hipMemAdvise(Mllc, MemSz, hipMemAdviseSetPreferredLocation, 0)); - HIP_CHECK(hipMemPrefetchAsync(Mllc, MemSz, 0, strm)); - HIP_CHECK(hipStreamSynchronize(strm)); - MemAdvise2<<<(NumElms/32), 32, 0, strm>>>(Mllc, NumElms); - HIP_CHECK(hipStreamSynchronize(strm)); + int managedMem = 0, pageMemAccess = 0; + HIP_CHECK(hipDeviceGetAttribute(&pageMemAccess, + hipDeviceAttributePageableMemoryAccess, 0)); + WARN("hipDeviceAttributePageableMemoryAccess:" << pageMemAccess); + HIP_CHECK(hipDeviceGetAttribute(&managedMem, hipDeviceAttributeManagedMemory, 0)); + WARN("hipDeviceAttributeManagedMemory: " << managedMem); + if ((managedMem == 1) && (pageMemAccess == 1)) { + int *Mllc = nullptr, MemSz = 4096 * 4, NumElms = 4096, InitVal = 123; + // Mllc = reinterpret_cast<(int *)>(aligned_alloc(4096, MemSz)); + Mllc = reinterpret_cast(aligned_alloc(4096, 4096*4)); + for (int i = 0; i < NumElms; ++i) { + Mllc[i] = InitVal; + } + hipStream_t strm; + int DataMismatch = 0; + HIP_CHECK(hipStreamCreate(&strm)); + // The following hipMemAdvise() call is made to know if advise on + // aligned_alloc() is causing any issue + HIP_CHECK(hipMemAdvise(Mllc, MemSz, hipMemAdviseSetPreferredLocation, 0)); + HIP_CHECK(hipMemPrefetchAsync(Mllc, MemSz, 0, strm)); + HIP_CHECK(hipStreamSynchronize(strm)); + MemAdvise2<<<(NumElms/32), 32, 0, strm>>>(Mllc, NumElms); + HIP_CHECK(hipStreamSynchronize(strm)); for (int i = 0; i < NumElms; ++i) { if (Mllc[i] != (InitVal + 10)) { DataMismatch++; } } - if (DataMismatch != 0) { - WARN("DataMismatch observed!!"); - exit(9); // 9 for failure - } else { - exit(10); // 10 for Pass result - } - } else { - SUCCEED("GPU 0 doesn't support ManagedMemory with hipDeviceAttributePageableMemoryAccess " - "attribute. Hence skipping the testing with Pass result.\n"); - exit(Catch::ResultDisposition::ContinueOnFailure); - } - } else { - wait(&stat); - int Result = WEXITSTATUS(stat); - if (Result == Catch::ResultDisposition::ContinueOnFailure) { - WARN("GPU 0 doesn't support ManagedMemory with hipDeviceAttributePageableMemoryAccess " - "attribute. Hence skipping the testing with Pass result.\n"); - } else { - if (Result != 10) { - REQUIRE(false); - } - } - } + REQUIRE(DataMismatch == 0); + } } else { - SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gx941, gfx942, Hence" - "skipping the testcase for this GPU " << device); - WARN("Memory model feature is only supported for gfx90a, gfx940, gx941, gfx942, Hence" - "skipping the testcase for this GPU " << device); - } - + HipTest::HIP_SKIP_TEST("GPU is not xnack enabled hence skipping the test...\n"); + } } #endif From d2df4a5552630fa877206bf92b1a44b7ae99c576 Mon Sep 17 00:00:00 2001 From: Maneesh Gupta Date: Wed, 12 Jul 2023 12:34:03 +0530 Subject: [PATCH 24/25] Remove Unit_HMM_OverSubscriptionTst from unit tests Test migrated to stress test as part of #317. [ROCm/hip-tests commit: c9190f77ebf3b0b036116a08eeaca6aaed0cc5c7] --- .../catch/unit/memory/CMakeLists.txt | 3 +- .../unit/memory/hipHmmOvrSubscriptionTst.cc | 104 ------------------ 2 files changed, 1 insertion(+), 106 deletions(-) delete mode 100644 projects/hip-tests/catch/unit/memory/hipHmmOvrSubscriptionTst.cc diff --git a/projects/hip-tests/catch/unit/memory/CMakeLists.txt b/projects/hip-tests/catch/unit/memory/CMakeLists.txt index f76ec2f9fe..6f236ac229 100644 --- a/projects/hip-tests/catch/unit/memory/CMakeLists.txt +++ b/projects/hip-tests/catch/unit/memory/CMakeLists.txt @@ -137,8 +137,7 @@ set(TEST_SRC hipMallocAsync.cc hipStreamAttachMemAsync.cc hipMemRangeGetAttributes_old.cc - hipMemGetAddressRange.cc - hipHmmOvrSubscriptionTst.cc) + hipMemGetAddressRange.cc) hip_add_exe_to_target(NAME MemoryTest2 TEST_SRC ${TEST_SRC} diff --git a/projects/hip-tests/catch/unit/memory/hipHmmOvrSubscriptionTst.cc b/projects/hip-tests/catch/unit/memory/hipHmmOvrSubscriptionTst.cc deleted file mode 100644 index 80a8e0d849..0000000000 --- a/projects/hip-tests/catch/unit/memory/hipHmmOvrSubscriptionTst.cc +++ /dev/null @@ -1,104 +0,0 @@ -/* -Copyright (c) 2021-Present 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. -*/ - -/* Test Case Description: This test case tests the working of OverSubscription - feature which is part of HMM.*/ - -#include - -#define INIT_VAL 2.5 -#define NUM_ELMS 268435456 // 268435456 * 4 = 1GB -#define ITERATIONS 10 -#define ONE_GB 1024 * 1024 * 1024 - -// Kernel function -__global__ void Square(int n, float *x) { - int index = blockIdx.x * blockDim.x + threadIdx.x; - int stride = blockDim.x * gridDim.x; - for (int i = index; i < n; i += stride) { - x[i] = x[i] + 10; - } -} - -static void OneGBMemTest(int dev) { - int DataMismatch = 0; - float *HmmAG = nullptr; - hipStream_t strm; - HIP_CHECK(hipStreamCreate(&strm)); - // Testing hipMemAttachGlobal Flag - HIP_CHECK(hipMallocManaged(&HmmAG, NUM_ELMS * sizeof(float), - hipMemAttachGlobal)); - - // Initializing HmmAG memory - for (int i = 0; i < NUM_ELMS; i++) { - HmmAG[i] = INIT_VAL; - } - - int blockSize = 256; - int numBlocks = (NUM_ELMS + blockSize - 1) / blockSize; - dim3 dimGrid(numBlocks, 1, 1); - dim3 dimBlock(blockSize, 1, 1); - HIP_CHECK(hipSetDevice(dev)); - for (int i = 0; i < ITERATIONS; ++i) { - Square<<>>(NUM_ELMS, HmmAG); - } - HIP_CHECK(hipStreamSynchronize(strm)); - for (int j = 0; j < NUM_ELMS; ++j) { - if (HmmAG[j] != (INIT_VAL + ITERATIONS * 10)) { - DataMismatch++; - break; - } - } - if (DataMismatch != 0) { - WARN("Data Mismatch observed when kernel launched on device: " << dev); - REQUIRE(false); - } - HIP_CHECK(hipFree(HmmAG)); - HIP_CHECK(hipStreamDestroy(strm)); -} - -TEST_CASE("Unit_HMM_OverSubscriptionTst") { - // Checking if xnack is enabled - hipDeviceProp_t prop; - HIP_CHECK(hipGetDeviceProperties(&prop, 0)); - char *p = NULL; - p = strstr(prop.gcnArchName, "xnack+"); - if (p) { - size_t FreeMem, TotGpuMem; - HIP_CHECK(hipMemGetInfo(&FreeMem, &TotGpuMem)); - int NumGB = (TotGpuMem/(ONE_GB)); - int TotalThreads = (NumGB + 10); - WARN("Launching " << TotalThreads); - WARN(" processes to test OverSubscription."); - - std::thread Thrds[TotalThreads]; - - for (int k = 0; k < TotalThreads; ++k) { - Thrds[k] = std::thread(OneGBMemTest, 0); - } - for (int k = 0; k < TotalThreads; ++k) { - Thrds[k].join(); - } - } else { - HipTest::HIP_SKIP_TEST("GPU is not xnack enabled hence skipping the test...\n"); - } -} From d7c774b709201991259c7e5491fd86da5fec3432 Mon Sep 17 00:00:00 2001 From: Maneesh Gupta Date: Fri, 14 Jul 2023 12:11:16 +0530 Subject: [PATCH 25/25] Disable tests failing in stress testing. [ROCm/hip-tests commit: ad9f036f1dd11e9c1293bc511d3f12c980bfc393] --- .../catch/hipTestMain/config/config_amd_linux_common.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json b/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json index 2ba59aac81..445b274c88 100644 --- a/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json +++ b/projects/hip-tests/catch/hipTestMain/config/config_amd_linux_common.json @@ -115,6 +115,10 @@ "Unit_hipMemcpyAsync_Negative_Parameters", "Unit_hipMemcpyDtoHAsync_Negative_Parameters", "Unit_hipMemcpyHtoDAsync_Negative_Parameters", - "Unit_hipMemcpyDtoDAsync_Negative_Parameters" + "Unit_hipMemcpyDtoDAsync_Negative_Parameters", + "=== Below tests fail in stress test on 13/07/23 ===", + "Unit_deviceAllocation_Malloc_ComplexDataType", + "Unit_deviceAllocation_New_ComplexDataType", + "Unit_hipStreamValue_Wait32_Blocking_Mask_Eq_1" ] }