From 34976df2463c756d6d4018bd942b98a5642e36d9 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Mon, 14 Aug 2023 12:06:14 +0530 Subject: [PATCH 01/30] SWDEV-385161 - Deprecate usage of env vars in HIP samples and tests (#363) * SWDEV-385161 - Deprecate usage of env vars in HIP samples and tests env vars such as HIP_PATH, ROCM_PATH, HIP_COMPILER, HIP_RUNTIME, HSA_PATH etc are removed. Change-Id: I280e20b291cfb14675846aae72d97fa5b3ad567d --- catch/CMakeLists.txt | 76 ++++----- catch/README.md | 2 +- catch/include/hip_test_common.hh | 3 +- catch/include/memcpy3d_tests_common.hh | 10 +- catch/include/performance_common.hh | 3 + catch/multiproc/hipMemCoherencyTstMProc.cc | 4 - .../coalesced_groups_shfl_down.cc | 2 +- .../coalesced_groups_shfl_up.cc | 4 +- catch/unit/cooperativeGrps/grid_group.cc | 4 +- catch/unit/device/getDeviceCount_exe.cc | 12 +- .../device/hipDeviceGetP2PAttribute_exe.cc | 10 +- catch/unit/device/hipDeviceGetUuid.cc | 2 +- catch/unit/deviceLib/BuiltIns_fadd.cc | 8 +- catch/unit/deviceLib/BuiltIns_fmax.cc | 8 +- catch/unit/deviceLib/BuiltIns_fmin.cc | 8 +- catch/unit/deviceLib/hipStdComplex.cc | 1 + catch/unit/deviceLib/unsafeAtomicAdd_RTC.cc | 24 +-- catch/unit/graph/hipGraphCycle.cc | 4 +- catch/unit/graph/hipStreamBeginCapture.cc | 1 + catch/unit/graph/user_object_common.hh | 4 +- catch/unit/kernel/hipShflTests.cc | 1 - catch/unit/memory/hipArrayCommon.hh | 5 - catch/unit/memory/hipArrayCreate.cc | 2 +- catch/unit/memory/hipFreeAsync.cc | 2 +- catch/unit/memory/hipMalloc3D.cc | 2 +- catch/unit/memory/hipMallocArray.cc | 20 ++- catch/unit/memory/hipMallocConcurrency.cc | 6 +- catch/unit/memory/hipMemAdviseMmap.cc | 3 +- catch/unit/memory/hipMemAdvise_old.cc | 1 - .../memory/hipMemRangeGetAttributes_old.cc | 2 +- catch/unit/memory/hipMemcpy3D.cc | 2 + catch/unit/memory/hipMemcpy3DAsync.cc | 2 + catch/unit/rtc/linker.cc | 5 +- .../stream/hipStreamCreateWithPriority.cc | 12 +- catch/unit/surface/hipSurfaceObj1D.cc | 2 +- catch/unit/surface/hipSurfaceObj2D.cc | 2 +- catch/unit/surface/hipSurfaceObj3D.cc | 2 +- catch/unit/texture/hipTextureMipmapObj2D.cc | 2 +- .../unit/texture/hipTextureObjFetchVector.cc | 4 +- samples/0_Intro/bit_extract/CMakeLists.txt | 9 +- samples/0_Intro/bit_extract/Makefile | 47 ------ samples/0_Intro/bit_extract/README.md | 2 +- samples/0_Intro/module_api/CMakeLists.txt | 10 +- samples/0_Intro/module_api/Makefile | 47 ------ .../0_Intro/module_api_global/CMakeLists.txt | 13 +- samples/0_Intro/module_api_global/Makefile | 41 ----- samples/0_Intro/square/CMakeLists.txt | 13 +- samples/0_Intro/square/Makefile | 47 ------ samples/0_Intro/square/README.md | 9 +- .../1_Utils/hipDispatchLatency/CMakeLists.txt | 10 +- samples/1_Utils/hipDispatchLatency/Makefile | 44 ------ samples/1_Utils/hipInfo/CMakeLists.txt | 11 +- samples/1_Utils/hipInfo/Makefile | 43 ----- .../0_MatrixTranspose/CMakeLists.txt | 9 +- samples/2_Cookbook/0_MatrixTranspose/Makefile | 60 ------- .../2_Cookbook/10_inline_asm/CMakeLists.txt | 9 +- samples/2_Cookbook/10_inline_asm/Makefile | 58 ------- .../11_texture_driver/CMakeLists.txt | 9 +- samples/2_Cookbook/11_texture_driver/Makefile | 41 ----- .../2_Cookbook/13_occupancy/CMakeLists.txt | 9 +- samples/2_Cookbook/13_occupancy/Makefile | 43 ----- samples/2_Cookbook/14_gpu_arch/CMakeLists.txt | 9 +- samples/2_Cookbook/14_gpu_arch/Makefile | 43 ----- .../device_functions/CMakeLists.txt | 9 +- .../device_functions/Makefile | 35 ----- .../host_functions/CMakeLists.txt | 7 - .../15_static_library/host_functions/Makefile | 42 ----- .../16_assembly_to_executable/Makefile | 5 +- .../17_llvm_ir_to_executable/Makefile | 5 +- samples/2_Cookbook/1_hipEvent/CMakeLists.txt | 9 +- samples/2_Cookbook/1_hipEvent/Makefile | 58 ------- .../2_Cookbook/20_hip_vulkan/CMakeLists.txt | 13 +- .../20_hip_vulkan/SineWaveSimulation.hip | 147 ------------------ samples/2_Cookbook/20_hip_vulkan/buildcmd.txt | 14 ++ .../2_Cookbook/3_shared_memory/CMakeLists.txt | 9 +- samples/2_Cookbook/3_shared_memory/Makefile | 60 ------- samples/2_Cookbook/4_shfl/CMakeLists.txt | 9 +- samples/2_Cookbook/4_shfl/Makefile | 63 -------- samples/2_Cookbook/5_2dshfl/CMakeLists.txt | 9 +- samples/2_Cookbook/5_2dshfl/Makefile | 64 -------- .../6_dynamic_shared/CMakeLists.txt | 10 +- samples/2_Cookbook/6_dynamic_shared/Makefile | 60 ------- samples/2_Cookbook/7_streams/CMakeLists.txt | 9 +- samples/2_Cookbook/7_streams/Makefile | 60 ------- samples/2_Cookbook/8_peer2peer/CMakeLists.txt | 9 +- samples/2_Cookbook/8_peer2peer/Makefile | 59 ------- samples/2_Cookbook/9_unroll/CMakeLists.txt | 9 +- samples/2_Cookbook/9_unroll/Makefile | 63 -------- samples/README.md | 11 +- 89 files changed, 184 insertions(+), 1567 deletions(-) delete mode 100644 samples/0_Intro/bit_extract/Makefile delete mode 100644 samples/0_Intro/module_api/Makefile delete mode 100644 samples/0_Intro/module_api_global/Makefile delete mode 100644 samples/0_Intro/square/Makefile delete mode 100644 samples/1_Utils/hipDispatchLatency/Makefile delete mode 100644 samples/1_Utils/hipInfo/Makefile delete mode 100644 samples/2_Cookbook/0_MatrixTranspose/Makefile delete mode 100644 samples/2_Cookbook/10_inline_asm/Makefile delete mode 100644 samples/2_Cookbook/11_texture_driver/Makefile delete mode 100644 samples/2_Cookbook/13_occupancy/Makefile delete mode 100644 samples/2_Cookbook/14_gpu_arch/Makefile delete mode 100644 samples/2_Cookbook/15_static_library/device_functions/Makefile delete mode 100644 samples/2_Cookbook/15_static_library/host_functions/Makefile delete mode 100644 samples/2_Cookbook/1_hipEvent/Makefile delete mode 100644 samples/2_Cookbook/20_hip_vulkan/SineWaveSimulation.hip delete mode 100644 samples/2_Cookbook/3_shared_memory/Makefile delete mode 100644 samples/2_Cookbook/4_shfl/Makefile delete mode 100644 samples/2_Cookbook/5_2dshfl/Makefile delete mode 100644 samples/2_Cookbook/6_dynamic_shared/Makefile delete mode 100644 samples/2_Cookbook/7_streams/Makefile delete mode 100644 samples/2_Cookbook/8_peer2peer/Makefile delete mode 100644 samples/2_Cookbook/9_unroll/Makefile diff --git a/catch/CMakeLists.txt b/catch/CMakeLists.txt index f9078da432..e34f59180d 100644 --- a/catch/CMakeLists.txt +++ b/catch/CMakeLists.txt @@ -9,51 +9,45 @@ project(hiptests) # flag to generate standalone exe per src file. message(STATUS "STANDALONE_TESTS : ${STANDALONE_TESTS}") -# Check if platform and compiler are set -if(HIP_PLATFORM STREQUAL "amd") - if(HIP_COMPILER STREQUAL "nvcc") - message(FATAL_ERROR "Unexpected HIP_COMPILER:${HIP_COMPILER} is set for HIP_PLATFOR:amd") - endif() -elseif(HIP_PLATFORM STREQUAL "nvidia") - if(DEFINED HIP_COMPILER AND NOT HIP_COMPILER STREQUAL "nvcc") - message(FATAL_ERROR "Unexpected HIP_COMPILER: ${HIP_COMPILER} is set for HIP_PLATFORM:nvidia") - endif() -else() +# Check if platform is set +if(NOT HIP_PLATFORM STREQUAL "amd" AND NOT HIP_PLATFORM STREQUAL "nvidia") message(FATAL_ERROR "Unexpected HIP_PLATFORM: " ${HIP_PLATFORM}) endif() -if (WIN32) +if(WIN32) set(EXT ".bat") endif() -# Read -DROCM_Path and env{ROCM_PATH} -if(NOT DEFINED ROCM_PATH) - if(DEFINED ENV{ROCM_PATH}) - set(ROCM_PATH $ENV{ROCM_PATH} CACHE STRING "ROCM Path") +if(HIP_PLATFORM STREQUAL "amd") + if(UNIX AND DEFINED ROCM_PATH) + # Read -DROCM_PATH and set CXX_FLAGS for amd platform only + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --rocm-path=${ROCM_PATH}") + endif() + + if(DEFINED HIP_PATH) + # Read -DHIP_PATH and set CXX_FLAGS for amd platform only + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --hip-path=${HIP_PATH}") + endif() +endif() + +# Read -DHIP_PATH +# If not set read env{HIP_PATH} only on Windows +if(WIN32) + if(NOT DEFINED HIP_PATH) + if(DEFINED ENV{HIP_PATH}) + set(HIP_PATH $ENV{HIP_PATH} CACHE STRING "HIP Path") + endif() endif() endif() -# Read -DHIP_Path and env{HIP_PATH} if(NOT DEFINED HIP_PATH) - if(DEFINED ENV{HIP_PATH}) - set(HIP_PATH $ENV{HIP_PATH} CACHE STRING "HIP Path") - endif() -endif() - -# both are not set -if(NOT DEFINED HIP_PATH AND NOT DEFINED ROCM_PATH) - set(HIP_PATH "/opt/rocm") - set(ROCM_PATH "/opt/rocm") -elseif(DEFINED HIP_PATH AND NOT DEFINED ROCM_PATH) - execute_process(COMMAND ${HIP_PATH}/bin/hipconfig${EXT} --rocmpath - OUTPUT_VARIABLE ROCM_PATH - OUTPUT_STRIP_TRAILING_WHITESPACE) -elseif(DEFINED ROCM_PATH AND NOT DEFINED HIP_PATH) - set(HIP_PATH ${ROCM_PATH}) + if(DEFINED ROCM_PATH) + set(HIP_PATH ${ROCM_PATH}) + else() + set(HIP_PATH "/opt/rocm") + endif() endif() message(STATUS "HIP_PATH: ${HIP_PATH}") -message(STATUS "ROCM_PATH: ${ROCM_PATH}") - set(CMAKE_CXX_COMPILER "${HIP_PATH}/bin/hipcc${EXT}") set(CMAKE_C_COMPILER "${HIP_PATH}/bin/hipcc${EXT}") @@ -62,10 +56,6 @@ execute_process(COMMAND ${HIPCONFIG_EXECUTABLE} --version OUTPUT_VARIABLE HIP_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) -if(HIP_PLATFORM STREQUAL "amd") - # prioritize -DROCM_PATH over env{ROCM_PATH} for amd platform only - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --rocm-path=${ROCM_PATH}") -endif() # enforce c++17 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++17") @@ -155,8 +145,8 @@ if (WIN32) SET(CMAKE_CXX_RESPONSE_FILE_LINK_FLAG "") endif() -if(HIP_PLATFORM MATCHES "amd" AND HIP_COMPILER MATCHES "clang") - add_compile_options(-Wall -Wextra -pedantic -Werror -Wno-deprecated) +if(HIP_PLATFORM STREQUAL "amd") + add_compile_options(-Wall -Wextra -Werror -Wno-deprecated) endif() cmake_policy(PUSH) @@ -178,10 +168,8 @@ message(STATUS "CMAKE HIP ARCHITECTURES: ${CMAKE_HIP_ARCHITECTURES}") # That results in hipcc building the test for gfx803 (the default target) # preference to pass arch - # OFFLOAD_ARCH_STR -# ENV{HCC_AMDGPU_TARGET} # rocm_agent_enumerator if(NOT DEFINED OFFLOAD_ARCH_STR - AND NOT DEFINED ENV{HCC_AMDGPU_TARGET} AND EXISTS "${ROCM_PATH}/bin/rocm_agent_enumerator" AND HIP_PLATFORM STREQUAL "amd" AND UNIX) execute_process(COMMAND ${ROCM_PATH}/bin/rocm_agent_enumerator @@ -208,10 +196,6 @@ endif() if(DEFINED OFFLOAD_ARCH_STR) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OFFLOAD_ARCH_STR} ") -elseif(DEFINED ENV{HCC_AMDGPU_TARGET}) - # hipcc pl script appends it to the options - set(OFFLOAD_ARCH_STR "--offload-arch=$ENV{HCC_AMDGPU_TARGET}") - set(HIP_GPU_ARCH_LIST $ENV{HCC_AMDGPU_TARGET}) endif() message(STATUS "Using offload arch string: ${OFFLOAD_ARCH_STR}") @@ -240,7 +224,7 @@ set(_subdirs ${_autogen} "subdirs(..)\n") file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${CATCH_BUILD_DIR}/CTestTestfile.cmake ${_subdirs}) # Enable device lambda on nvidia platforms -if(HIP_COMPILER MATCHES "nvcc") +if(HIP_PLATFORM STREQUAL "nvidia") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --extended-lambda") endif() diff --git a/catch/README.md b/catch/README.md index 5688f558d4..22a4218766 100644 --- a/catch/README.md +++ b/catch/README.md @@ -11,7 +11,7 @@ Tests in Catch2 are declared via ```TEST_CASE```. [Catch2 Detailed Reference](https://github.com/catchorg/Catch2/blob/v2.13.6/docs/Readme.md#top) ## Taking care of existing features -- Don’t build on platform: EXCLUDE_(HIP_PLATFORM/HIP_RUNTIME), can be done via CMAKE. Adding source in if(HIP_PLATFORM == amd/nvidia). +- Don’t build on platform: EXCLUDE_HIP_PLATFORM, can be done via CMAKE. Adding source in if(HIP_PLATFORM == amd/nvidia). - HIPCC_OPTIONS/CLANG Options: Can be done via: set_source_files_properties(src.cc PROPERTIES COMPILE_FLAGS “…”). - Additional libraries: Can be done via target_link_libraries() - Multiple runs with different args: This can be done by Catch’s Feature: GENERATE(…) diff --git a/catch/include/hip_test_common.hh b/catch/include/hip_test_common.hh index 7b4b08ee38..f5442c5dbb 100644 --- a/catch/include/hip_test_common.hh +++ b/catch/include/hip_test_common.hh @@ -21,6 +21,7 @@ THE SOFTWARE. */ #pragma once +#pragma clang diagnostic ignored "-Wsign-compare" #include "hip_test_context.hh" #include @@ -355,7 +356,7 @@ class BlockingContext { hipStream_t stream; public: - BlockingContext(hipStream_t s) : stream(s), blocked(true) {} + BlockingContext(hipStream_t s) : blocked(true), stream(s) {} BlockingContext(const BlockingContext& in) { blocked = in.blocked_val(); diff --git a/catch/include/memcpy3d_tests_common.hh b/catch/include/memcpy3d_tests_common.hh index 49f09c1e50..c3c7028517 100644 --- a/catch/include/memcpy3d_tests_common.hh +++ b/catch/include/memcpy3d_tests_common.hh @@ -21,7 +21,8 @@ THE SOFTWARE. */ #pragma once - +#pragma clang diagnostic ignored "-Wmissing-field-initializers" +#pragma clang diagnostic ignored "-Wunused-lambda-capture" #include #include @@ -31,7 +32,7 @@ THE SOFTWARE. using PtrVariant = std::variant; -static hipMemcpyKind ReverseMemcpyDirection(const hipMemcpyKind direction) { +static inline hipMemcpyKind ReverseMemcpyDirection(const hipMemcpyKind direction) { switch (direction) { case hipMemcpyHostToDevice: return hipMemcpyDeviceToHost; @@ -76,7 +77,7 @@ static bool operator==(const hipExtent& lhs, const hipExtent& rhs) { return lhs.width == rhs.width && lhs.height == rhs.height && lhs.depth == rhs.depth; } -static bool operator==(const hipMemcpy3DParms& lhs, const hipMemcpy3DParms& rhs) { +static inline bool operator==(const hipMemcpy3DParms& lhs, const hipMemcpy3DParms& rhs) { return lhs.dstArray == rhs.dstArray && lhs.dstPtr == rhs.dstPtr && lhs.dstPos == rhs.dstPos && lhs.srcArray == rhs.srcArray && lhs.srcPtr == rhs.srcPtr && lhs.srcPos == rhs.srcPos && lhs.extent == rhs.extent && lhs.kind == rhs.kind; @@ -168,7 +169,6 @@ void Memcpy3DDeviceToDeviceShell(F memcpy_func, const hipStream_t kernel_stream const auto device_count = HipTest::getDeviceCount(); const auto src_device = GENERATE_COPY(range(0, device_count)); const auto dst_device = GENERATE_COPY(range(0, device_count)); - const size_t src_cols_mult = GENERATE(1, 2); INFO("Src device: " << src_device << ", Dst device: " << dst_device); @@ -797,4 +797,4 @@ void DrvMemcpy3DArrayDeviceShell(F memcpy_func, const hipStream_t kernel_stream }; PitchedMemoryVerify(host_alloc.ptr(), extent.width, extent.width / sizeof(int), extent.height, extent.depth, f); -} \ No newline at end of file +} diff --git a/catch/include/performance_common.hh b/catch/include/performance_common.hh index 9b0c790444..21e87ceb2c 100644 --- a/catch/include/performance_common.hh +++ b/catch/include/performance_common.hh @@ -33,6 +33,9 @@ THE SOFTWARE. #include #include +#pragma clang diagnostic ignored "-Wunused-but-set-variable" +#pragma clang diagnostic ignored "-Wunused-function" + #if defined(_WIN32) #if defined(_WIN64) typedef __int64 ssize_t; diff --git a/catch/multiproc/hipMemCoherencyTstMProc.cc b/catch/multiproc/hipMemCoherencyTstMProc.cc index 6098cf9e4c..8eacc288cf 100644 --- a/catch/multiproc/hipMemCoherencyTstMProc.cc +++ b/catch/multiproc/hipMemCoherencyTstMProc.cc @@ -131,7 +131,6 @@ TEST_CASE("Unit_malloc_CoherentTst") { p = strstr(prop.gcnArchName, "xnack+"); if (p) { // Test Case execution begins from here - int stat = 0; int managed = 0; HIPCHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributeManagedMemory, 0)); @@ -162,7 +161,6 @@ TEST_CASE("Unit_malloc_CoherentTstWthAdvise") { char *p = NULL; p = strstr(prop.gcnArchName, "xnack+"); if (p) { - int stat = 0; int managed = 0; HIP_CHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributeManagedMemory, 0)); @@ -195,7 +193,6 @@ TEST_CASE("Unit_mmap_CoherentTst") { char *p = NULL; p = strstr(prop.gcnArchName, "xnack+"); if (p) { - int stat = 0; int managed = 0; HIP_CHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributeManagedMemory, 0)); @@ -233,7 +230,6 @@ TEST_CASE("Unit_mmap_CoherentTstWthAdvise") { char *p = NULL; p = strstr(prop.gcnArchName, "xnack+"); if (p) { - int stat = 0; int managed = 0; HIP_CHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributeManagedMemory, 0)); diff --git a/catch/unit/cooperativeGrps/coalesced_groups_shfl_down.cc b/catch/unit/cooperativeGrps/coalesced_groups_shfl_down.cc index de13e8eda1..675da24dd5 100644 --- a/catch/unit/cooperativeGrps/coalesced_groups_shfl_down.cc +++ b/catch/unit/cooperativeGrps/coalesced_groups_shfl_down.cc @@ -31,7 +31,7 @@ THE SOFTWARE. #include #include #include - +#pragma clang diagnostic ignored "-Wunused-variable" using namespace cooperative_groups; #define ASSERT_EQUAL(lhs, rhs) assert(lhs == rhs) diff --git a/catch/unit/cooperativeGrps/coalesced_groups_shfl_up.cc b/catch/unit/cooperativeGrps/coalesced_groups_shfl_up.cc index 75ca40a6d7..54cd62c197 100644 --- a/catch/unit/cooperativeGrps/coalesced_groups_shfl_up.cc +++ b/catch/unit/cooperativeGrps/coalesced_groups_shfl_up.cc @@ -30,7 +30,7 @@ THE SOFTWARE. #include #include #include - +#pragma clang diagnostic ignored "-Wunused-variable" using namespace cooperative_groups; #define ASSERT_EQUAL(lhs, rhs) assert(lhs == rhs) @@ -247,4 +247,4 @@ TEST_CASE("Unit_coalesced_groups_shfl_up") { } } -/* Kogge-Stone algorithm */ \ No newline at end of file +/* Kogge-Stone algorithm */ diff --git a/catch/unit/cooperativeGrps/grid_group.cc b/catch/unit/cooperativeGrps/grid_group.cc index ee7402341a..51e1514762 100644 --- a/catch/unit/cooperativeGrps/grid_group.cc +++ b/catch/unit/cooperativeGrps/grid_group.cc @@ -143,7 +143,7 @@ TEST_CASE("Unit_Grid_Group_Getters_Positive_Basic") { HIP_CHECK(hipDeviceSynchronize()); // Verify grid_group.is_valid() values - ArrayAllOf(uint_arr.ptr(), grid.thread_count_, [](uint32_t i) { return 1; }); + ArrayAllOf(uint_arr.ptr(), grid.thread_count_, [](uint32_t) { return 1; }); } /** @@ -282,4 +282,4 @@ TEST_CASE("Unit_Grid_Group_Sync_Positive_Basic") { } REQUIRE(uint_arr.ptr()[i * grid.block_count_ + j] == max_in_this_loop - 1); } -} \ No newline at end of file +} diff --git a/catch/unit/device/getDeviceCount_exe.cc b/catch/unit/device/getDeviceCount_exe.cc index bf9951b6d4..851c0e257d 100644 --- a/catch/unit/device/getDeviceCount_exe.cc +++ b/catch/unit/device/getDeviceCount_exe.cc @@ -34,10 +34,10 @@ bool UNSETENV(std::string var) { return (result == 0) ? true: false; } -bool SETENV(std::string var, std::string value, int overwrite) { +bool SETENV(std::string var, std::string value) { int result = -1; #ifdef __unix__ - result = setenv(var.c_str(), value.c_str(), overwrite); + result = setenv(var.c_str(), value.c_str(), 1); #else result = _putenv((var + '=' + value).c_str()); #endif @@ -59,7 +59,7 @@ int main(int argc, char** argv) { // disable visible_devices env from shell #ifdef __HIP_PLATFORM_NVCC__ UNSETENV("CUDA_VISIBLE_DEVICES"); - SETENV("CUDA_VISIBLE_DEVICES", argv[1], 1); + SETENV("CUDA_VISIBLE_DEVICES", argv[1]); auto init_res = hipInit(0); if (hipSuccess != init_res) { std::cerr << "CUDA INIT API returned : " << hipGetErrorString(init_res) << std::endl; @@ -68,8 +68,8 @@ int main(int argc, char** argv) { #else UNSETENV("ROCR_VISIBLE_DEVICES"); UNSETENV("HIP_VISIBLE_DEVICES"); - SETENV("ROCR_VISIBLE_DEVICES", argv[1], 1); - SETENV("HIP_VISIBLE_DEVICES", argv[1], 1); + SETENV("ROCR_VISIBLE_DEVICES", argv[1]); + SETENV("HIP_VISIBLE_DEVICES", argv[1]); #endif int count = 0; @@ -86,4 +86,4 @@ int main(int argc, char** argv) { UNSETENV("HIP_VISIBLE_DEVICES"); #endif return count; -} \ No newline at end of file +} diff --git a/catch/unit/device/hipDeviceGetP2PAttribute_exe.cc b/catch/unit/device/hipDeviceGetP2PAttribute_exe.cc index 92b1c577f5..22afc7275a 100644 --- a/catch/unit/device/hipDeviceGetP2PAttribute_exe.cc +++ b/catch/unit/device/hipDeviceGetP2PAttribute_exe.cc @@ -32,10 +32,10 @@ bool UNSETENV(std::string var) { return (result == 0) ? true: false; } -bool SETENV(std::string var, std::string value, int overwrite) { +bool SETENV(std::string var, std::string value) { int result = -1; #ifdef __unix__ - result = setenv(var.c_str(), value.c_str(), overwrite); + result = setenv(var.c_str(), value.c_str(), 1); #else result = _putenv((var + '=' + value).c_str()); #endif @@ -44,10 +44,10 @@ bool SETENV(std::string var, std::string value, int overwrite) { void inline hideDevices(const char* devices) { #if HT_NVIDIA - SETENV("CUDA_VISIBLE_DEVICES", devices, 1); + SETENV("CUDA_VISIBLE_DEVICES", devices); #else - SETENV("HIP_VISIBLE_DEVICES", devices, 1); - SETENV("ROCR_VISIBLE_DEVICES", devices, 1); + SETENV("HIP_VISIBLE_DEVICES", devices); + SETENV("ROCR_VISIBLE_DEVICES", devices); #endif } diff --git a/catch/unit/device/hipDeviceGetUuid.cc b/catch/unit/device/hipDeviceGetUuid.cc index d495e9fe94..d02f595673 100644 --- a/catch/unit/device/hipDeviceGetUuid.cc +++ b/catch/unit/device/hipDeviceGetUuid.cc @@ -53,7 +53,7 @@ TEST_CASE("Unit_hipDeviceGetUuid_Positive") { // Atleast one non zero value size_t uuidSize = sizeof(uuid.bytes) / sizeof(uuid.bytes[0]); - for (int i = 0; i < uuidSize; i++) { + for (size_t i = 0; i < uuidSize; i++) { if (uuid.bytes[i] != 0) { uuidValid = true; break; diff --git a/catch/unit/deviceLib/BuiltIns_fadd.cc b/catch/unit/deviceLib/BuiltIns_fadd.cc index 769b0dc97a..5303afb519 100644 --- a/catch/unit/deviceLib/BuiltIns_fadd.cc +++ b/catch/unit/deviceLib/BuiltIns_fadd.cc @@ -198,8 +198,8 @@ TEST_CASE("Unit_BuiltInAtomicAdd_CoherentGlobalMemWithRtc") { void* config_d[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args_f, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, HIP_LAUNCH_PARAM_END}; - hipModuleLaunchKernel(fmaxkernel, 1, 1, 1, 1, 1, 1, 0, - nullptr, nullptr, config_d); + HIP_CHECK(hipModuleLaunchKernel(fmaxkernel, 1, 1, 1, 1, 1, 1, 0, + nullptr, nullptr, config_d)); HIP_CHECK(hipDeviceSynchronize()); HIP_CHECK(hipMemcpy(B_h, result, sizeof(double), hipMemcpyDeviceToHost)); REQUIRE(A_h[0] == INITIAL_VAL); @@ -278,8 +278,8 @@ TEST_CASE("Unit_BuiltInAtomicAdd_NonCoherentGlobalMemWithRtc") { void* config_d[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args_f, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, HIP_LAUNCH_PARAM_END}; - hipModuleLaunchKernel(fmaxkernel, 1, 1, 1, 1, 1, 1, 0, - nullptr, nullptr, config_d); + HIP_CHECK(hipModuleLaunchKernel(fmaxkernel, 1, 1, 1, 1, 1, 1, 0, + nullptr, nullptr, config_d)); HIP_CHECK(hipDeviceSynchronize()); HIP_CHECK(hipMemcpy(B_h, result, sizeof(double), hipMemcpyDeviceToHost)); REQUIRE(A_h[0] == INITIAL_VAL + INC_VAL); diff --git a/catch/unit/deviceLib/BuiltIns_fmax.cc b/catch/unit/deviceLib/BuiltIns_fmax.cc index 9dcddc0596..656d9b419e 100644 --- a/catch/unit/deviceLib/BuiltIns_fmax.cc +++ b/catch/unit/deviceLib/BuiltIns_fmax.cc @@ -229,8 +229,8 @@ TEST_CASE("Unit_BuiltinAtomicsRTC_fmaxCoherentGlobalMem") { void* config_d[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args_f, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, HIP_LAUNCH_PARAM_END}; - hipModuleLaunchKernel(fmaxkernel, 1, 1, 1, 1, 1, 1, 0, - nullptr, nullptr, config_d); + HIP_CHECK(hipModuleLaunchKernel(fmaxkernel, 1, 1, 1, 1, 1, 1, 0, + nullptr, nullptr, config_d)); HIP_CHECK(hipDeviceSynchronize()); HIP_CHECK(hipMemcpy(B_h, result, sizeof(double), hipMemcpyDeviceToHost)); REQUIRE(*B_h == 0); @@ -324,8 +324,8 @@ TEST_CASE("Unit_BuiltinAtomicsRTC_fmaxNonCoherentGlobalFlatMem") { void* config_d[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args_f, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, HIP_LAUNCH_PARAM_END}; - hipModuleLaunchKernel(fmaxkernel, 1, 1, 1, 1, 1, 1, 0, - nullptr, nullptr, config_d); + HIP_CHECK(hipModuleLaunchKernel(fmaxkernel, 1, 1, 1, 1, 1, 1, 0, + nullptr, nullptr, config_d)); HIP_CHECK(hipDeviceSynchronize()); HIP_CHECK(hipMemcpy(B_h, result, sizeof(double), hipMemcpyDeviceToHost)); REQUIRE(*B_h == INITIAL_VAL); diff --git a/catch/unit/deviceLib/BuiltIns_fmin.cc b/catch/unit/deviceLib/BuiltIns_fmin.cc index d669bee9aa..6372888b3f 100644 --- a/catch/unit/deviceLib/BuiltIns_fmin.cc +++ b/catch/unit/deviceLib/BuiltIns_fmin.cc @@ -230,8 +230,8 @@ TEST_CASE("Unit_BuiltinAtomicsRTC__fminCoherentGlobalMem") { void* config_d[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args_f, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, HIP_LAUNCH_PARAM_END}; - hipModuleLaunchKernel(fmaxkernel, 1, 1, 1, 1, 1, 1, 0, - nullptr, nullptr, config_d); + HIP_CHECK(hipModuleLaunchKernel(fmaxkernel, 1, 1, 1, 1, 1, 1, 0, + nullptr, nullptr, config_d)); HIP_CHECK(hipDeviceSynchronize()); HIP_CHECK(hipMemcpy(B_h, result, sizeof(double), hipMemcpyDeviceToHost)); REQUIRE(*B_h == 0); @@ -327,8 +327,8 @@ TEST_CASE("Unit_BuiltinAtomicsRTC_fminNonCoherentGlobalFlatMem") { void* config_d[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args_f, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, HIP_LAUNCH_PARAM_END}; - hipModuleLaunchKernel(fmaxkernel, 1, 1, 1, 1, 1, 1, 0, - nullptr, nullptr, config_d); + HIP_CHECK(hipModuleLaunchKernel(fmaxkernel, 1, 1, 1, 1, 1, 1, 0, + nullptr, nullptr, config_d)); HIP_CHECK(hipDeviceSynchronize()); HIP_CHECK(hipMemcpy(B_h, result, sizeof(double), hipMemcpyDeviceToHost)); REQUIRE(*B_h == INITIAL_VAL); diff --git a/catch/unit/deviceLib/hipStdComplex.cc b/catch/unit/deviceLib/hipStdComplex.cc index f900625d89..c0bafae007 100644 --- a/catch/unit/deviceLib/hipStdComplex.cc +++ b/catch/unit/deviceLib/hipStdComplex.cc @@ -22,6 +22,7 @@ THE SOFTWARE. #include #include +#pragma clang diagnostic ignored "-Wunused-variable" // Tolerance for error const double tolerance = 1e-6; diff --git a/catch/unit/deviceLib/unsafeAtomicAdd_RTC.cc b/catch/unit/deviceLib/unsafeAtomicAdd_RTC.cc index b91d15cf62..6a96dbe32c 100644 --- a/catch/unit/deviceLib/unsafeAtomicAdd_RTC.cc +++ b/catch/unit/deviceLib/unsafeAtomicAdd_RTC.cc @@ -126,8 +126,8 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_CoherentRTCnounsafeatomicflag", "", void* config_d[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args_f, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, HIP_LAUNCH_PARAM_END}; - hipModuleLaunchKernel(f_kernel, 1, 1, 1, 1, 1, 1, 0, - nullptr, nullptr, config_d); + HIP_CHECK(hipModuleLaunchKernel(f_kernel, 1, 1, 1, 1, 1, 1, 0, + nullptr, nullptr, config_d)); HIP_CHECK(hipDeviceSynchronize()); REQUIRE(A_h[0] == INITIAL_VAL); REQUIRE(*result == 0); @@ -218,8 +218,8 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_CoherentRTCunsafeatomicflag", "", void* config_d[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args_f, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, HIP_LAUNCH_PARAM_END}; - hipModuleLaunchKernel(f_kernel, 1, 1, 1, 1, 1, 1, 0, - nullptr, nullptr, config_d); + HIP_CHECK(hipModuleLaunchKernel(f_kernel, 1, 1, 1, 1, 1, 1, 0, + nullptr, nullptr, config_d)); HIP_CHECK(hipDeviceSynchronize()); REQUIRE(A_h[0] == INITIAL_VAL); REQUIRE(*result == 0); @@ -306,8 +306,8 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_CoherentRTCwithoutflag", "", void* config_d[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args_f, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, HIP_LAUNCH_PARAM_END}; - hipModuleLaunchKernel(f_kernel, 1, 1, 1, 1, 1, - 1, 0, nullptr, nullptr, config_d); + HIP_CHECK(hipModuleLaunchKernel(f_kernel, 1, 1, 1, 1, 1, + 1, 0, nullptr, nullptr, config_d)); HIP_CHECK(hipDeviceSynchronize()); REQUIRE(A_h[0] == INITIAL_VAL); REQUIRE(*result == 0); @@ -392,8 +392,8 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_NonCoherentRTCnounsafeatomicflag", "", void* config_d[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args_f, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, HIP_LAUNCH_PARAM_END}; - hipModuleLaunchKernel(f_kernel, 1, 1, 1, 1, 1, 1, 0, - nullptr, nullptr, config_d); + HIP_CHECK(hipModuleLaunchKernel(f_kernel, 1, 1, 1, 1, 1, 1, 0, + nullptr, nullptr, config_d)); HIP_CHECK(hipDeviceSynchronize()); REQUIRE(A_h[0] == INITIAL_VAL + INCREMENT_VAL); REQUIRE(*result == INITIAL_VAL); @@ -480,8 +480,8 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_NonCoherentRTCunsafeatomicflag", "", void* config_d[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args_f, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, HIP_LAUNCH_PARAM_END}; - hipModuleLaunchKernel(f_kernel, 1, 1, 1, 1, 1, 1, 0, - nullptr, nullptr, config_d); + HIP_CHECK(hipModuleLaunchKernel(f_kernel, 1, 1, 1, 1, 1, 1, 0, + nullptr, nullptr, config_d)); HIP_CHECK(hipDeviceSynchronize()); REQUIRE(A_h[0] == INITIAL_VAL + INCREMENT_VAL); REQUIRE(*result == INITIAL_VAL); @@ -568,8 +568,8 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_NonCoherentRTC", "", void* config_d[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args_f, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, HIP_LAUNCH_PARAM_END}; - hipModuleLaunchKernel(f_kernel, 1, 1, 1, 1, 1, 1, 0, - nullptr, nullptr, config_d); + HIP_CHECK(hipModuleLaunchKernel(f_kernel, 1, 1, 1, 1, 1, 1, 0, + nullptr, nullptr, config_d)); HIP_CHECK(hipDeviceSynchronize()); REQUIRE(A_h[0] == INITIAL_VAL + INCREMENT_VAL); REQUIRE(*result == INITIAL_VAL); diff --git a/catch/unit/graph/hipGraphCycle.cc b/catch/unit/graph/hipGraphCycle.cc index dedf4dd558..bb1a7e63ae 100644 --- a/catch/unit/graph/hipGraphCycle.cc +++ b/catch/unit/graph/hipGraphCycle.cc @@ -132,7 +132,6 @@ TEST_CASE("Unit_hipGraph_BasicCyclic4") { HipTest::initArrays(&X_d, &Y_d, nullptr, &X_h, &Y_h, nullptr, N, false); - constexpr size_t memSetVal = 9; hipGraphNode_t kMemCpyH2D_X, memcpyD2D, memcpyD2H_RC, emptyNode1; HIP_CHECK(hipStreamCreate(&stream)); @@ -192,7 +191,6 @@ TEST_CASE("Unit_hipGraph_BasicCyclic5") { HipTest::initArrays(&X_d, &Y_d, nullptr, &X_h, &Y_h, nullptr, N, false); - constexpr size_t memSetVal = 9; hipGraphNode_t kMemCpyH2D_X, memcpyD2D, memcpyD2H_RC, emptyNode1, emptyNode2, emptyNode3; HIP_CHECK(hipStreamCreate(&stream)); @@ -241,4 +239,4 @@ TEST_CASE("Unit_hipGraph_BasicCyclic5") { HIP_CHECK(hipGraphExecDestroy(graphExec)); HIP_CHECK(hipGraphDestroy(graph)); HIP_CHECK(hipStreamDestroy(stream)); -} \ No newline at end of file +} diff --git a/catch/unit/graph/hipStreamBeginCapture.cc b/catch/unit/graph/hipStreamBeginCapture.cc index cc7e85ef5f..9814a05097 100644 --- a/catch/unit/graph/hipStreamBeginCapture.cc +++ b/catch/unit/graph/hipStreamBeginCapture.cc @@ -22,6 +22,7 @@ THE SOFTWARE. #include #include "stream_capture_common.hh" // NOLINT +#pragma clang diagnostic ignored "-Wunused-variable" /** * @addtogroup hipStreamBeginCapture hipStreamBeginCapture * @{ diff --git a/catch/unit/graph/user_object_common.hh b/catch/unit/graph/user_object_common.hh index 1929199b43..d649e3e746 100644 --- a/catch/unit/graph/user_object_common.hh +++ b/catch/unit/graph/user_object_common.hh @@ -24,6 +24,8 @@ THE SOFTWARE. #include +#pragma clang diagnostic ignored "-Wunused-function" + struct BoxStruct { int count; BoxStruct() { INFO("Constructor called for Struct!\n"); } @@ -58,4 +60,4 @@ void destroyFloatObj(void* ptr) { delete ptr2; } -} // anonymous namespace \ No newline at end of file +} // anonymous namespace diff --git a/catch/unit/kernel/hipShflTests.cc b/catch/unit/kernel/hipShflTests.cc index 711a8d1744..89c529c16b 100644 --- a/catch/unit/kernel/hipShflTests.cc +++ b/catch/unit/kernel/hipShflTests.cc @@ -150,7 +150,6 @@ static void runTest() { // verify the results REQUIRE(errors == compare(TransposeMatrix, cpuTransposeMatrix)); - double eps = 1.0E-6; // free the resources on device side HIP_CHECK(hipFree(gpuMatrix)); HIP_CHECK(hipFree(gpuTransposeMatrix)); diff --git a/catch/unit/memory/hipArrayCommon.hh b/catch/unit/memory/hipArrayCommon.hh index b19a32a206..52ade2ea21 100644 --- a/catch/unit/memory/hipArrayCommon.hh +++ b/catch/unit/memory/hipArrayCommon.hh @@ -43,12 +43,7 @@ __global__ void readFromTexture(T* output, hipTextureObject_t texObj, size_t wid } else { const float v = y / (float)height; if (textureGather) { - // tex2Dgather not supported on __gfx90a__ - #if !defined(__gfx90a__) output[y * width + x] = tex2Dgather(texObj, u, v, ChannelToRead); - #else - #warning("tex2Dgather not supported on gfx90a"); - #endif } else { output[y * width + x] = tex2D(texObj, u, v); } diff --git a/catch/unit/memory/hipArrayCreate.cc b/catch/unit/memory/hipArrayCreate.cc index a22386070b..b6058c8176 100644 --- a/catch/unit/memory/hipArrayCreate.cc +++ b/catch/unit/memory/hipArrayCreate.cc @@ -54,7 +54,7 @@ static void ArrayCreate_DiffSizes(int gpu) { std::vector> runs {std::make_pair(NUM_W, NUM_H), std::make_pair(BIGNUM_W, BIGNUM_H)}; for (const auto& size : runs) { std::array array; - size_t pavail, avail; + size_t pavail; HIP_CHECK_THREAD(hipMemGetInfo(&pavail, nullptr)); HIP_ARRAY_DESCRIPTOR desc; desc.NumChannels = 1; diff --git a/catch/unit/memory/hipFreeAsync.cc b/catch/unit/memory/hipFreeAsync.cc index 6962189655..c7fcd0b179 100644 --- a/catch/unit/memory/hipFreeAsync.cc +++ b/catch/unit/memory/hipFreeAsync.cc @@ -26,7 +26,7 @@ TEST_CASE("Unit_hipFreeAsync_negative") { HIP_CHECK(hipSetDevice(0)); void* p = nullptr; hipStream_t stream{nullptr}; - hipStreamCreate(&stream); + HIP_CHECK(hipStreamCreate(&stream)); SECTION("dev_ptr is nullptr") { REQUIRE(hipFreeAsync(nullptr, stream) != hipSuccess); } diff --git a/catch/unit/memory/hipMalloc3D.cc b/catch/unit/memory/hipMalloc3D.cc index 7e0e249bee..47dae81522 100644 --- a/catch/unit/memory/hipMalloc3D.cc +++ b/catch/unit/memory/hipMalloc3D.cc @@ -43,7 +43,7 @@ static void MemoryAlloc3DDiffSizes(int gpu) { size_t height{sizes}, depth{sizes}; hipPitchedPtr devPitchedPtr[CHUNK_LOOP]; hipExtent extent = make_hipExtent(width, height, depth); - size_t tot, avail, ptot, pavail; + size_t ptot, pavail; HIPCHECK(hipMemGetInfo(&pavail, &ptot)); for (int i = 0; i < CHUNK_LOOP; i++) { HIPCHECK(hipMalloc3D(&devPitchedPtr[i], extent)); diff --git a/catch/unit/memory/hipMallocArray.cc b/catch/unit/memory/hipMallocArray.cc index 1ea94d2146..14a095f6fd 100644 --- a/catch/unit/memory/hipMallocArray.cc +++ b/catch/unit/memory/hipMallocArray.cc @@ -399,12 +399,22 @@ TEMPLATE_TEST_CASE("Unit_hipMallocArray_happy", "", uint, int, int4, ushort, sho testArrayAsSurface(arrayPtr, width, height); } SECTION("hipArrayTextureGather") { - height = 1024; - INFO("flag is hipArrayTextureGather"); - INFO("height: " << height); + hipDeviceProp_t prop; + int device; + HIP_CHECK(hipGetDevice(&device)); + HIP_CHECK(hipGetDeviceProperties(&prop, device)); + // tex2Dgather not supported on gfx90a + if (std::string(prop.gcnArchName).find("gfx90a") == std::string::npos) { + height = 1024; + INFO("flag is hipArrayTextureGather"); + INFO("height: " << height); - HIP_CHECK(hipMallocArray(&arrayPtr, &desc, width, height, hipArrayTextureGather)); - testArrayAsTextureWithGather(arrayPtr, width, height); + HIP_CHECK(hipMallocArray(&arrayPtr, &desc, width, height, hipArrayTextureGather)); + testArrayAsTextureWithGather(arrayPtr, width, height); + } else { + SUCCEED("tex2Dgather is not supported for gfx90a, Hence" + "skipping the testcase for this device " << device); + } } #endif diff --git a/catch/unit/memory/hipMallocConcurrency.cc b/catch/unit/memory/hipMallocConcurrency.cc index 17028d232d..6481885f2e 100644 --- a/catch/unit/memory/hipMallocConcurrency.cc +++ b/catch/unit/memory/hipMallocConcurrency.cc @@ -82,7 +82,7 @@ static std::atomic g_thTestPassed{true}; /** * Validates data consistency on supplied gpu */ -static bool validateMemoryOnGPU(int gpu, bool concurOnOneGPU = false) { +static bool validateMemoryOnGPU(int gpu) { int *A_d, *B_d, *C_d; int *A_h, *B_h, *C_h; bool TestPassed = true; @@ -148,7 +148,7 @@ static bool regressAllocInLoop(int gpu) { * Validates data consistency on supplied gpu * In Multithreaded Environment */ -static bool validateMemoryOnGpuMThread(int gpu, bool concurOnOneGPU = false) { +static bool validateMemoryOnGpuMThread(int gpu) { int *A_d, *B_d, *C_d; int *A_h, *B_h, *C_h; bool TestPassed = true; @@ -213,7 +213,7 @@ static bool regressAllocInLoopMthread(int gpu) { * Thread func to regress alloc and check data consistency */ static void threadFunc(int gpu) { - g_thTestPassed = regressAllocInLoopMthread(gpu) && validateMemoryOnGpuMThread(gpu, true); + g_thTestPassed = regressAllocInLoopMthread(gpu) && validateMemoryOnGpuMThread(gpu); UNSCOPED_INFO("thread execution status on gpu" << gpu << ":" << g_thTestPassed.load()); } diff --git a/catch/unit/memory/hipMemAdviseMmap.cc b/catch/unit/memory/hipMemAdviseMmap.cc index f7f4db3fcc..044f2099cf 100644 --- a/catch/unit/memory/hipMemAdviseMmap.cc +++ b/catch/unit/memory/hipMemAdviseMmap.cc @@ -31,7 +31,7 @@ THE SOFTWARE. */ TEST_CASE("Unit_hipMemAdvise_MmapMem") { - int managed = 0, NUM_ELMS = 212992, PageableMem = 0; + int managed = 0, PageableMem = 0; INFO("The following are the attribute values related to HMM for" " device 0:\n"); HIP_CHECK(hipDeviceGetAttribute(&managed, @@ -54,6 +54,7 @@ TEST_CASE("Unit_hipMemAdvise_MmapMem") { #ifdef __linux__ // For now this test is enabled only for linux platforms FILE *fptr; + int NUM_ELMS = 212992; fptr = fopen("ForTest1.txt", "w"); for (int m = 0; m < NUM_ELMS; ++m) { putw(m, fptr); diff --git a/catch/unit/memory/hipMemAdvise_old.cc b/catch/unit/memory/hipMemAdvise_old.cc index 62dcb81627..b69e46af7b 100644 --- a/catch/unit/memory/hipMemAdvise_old.cc +++ b/catch/unit/memory/hipMemAdvise_old.cc @@ -666,7 +666,6 @@ TEST_CASE("Unit_hipMemAdvise_TstAlignedAllocMem") { std::string gfxName(prop.gcnArchName); if (gfxName.find("xnack+") != std::string::npos) { - int stat = 0; int managedMem = 0, pageMemAccess = 0; HIP_CHECK(hipDeviceGetAttribute(&pageMemAccess, hipDeviceAttributePageableMemoryAccess, 0)); diff --git a/catch/unit/memory/hipMemRangeGetAttributes_old.cc b/catch/unit/memory/hipMemRangeGetAttributes_old.cc index e1240f4330..63952f1bfd 100644 --- a/catch/unit/memory/hipMemRangeGetAttributes_old.cc +++ b/catch/unit/memory/hipMemRangeGetAttributes_old.cc @@ -26,6 +26,7 @@ THE SOFTWARE. #include #define MEM_SIZE 8192 +#ifdef __linux__ static bool CheckError(hipError_t err, int LineNo) { if (err == hipSuccess) { WARN("Error expected but received hipSuccess at line no.:" @@ -59,7 +60,6 @@ static int HmmAttrPrint() { return managed; } -#ifdef __linux__ /* Test Scenario: Testing basic working of hipMemRangeGetAttributes() api with different flags */ diff --git a/catch/unit/memory/hipMemcpy3D.cc b/catch/unit/memory/hipMemcpy3D.cc index 5ca6373308..79b9d0f90f 100644 --- a/catch/unit/memory/hipMemcpy3D.cc +++ b/catch/unit/memory/hipMemcpy3D.cc @@ -28,6 +28,8 @@ THE SOFTWARE. #include #include +#pragma clang diagnostic ignored "-Wunused-variable" + TEST_CASE("Unit_hipMemcpy3D_Positive_Basic") { constexpr bool async = false; diff --git a/catch/unit/memory/hipMemcpy3DAsync.cc b/catch/unit/memory/hipMemcpy3DAsync.cc index 4689c12dec..d346bdcac5 100644 --- a/catch/unit/memory/hipMemcpy3DAsync.cc +++ b/catch/unit/memory/hipMemcpy3DAsync.cc @@ -28,6 +28,8 @@ THE SOFTWARE. #include #include +#pragma clang diagnostic ignored "-Wunused-variable" + TEST_CASE("Unit_hipMemcpy3DAsync_Positive_Basic") { constexpr bool async = true; diff --git a/catch/unit/rtc/linker.cc b/catch/unit/rtc/linker.cc index 8733487ccf..151980b24c 100644 --- a/catch/unit/rtc/linker.cc +++ b/catch/unit/rtc/linker.cc @@ -11,8 +11,7 @@ #include #include -static constexpr auto NUM_THREADS{128}; -static constexpr auto NUM_BLOCKS{32}; +#pragma clang diagnostic ignored "-Wuninitialized" static constexpr auto src{ R"( @@ -125,4 +124,4 @@ TEST_CASE("Unit_RTC_LinkerAPI") { for (size_t i = 0; i < n; ++i) { REQUIRE(fabs(a * hX[i] + hY[i] - hOut[i]) <= fabs(hOut[i]) * 1e-6); } -} \ No newline at end of file +} diff --git a/catch/unit/stream/hipStreamCreateWithPriority.cc b/catch/unit/stream/hipStreamCreateWithPriority.cc index 9bc8bb32bf..ee3b723c7e 100644 --- a/catch/unit/stream/hipStreamCreateWithPriority.cc +++ b/catch/unit/stream/hipStreamCreateWithPriority.cc @@ -686,8 +686,8 @@ void TestForMultipleStreamWithPriority(void) { } // launch kernels repeatedly on each of the low prioritiy stream for (int k = 0; k < LOW_PRIORITY_STREAMCOUNT; ++k) { - for (int i = 0; i < size; i += MEMCPYSIZE1) { - int j = i / sizeof(T); + for (size_t i = 0; i < size; i += MEMCPYSIZE1) { + size_t j = i / sizeof(T); if (enable_priority_low) { hipLaunchKernelGGL((memcpy_kernel), dim3(GRIDSIZE), dim3(BLOCKSIZE), 0, stream_low[k], dst_d_low[k] + j, src_d_low[k] + j, @@ -697,8 +697,8 @@ void TestForMultipleStreamWithPriority(void) { } // launch kernels repeatedly on each of the normal prioritiy stream for (int k = 0; k < NORMAL_PRIORITY_STREAMCOUNT; ++k) { - for (int i = 0; i < size; i += MEMCPYSIZE1) { - int j = i / sizeof(T); + for (size_t i = 0; i < size; i += MEMCPYSIZE1) { + size_t j = i / sizeof(T); if (enable_priority_normal) { hipLaunchKernelGGL((memcpy_kernel), dim3(GRIDSIZE), dim3(BLOCKSIZE), 0, stream_normal[k], dst_d_normal[k] + j, src_d_normal[k] + j, @@ -708,8 +708,8 @@ void TestForMultipleStreamWithPriority(void) { } // launch kernels repeatedly on each of the high prioritiy stream for (int k = 0; k < HIGH_PRIORITY_STREAMCOUNT; ++k) { - for (int i = 0; i < size; i += MEMCPYSIZE1) { - int j = i / sizeof(T); + for (size_t i = 0; i < size; i += MEMCPYSIZE1) { + size_t j = i / sizeof(T); if (enable_priority_high) { hipLaunchKernelGGL((memcpy_kernel), dim3(GRIDSIZE), dim3(BLOCKSIZE), 0, stream_high[k], dst_d_high[k] + j, src_d_high[k] + j, diff --git a/catch/unit/surface/hipSurfaceObj1D.cc b/catch/unit/surface/hipSurfaceObj1D.cc index 5068e770b6..e8a59f30a0 100644 --- a/catch/unit/surface/hipSurfaceObj1D.cc +++ b/catch/unit/surface/hipSurfaceObj1D.cc @@ -19,7 +19,7 @@ THE SOFTWARE. #include #include #include - +#pragma clang diagnostic ignored "-Wunused-variable" template __global__ void surf1DKernelR(hipSurfaceObject_t surfaceObject, diff --git a/catch/unit/surface/hipSurfaceObj2D.cc b/catch/unit/surface/hipSurfaceObj2D.cc index 22f143e7df..725f949a20 100644 --- a/catch/unit/surface/hipSurfaceObj2D.cc +++ b/catch/unit/surface/hipSurfaceObj2D.cc @@ -19,7 +19,7 @@ THE SOFTWARE. #include #include #include - +#pragma clang diagnostic ignored "-Wunused-variable" #define LOG_DATA 0 template diff --git a/catch/unit/surface/hipSurfaceObj3D.cc b/catch/unit/surface/hipSurfaceObj3D.cc index 804cc5fb81..cb62de3524 100644 --- a/catch/unit/surface/hipSurfaceObj3D.cc +++ b/catch/unit/surface/hipSurfaceObj3D.cc @@ -19,7 +19,7 @@ THE SOFTWARE. #include #include #include - +#pragma clang diagnostic ignored "-Wunused-variable" template __global__ void surf3DKernelR(hipSurfaceObject_t surfaceObject, diff --git a/catch/unit/texture/hipTextureMipmapObj2D.cc b/catch/unit/texture/hipTextureMipmapObj2D.cc index 7c55e6103e..2b70c13c9f 100644 --- a/catch/unit/texture/hipTextureMipmapObj2D.cc +++ b/catch/unit/texture/hipTextureMipmapObj2D.cc @@ -98,7 +98,7 @@ static void runMipMapTest(unsigned int width, unsigned int height, unsigned int hipLaunchKernelGGL(tex2DKernel, dim3(dimGrid), dim3(dimBlock), 0, 0, dData, textureObject, width, (2 * mipmap_level)); HIP_CHECK(hipGetLastError()); - hipDeviceSynchronize(); + HIP_CHECK(hipDeviceSynchronize()); float* hOutputData = reinterpret_cast(malloc(size)); REQUIRE(hOutputData != nullptr); diff --git a/catch/unit/texture/hipTextureObjFetchVector.cc b/catch/unit/texture/hipTextureObjFetchVector.cc index d31e5fbd7f..7aa2fc8b37 100644 --- a/catch/unit/texture/hipTextureObjFetchVector.cc +++ b/catch/unit/texture/hipTextureObjFetchVector.cc @@ -21,7 +21,7 @@ THE SOFTWARE. #include #include #include - +#pragma clang diagnostic ignored "-Wunused-variable" template __global__ void tex1dKernelFetch(T *val, hipTextureObject_t obj, int N) { #if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT @@ -79,7 +79,7 @@ bool runTest() { // Allocating the required buffer on gpu device T *texBuf, *texBufOut; T val[N], output[N]; - hipGetLastError(); // Clear err due to negative tests + auto err = hipGetLastError(); // Clear err due to negative tests memset(output, 0, sizeof(output)); std::srand(std::time(nullptr)); // use current time as seed for random generator diff --git a/samples/0_Intro/bit_extract/CMakeLists.txt b/samples/0_Intro/bit_extract/CMakeLists.txt index 4986dc1b1f..148f0b2904 100644 --- a/samples/0_Intro/bit_extract/CMakeLists.txt +++ b/samples/0_Intro/bit_extract/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -26,17 +26,10 @@ if(NOT WIN32 AND NOT DEFINED __HIP_ENABLE_PCH) set(__HIP_ENABLE_PCH ON CACHE BOOL "enable/disable pre-compiled hip headers") endif() -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - if(${__HIP_ENABLE_PCH}) add_definitions(-D__HIP_ENABLE_PCH) endif() -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # Find hip find_package(hip) diff --git a/samples/0_Intro/bit_extract/Makefile b/samples/0_Intro/bit_extract/Makefile deleted file mode 100644 index 939aca00a5..0000000000 --- a/samples/0_Intro/bit_extract/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright (c) 2016 - 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 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. - -#Dependencies : [MYHIP]/bin must be in user's path. -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif -HIP_PLATFORM=$(shell $(HIP_PATH)/bin/hipconfig --platform) -HIPCC=$(HIP_PATH)/bin/hipcc -INCLUDES := -I../../common - -# Show how to use PLATFORM to specify different options for each compiler: -ifeq (${HIP_PLATFORM}, nvcc) - HIPCC_FLAGS = -gencode=arch=compute_20,code=sm_20 -endif - -EXE=bit_extract - -$(EXE): bit_extract.cpp - $(HIPCC) $(HIPCC_FLAGS) $(INCLUDES) $< -o $@ - -all: $(EXE) - -clean: - rm -f *.o $(EXE) diff --git a/samples/0_Intro/bit_extract/README.md b/samples/0_Intro/bit_extract/README.md index 69995721b0..abf829d75d 100644 --- a/samples/0_Intro/bit_extract/README.md +++ b/samples/0_Intro/bit_extract/README.md @@ -1,6 +1,6 @@ # bit_extract Show an application written directly in HIP which uses platform-specific check on __HIP_PLATFORM_AMD__ to enable use of -an instruction that only exists on the HCC platform. +an instruction that only exists on the AMD platform. See related [blog](http://gpuopen.com/platform-aware-coding-inside-hip/) demonstrating platform specialization. diff --git a/samples/0_Intro/module_api/CMakeLists.txt b/samples/0_Intro/module_api/CMakeLists.txt index 7106df44c0..264304d31d 100644 --- a/samples/0_Intro/module_api/CMakeLists.txt +++ b/samples/0_Intro/module_api/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -23,14 +23,6 @@ project(module_api) cmake_minimum_required(VERSION 3.10) include_directories(../../common) - -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # Find hip find_package(hip) diff --git a/samples/0_Intro/module_api/Makefile b/samples/0_Intro/module_api/Makefile deleted file mode 100644 index ee3e68e067..0000000000 --- a/samples/0_Intro/module_api/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright (c) 2016 - 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 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. -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif -HIPCC=$(HIP_PATH)/bin/hipcc -HIP_PLATFORM=$(shell $(HIP_PATH)/bin/hipconfig --compiler) -INCLUDES := -I../../common - -all: vcpy_kernel.code runKernel.hip.out launchKernelHcc.hip.out defaultDriver.hip.out - -runKernel.hip.out: runKernel.cpp - $(HIPCC) $(HIPCC_FLAGS) $(INCLUDES) $< -o $@ - -launchKernelHcc.hip.out: launchKernelHcc.cpp - $(HIPCC) $(HIPCC_FLAGS) $(INCLUDES) $< -o $@ - -defaultDriver.hip.out: defaultDriver.cpp - $(HIPCC) $(HIPCC_FLAGS) $(INCLUDES) $< -o $@ - -vcpy_kernel.code: vcpy_kernel.cpp - $(HIPCC) --genco $(GENCO_FLAGS) $(INCLUDES) $^ -o $@ - -clean: - rm -f *.code *.out diff --git a/samples/0_Intro/module_api_global/CMakeLists.txt b/samples/0_Intro/module_api_global/CMakeLists.txt index 186a99d164..0f22e25e82 100644 --- a/samples/0_Intro/module_api_global/CMakeLists.txt +++ b/samples/0_Intro/module_api_global/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -18,17 +18,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -project(modile_api_global) +project(module_api_global) cmake_minimum_required(VERSION 3.10) -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # Find hip find_package(hip) @@ -53,4 +46,4 @@ add_dependencies(runKernel.hip.out codeobj) target_include_directories(runKernel.hip.out PRIVATE ../../common) # Link with HIP -target_link_libraries(runKernel.hip.out hip::host) \ No newline at end of file +target_link_libraries(runKernel.hip.out hip::host) diff --git a/samples/0_Intro/module_api_global/Makefile b/samples/0_Intro/module_api_global/Makefile deleted file mode 100644 index 732eec63aa..0000000000 --- a/samples/0_Intro/module_api_global/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (c) 2017 - 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 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. -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif -HIPCC=$(HIP_PATH)/bin/hipcc -HIP_PLATFORM=$(shell $(HIP_PATH)/bin/hipconfig --compiler) -INCLUDES := -I../../common - -all: vcpy_kernel.code runKernel.hip.out - -runKernel.hip.out: runKernel.cpp - $(HIPCC) $(HIPCC_FLAGS) $(INCLUDES) $< -o $@ - -vcpy_kernel.code: vcpy_kernel.cpp - $(HIPCC) --genco $(GENCO_FLAGS) $^ -o $@ - -clean: - rm -f *.code *.out diff --git a/samples/0_Intro/square/CMakeLists.txt b/samples/0_Intro/square/CMakeLists.txt index 104f828698..7ff5848efd 100644 --- a/samples/0_Intro/square/CMakeLists.txt +++ b/samples/0_Intro/square/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -24,15 +24,8 @@ project(square) cmake_minimum_required(VERSION 3.10) -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # create square.cpp -execute_process(COMMAND sh -c "${ROCM_PATH}/hip/bin/hipify-perl ../square.cu > ../square.cpp") +execute_process(COMMAND sh -c "${CMAKE_PREFIX_PATH}/hip/bin/hipify-perl ../square.cu > ../square.cpp") # Find hip find_package(hip) @@ -45,4 +38,4 @@ set(CMAKE_CXX_LINKER ${HIP_HIPCC_EXECUTABLE}) add_executable(square square.cpp) # Link with HIP -target_link_libraries(square hip::host) \ No newline at end of file +target_link_libraries(square hip::host) diff --git a/samples/0_Intro/square/Makefile b/samples/0_Intro/square/Makefile deleted file mode 100644 index 83a37326ad..0000000000 --- a/samples/0_Intro/square/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright (c) 2016 - 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 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. -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif -HIP_PLATFORM=$(shell $(HIP_PATH)/bin/hipconfig --platform) -HIPCC=$(HIP_PATH)/bin/hipcc - -ifeq (${HIP_PLATFORM}, nvidia) - SOURCES=square.cu -else - SOURCES=square.cpp -endif - -all: square.out - -# Step -square.cpp: square.cu - $(HIP_PATH)/bin/hipify-perl square.cu > square.cpp - -square.out: $(SOURCES) - $(HIPCC) $(CXXFLAGS) $(SOURCES) -o $@ - -clean: - rm -f *.o *.out square.cpp diff --git a/samples/0_Intro/square/README.md b/samples/0_Intro/square/README.md index 807f08754e..5644184ee7 100644 --- a/samples/0_Intro/square/README.md +++ b/samples/0_Intro/square/README.md @@ -14,11 +14,16 @@ $ export PATH=$PATH:[MYHIP]/bin $ export HIP_PATH=[MYHIP] ``` -- Build executible file +- Build executable file ``` $ cd ~/hip/samples/0_Intro/square -$ make + mkdir -p build && cd build + + cmake -DCMAKE_PREFIX_PATH= -DHIP_CXX_COMPILER= .. + make + +$ Building without cmake /opt/rocm/hip/bin/hipify-perl square.cu > square.cpp /opt/rocm/hip/bin/hipcc square.cpp -o square.out /opt/rocm/hip/bin/hipcc -use-staticlib square.cpp -o square.out.static diff --git a/samples/1_Utils/hipDispatchLatency/CMakeLists.txt b/samples/1_Utils/hipDispatchLatency/CMakeLists.txt index 33caab73b7..61c5f22b8a 100644 --- a/samples/1_Utils/hipDispatchLatency/CMakeLists.txt +++ b/samples/1_Utils/hipDispatchLatency/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -23,14 +23,6 @@ project(hipDispatchLatency) cmake_minimum_required(VERSION 3.10) include_directories(../../common) - -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # Find hip find_package(hip) diff --git a/samples/1_Utils/hipDispatchLatency/Makefile b/samples/1_Utils/hipDispatchLatency/Makefile deleted file mode 100644 index 6643e3f034..0000000000 --- a/samples/1_Utils/hipDispatchLatency/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright (c) 2016 - 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 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. -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif -HIPCC=$(HIP_PATH)/bin/hipcc -std=c++11 -INCLUDES := -I../../common - -CXXFLAGS = -O3 $(INCLUDES) - -all: test_kernel.code hipDispatchLatency.out hipDispatchEnqueueRateMT.out - -hipDispatchLatency.out: hipDispatchLatency.cpp - $(HIPCC) $(CXXFLAGS) hipDispatchLatency.cpp -o $@ - -hipDispatchEnqueueRateMT.out: hipDispatchEnqueueRateMT.cpp - $(HIPCC) $(CXXFLAGS) hipDispatchEnqueueRateMT.cpp -lpthread -o $@ - -test_kernel.code: test_kernel.cpp - $(HIP_PATH)/bin/hipcc --genco $(GENCO_FLAGS) $^ -o $@ -clean: - rm -f *.o *.out diff --git a/samples/1_Utils/hipInfo/CMakeLists.txt b/samples/1_Utils/hipInfo/CMakeLists.txt index 60cf123282..63bf4f7175 100644 --- a/samples/1_Utils/hipInfo/CMakeLists.txt +++ b/samples/1_Utils/hipInfo/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -30,17 +30,10 @@ cmake_minimum_required(VERSION 3.10) # flag is set to ON in compute build for windows option(HIPINFO_INTERNAL_BUILD "Enable building hipInfo from compute" OFF) -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # need to set rocm_path for windows # since clang and hip are two different folders during build/install step if (WIN32 AND HIPINFO_INTERNAL_BUILD) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --rocm-path=${HIP_PATH}") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --rocm-path=${CMAKE_PREFIX_PATH}") endif() # Find hip diff --git a/samples/1_Utils/hipInfo/Makefile b/samples/1_Utils/hipInfo/Makefile deleted file mode 100644 index c5bc1a9c74..0000000000 --- a/samples/1_Utils/hipInfo/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2016 - 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 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. -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif -HIPCC=$(HIP_PATH)/bin/hipcc -INCLUDES := -I../../common - -EXE=hipInfo - -all: install - -$(EXE): hipInfo.cpp - $(HIPCC) hipInfo.cpp $(INCLUDES) -o $@ - -install: $(EXE) - cp $(EXE) $(HIP_PATH)/bin - - -clean: - rm -f *.o $(EXE) diff --git a/samples/2_Cookbook/0_MatrixTranspose/CMakeLists.txt b/samples/2_Cookbook/0_MatrixTranspose/CMakeLists.txt index 015e6a047e..a396bbc0c5 100644 --- a/samples/2_Cookbook/0_MatrixTranspose/CMakeLists.txt +++ b/samples/2_Cookbook/0_MatrixTranspose/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -22,13 +22,6 @@ project(MatrixTranspose) cmake_minimum_required(VERSION 3.10) -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # Find hip find_package(hip) diff --git a/samples/2_Cookbook/0_MatrixTranspose/Makefile b/samples/2_Cookbook/0_MatrixTranspose/Makefile deleted file mode 100644 index 308efa6dc6..0000000000 --- a/samples/2_Cookbook/0_MatrixTranspose/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (c) 2016 - 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 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. -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif - -HIPCC=$(HIP_PATH)/bin/hipcc - -TARGET=hcc - -INCLUDES := -I../../common -SOURCES = MatrixTranspose.cpp -OBJECTS = $(SOURCES:.cpp=.o) - -EXECUTABLE=./MatrixTranspose - -.PHONY: test - - -all: $(EXECUTABLE) test - -CXXFLAGS =-g $(INCLUDES) -CXX=$(HIPCC) - - -$(EXECUTABLE): $(OBJECTS) - $(HIPCC) $(OBJECTS) -o $@ - - -test: $(EXECUTABLE) - $(EXECUTABLE) - - -clean: - rm -f $(EXECUTABLE) - rm -f $(OBJECTS) - rm -f $(HIP_PATH)/src/*.o - diff --git a/samples/2_Cookbook/10_inline_asm/CMakeLists.txt b/samples/2_Cookbook/10_inline_asm/CMakeLists.txt index f20827df3f..712ea216bc 100644 --- a/samples/2_Cookbook/10_inline_asm/CMakeLists.txt +++ b/samples/2_Cookbook/10_inline_asm/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -22,13 +22,6 @@ project(inline_asm) cmake_minimum_required(VERSION 3.10) -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # Find hip find_package(hip) diff --git a/samples/2_Cookbook/10_inline_asm/Makefile b/samples/2_Cookbook/10_inline_asm/Makefile deleted file mode 100644 index 31928eb2dc..0000000000 --- a/samples/2_Cookbook/10_inline_asm/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (c) 2017 - 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 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. -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif - -HIPCC=$(HIP_PATH)/bin/hipcc - -TARGET=hcc - -SOURCES = inline_asm.cpp -OBJECTS = $(SOURCES:.cpp=.o) -INCLUDES := -I../../common -EXECUTABLE=./inline_asm - -.PHONY: test - - -all: $(EXECUTABLE) test - -CXXFLAGS =-g $(INCLUDES) -CXX=$(HIPCC) - - -$(EXECUTABLE): $(OBJECTS) - $(HIPCC) $(OBJECTS) -o $@ - - -test: $(EXECUTABLE) - $(EXECUTABLE) - - -clean: - rm -f $(EXECUTABLE) - rm -f $(OBJECTS) - diff --git a/samples/2_Cookbook/11_texture_driver/CMakeLists.txt b/samples/2_Cookbook/11_texture_driver/CMakeLists.txt index 55aa40b2a6..a11422877c 100644 --- a/samples/2_Cookbook/11_texture_driver/CMakeLists.txt +++ b/samples/2_Cookbook/11_texture_driver/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -22,13 +22,6 @@ project(texture2dDrv) cmake_minimum_required(VERSION 3.10) -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # Find hip find_package(hip) diff --git a/samples/2_Cookbook/11_texture_driver/Makefile b/samples/2_Cookbook/11_texture_driver/Makefile deleted file mode 100644 index 25737ea2e2..0000000000 --- a/samples/2_Cookbook/11_texture_driver/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (c) 2017 - 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 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. -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif -HIPCC=$(HIP_PATH)/bin/hipcc -HIP_PLATFORM=$(shell $(HIP_PATH)/bin/hipconfig --compiler) -INCLUDES := -I../../common - -all: tex2dKernel.code texture2dDrv.out - -texture2dDrv.out: texture2dDrv.cpp - $(HIPCC) $(HIPCC_FLAGS) $(INCLUDES) $< -o $@ - -tex2dKernel.code: tex2dKernel.cpp - $(HIPCC) --genco $(GENCO_FLAGS) $^ -o $@ - -clean: - rm -f *.code *.out diff --git a/samples/2_Cookbook/13_occupancy/CMakeLists.txt b/samples/2_Cookbook/13_occupancy/CMakeLists.txt index 44d0303068..c0ec339d1e 100644 --- a/samples/2_Cookbook/13_occupancy/CMakeLists.txt +++ b/samples/2_Cookbook/13_occupancy/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -22,13 +22,6 @@ project(occupancy) cmake_minimum_required(VERSION 3.10) -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # Find hip find_package(hip) diff --git a/samples/2_Cookbook/13_occupancy/Makefile b/samples/2_Cookbook/13_occupancy/Makefile deleted file mode 100644 index dd4037418f..0000000000 --- a/samples/2_Cookbook/13_occupancy/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# 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 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. -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif -HIPCC=$(HIP_PATH)/bin/hipcc -INCLUDES := -I../../common -EXE=./occupancy - -.PHONY: test - -all: test - -$(EXE): occupancy.cpp - $(HIPCC) $(INCLUDES) $^ -o $@ - -test: $(EXE) - $(EXE) - -clean: - rm -f *.o $(EXE) diff --git a/samples/2_Cookbook/14_gpu_arch/CMakeLists.txt b/samples/2_Cookbook/14_gpu_arch/CMakeLists.txt index 91354b11cc..5a2a426db6 100644 --- a/samples/2_Cookbook/14_gpu_arch/CMakeLists.txt +++ b/samples/2_Cookbook/14_gpu_arch/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -22,13 +22,6 @@ project(gpuarch) cmake_minimum_required(VERSION 3.10) -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # Find hip find_package(hip) diff --git a/samples/2_Cookbook/14_gpu_arch/Makefile b/samples/2_Cookbook/14_gpu_arch/Makefile deleted file mode 100644 index a3b1115780..0000000000 --- a/samples/2_Cookbook/14_gpu_arch/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2020 - 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 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. -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif -HIPCC=$(HIP_PATH)/bin/hipcc -INCLUDES := -I../../common -EXE=./gpuarch - -.PHONY: test - -all: test - -$(EXE): gpuarch.cpp - $(HIPCC) $(INCLUDES) $^ -o $@ - -test: $(EXE) - $(EXE) - -clean: - rm -f *.o $(EXE) diff --git a/samples/2_Cookbook/15_static_library/device_functions/CMakeLists.txt b/samples/2_Cookbook/15_static_library/device_functions/CMakeLists.txt index 317b7a819e..98bde53e1c 100644 --- a/samples/2_Cookbook/15_static_library/device_functions/CMakeLists.txt +++ b/samples/2_Cookbook/15_static_library/device_functions/CMakeLists.txt @@ -2,13 +2,6 @@ project(static_lib) cmake_minimum_required(VERSION 3.10) -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # Find hip find_package(hip REQUIRED) @@ -38,7 +31,7 @@ add_library(HipDevice STATIC ${CPP_SOURCES}) target_compile_options(HipDevice PRIVATE -fgpu-rdc) target_link_libraries(HipDevice PRIVATE -fgpu-rdc) -target_include_directories(HipDevice PRIVATE ${ROCM_PATH}/hsa/include) +target_include_directories(HipDevice PRIVATE ${CMAKE_PREFIX_PATH}/hsa/include) # Create test executable that uses libHipDevice.a set(TEST_SOURCES ${CMAKE_SOURCE_DIR}/hipMain2.cpp) diff --git a/samples/2_Cookbook/15_static_library/device_functions/Makefile b/samples/2_Cookbook/15_static_library/device_functions/Makefile deleted file mode 100644 index aaf7abb3c6..0000000000 --- a/samples/2_Cookbook/15_static_library/device_functions/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif - -HIPCC=$(HIP_PATH)/bin/hipcc - -.PHONY: test - -all: $(RDC_EXE) test - -STATIC_LIB_SRC=hipDevice.cpp -STATIC_LIB=./libHipDevice.a -STATIC_MAIN_SRC=hipMain2.cpp -RDC_EXE=./test_device_static.out - -$(STATIC_LIB): - $(HIPCC) $(STATIC_LIB_SRC) -c -fgpu-rdc -fPIC -o hipDevice.o - ar rcsD $@ hipDevice.o - -# Compiles hipMain2 with hipcc and links with libHipDevice.a which contains device function. -$(RDC_EXE): $(STATIC_LIB) - $(HIPCC) $(STATIC_LIB) $(STATIC_MAIN_SRC) -fgpu-rdc -o $@ - -test: $(RDC_EXE) - $(RDC_EXE) - -clean: - rm -f $(RDC_EXE) - rm -f $(STATIC_LIB) - rm -f *.o diff --git a/samples/2_Cookbook/15_static_library/host_functions/CMakeLists.txt b/samples/2_Cookbook/15_static_library/host_functions/CMakeLists.txt index 8404ac58b2..4f5af10a01 100644 --- a/samples/2_Cookbook/15_static_library/host_functions/CMakeLists.txt +++ b/samples/2_Cookbook/15_static_library/host_functions/CMakeLists.txt @@ -2,13 +2,6 @@ project(static_lib) cmake_minimum_required(VERSION 3.10) -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # Find hip find_package(hip REQUIRED) diff --git a/samples/2_Cookbook/15_static_library/host_functions/Makefile b/samples/2_Cookbook/15_static_library/host_functions/Makefile deleted file mode 100644 index e6daa41da6..0000000000 --- a/samples/2_Cookbook/15_static_library/host_functions/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif - -HIPCC=$(HIP_PATH)/bin/hipcc -GXX=g++ - -EMIT_STATIC_LIB_SRC=hipOptLibrary.cpp -EMIT_STATIC_LIB=./libHipOptLibrary.a -EMIT_STATIC_MAIN_SRC=hipMain1.cpp -HIPCC_EXE=./test_emit_static_hipcc_linker.out -HOST_EXE=./test_emit_static_host_linker.out - -.PHONY: test - -all: $(HIPCC_EXE) $(HOST_EXE) test - -$(EMIT_STATIC_LIB): - $(HIPCC) $(EMIT_STATIC_LIB_SRC) --emit-static-lib -fPIC -o $@ - -# Compiles hipMain1 with hipcc and links with libHipOptLibrary.a which contains host function. -$(HIPCC_EXE): $(EMIT_STATIC_LIB) - $(HIPCC) $(EMIT_STATIC_MAIN_SRC) -L. -lHipOptLibrary -o $@ - -# Compiles hipMain1 with g++ and links with libHipOptLibrary.a which contains host function. -$(HOST_EXE): $(EMIT_STATIC_LIB) - $(GXX) $(EMIT_STATIC_MAIN_SRC) -L. -lHipOptLibrary -L$(HIP_PATH)/lib -lamdhip64 -Wl,-rpath=$(HIP_PATH)/lib -o $@ - -test: $(HIPCC_EXE) $(HOST_EXE) - $(HIPCC_EXE) - $(HOST_EXE) - -clean: - rm -f $(HIPCC_EXE) - rm -f $(HOST_EXE) - rm -f $(EMIT_STATIC_LIB) - rm -f *.o diff --git a/samples/2_Cookbook/16_assembly_to_executable/Makefile b/samples/2_Cookbook/16_assembly_to_executable/Makefile index e0615b84dd..bc1f6ee341 100644 --- a/samples/2_Cookbook/16_assembly_to_executable/Makefile +++ b/samples/2_Cookbook/16_assembly_to_executable/Makefile @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -22,9 +22,6 @@ ifeq ($(OS),Windows_NT) endif ROCM_PATH?= $(wildcard /opt/rocm/) HIP_PATH?= $(ROCM_PATH) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif HIPCC=$(HIP_PATH)/bin/hipcc CLANG=$(HIP_PATH)/llvm/bin/clang diff --git a/samples/2_Cookbook/17_llvm_ir_to_executable/Makefile b/samples/2_Cookbook/17_llvm_ir_to_executable/Makefile index eef1f6ff9f..330ad23c60 100644 --- a/samples/2_Cookbook/17_llvm_ir_to_executable/Makefile +++ b/samples/2_Cookbook/17_llvm_ir_to_executable/Makefile @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -22,9 +22,6 @@ ifeq ($(OS),Windows_NT) endif ROCM_PATH?= $(wildcard /opt/rocm/) HIP_PATH?= $(ROCM_PATH) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif HIPCC=$(HIP_PATH)/bin/hipcc CLANG=$(HIP_PATH)/llvm/bin/clang diff --git a/samples/2_Cookbook/1_hipEvent/CMakeLists.txt b/samples/2_Cookbook/1_hipEvent/CMakeLists.txt index 562d8e9c7f..b709921162 100644 --- a/samples/2_Cookbook/1_hipEvent/CMakeLists.txt +++ b/samples/2_Cookbook/1_hipEvent/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -22,13 +22,6 @@ project(hipEvent) cmake_minimum_required(VERSION 3.10) -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # Find hip find_package(hip) diff --git a/samples/2_Cookbook/1_hipEvent/Makefile b/samples/2_Cookbook/1_hipEvent/Makefile deleted file mode 100644 index 09d1cf923e..0000000000 --- a/samples/2_Cookbook/1_hipEvent/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (c) 2016 - 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 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. - -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif - -HIPCC=$(HIP_PATH)/bin/hipcc - -TARGET=hcc - -SOURCES = hipEvent.cpp -OBJECTS = $(SOURCES:.cpp=.o) -INCLUDES := -I../../common - -EXECUTABLE=./hipEvent - -.PHONY: test - - -all: $(EXECUTABLE) test - -CXXFLAGS =-g $(INCLUDES) -CXX=$(HIPCC) - - -$(EXECUTABLE): $(OBJECTS) - $(HIPCC) $(OBJECTS) -o $@ - - -test: $(EXECUTABLE) - $(EXECUTABLE) - - -clean: - rm -f $(EXECUTABLE) - rm -f $(OBJECTS) - rm -f $(HIP_PATH)/src/*.o - diff --git a/samples/2_Cookbook/20_hip_vulkan/CMakeLists.txt b/samples/2_Cookbook/20_hip_vulkan/CMakeLists.txt index 288c47c3d2..55918d5a6a 100644 --- a/samples/2_Cookbook/20_hip_vulkan/CMakeLists.txt +++ b/samples/2_Cookbook/20_hip_vulkan/CMakeLists.txt @@ -1,5 +1,5 @@ -# Copyright (c) 2020 - 2022 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -29,17 +29,10 @@ project(hipVulkan) cmake_minimum_required(VERSION 3.10) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake;${CMAKE_MODULE_PATH}") -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # need to set rocm_path for windows # since clang and hip are two different folders during build/install step if (WIN32 AND HIPINFO_INTERNAL_BUILD) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --rocm-path=${HIP_PATH}") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --rocm-path=${CMAKE_PREFIX_PATH}") endif() @@ -85,7 +78,7 @@ set(CMAKE_BUILD_TYPE Release) # Create the excutable add_executable(hipVulkan VulkanBaseApp.cpp VulkanBaseApp.h main.cpp SineWaveSimulation.cpp SineWaveSimulation.h linmath.h) -include_directories(${HIP_PATH}/include) +include_directories(${CMAKE_PREFIX_PATH}/include) include_directories(${GLFW_PATH}/include) # Link with HIP diff --git a/samples/2_Cookbook/20_hip_vulkan/SineWaveSimulation.hip b/samples/2_Cookbook/20_hip_vulkan/SineWaveSimulation.hip deleted file mode 100644 index 41adae8065..0000000000 --- a/samples/2_Cookbook/20_hip_vulkan/SineWaveSimulation.hip +++ /dev/null @@ -1,147 +0,0 @@ -/* Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of NVIDIA CORPORATION nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Modifications Copyright (C)2021 Advanced - * Micro Devices, Inc. All rights reserved. - */ - -#include "SineWaveSimulation.h" -#include -//#include -#include "hip/hip_runtime.h" - - -__global__ void sinewave(float *heightMap, unsigned int width, unsigned int height, float time) -{ - const float freq = 4.0f; - const size_t stride = gridDim.x * blockDim.x; - - // Iterate through the entire array in a way that is - // independent of the grid configuration - for (size_t tid = blockIdx.x * blockDim.x + threadIdx.x; tid < width * height; tid += stride) { - // Calculate the x, y coordinates - const size_t y = tid / width; - const size_t x = tid - y * width; - // Normalize x, y to [0,1] - const float u = ((2.0f * x) / width) - 1.0f; - const float v = ((2.0f * y) / height) - 1.0f; - // Calculate the new height value - const float w = 0.5f * sinf(u * freq + time) * cosf(v * freq + time); - // Store this new height value - heightMap[tid] = w; - } -} - -SineWaveSimulation::SineWaveSimulation(size_t width, size_t height) - : m_heightMap(nullptr), m_width(width), m_height(height) -{ -} - -void SineWaveSimulation::initCudaLaunchConfig(int device) -{ - hipDeviceProp_t prop = {}; - checkHIPErrors(hipSetDevice(device)); - checkHIPErrors(hipGetDeviceProperties(&prop, device)); - - // We don't need large block sizes, since there's not much inter-thread communication - m_threads = prop.warpSize; - - // Use the occupancy calculator and fill the gpu as best as we can - checkHIPErrors(hipOccupancyMaxActiveBlocksPerMultiprocessor(&m_blocks, sinewave, prop.warpSize, 0)); - m_blocks *= prop.multiProcessorCount; - - // Go ahead and the clamp the blocks to the minimum needed for this height/width - m_blocks = std::min(m_blocks, (int)((m_width * m_height + m_threads - 1) / m_threads)); -} - -int SineWaveSimulation::initCuda(uint8_t *vkDeviceUUID, size_t UUID_SIZE) -{ - int current_device = 0; - int device_count = 0; - int devices_prohibited = 0; - - hipDeviceProp_t deviceProp; - checkHIPErrors(hipGetDeviceCount(&device_count)); - - if (device_count == 0) { - fprintf(stderr, "CUDA error: no devices supporting CUDA.\n"); - exit(EXIT_FAILURE); - } - - // Find the GPU which is selected by Vulkan - while (current_device < device_count) { - hipGetDeviceProperties(&deviceProp, current_device); - - if ((deviceProp.computeMode != hipComputeModeProhibited)) { - // Compare the cuda device UUID with vulkan UUID - // FIXME - int ret = 0; // memcmp((void*)&deviceProp.uuid, vkDeviceUUID, UUID_SIZE); - if (ret == 0) - { - checkHIPErrors(hipSetDevice(current_device)); - checkHIPErrors(hipGetDeviceProperties(&deviceProp, current_device)); - printf("GPU Device %d: \"%s\" with compute capability %d.%d\n\n", - current_device, deviceProp.name, deviceProp.major, - deviceProp.minor); - - return current_device; - } - - } else { - devices_prohibited++; - } - - current_device++; - } - - if (devices_prohibited == device_count) { - fprintf(stderr, - "HIP error:" - " No Vulkan-HIP Interop capable GPU found.\n"); - exit(EXIT_FAILURE); - } - - return -1; -} - -SineWaveSimulation::~SineWaveSimulation() -{ - m_heightMap = NULL; -} - -void SineWaveSimulation::initSimulation(float *heights) -{ - m_heightMap = heights; -} - -void SineWaveSimulation::stepSimulation(float time, hipStream_t stream) -{ - hipLaunchKernelGGL(sinewave, dim3(m_blocks), dim3(m_threads), 0, stream , m_heightMap, m_width, m_height, time); - getLastHIPError("Failed to launch CUDA simulation"); - //hipStreamSynchronize(stream); -} diff --git a/samples/2_Cookbook/20_hip_vulkan/buildcmd.txt b/samples/2_Cookbook/20_hip_vulkan/buildcmd.txt index 791466ec42..6f476b68bf 100644 --- a/samples/2_Cookbook/20_hip_vulkan/buildcmd.txt +++ b/samples/2_Cookbook/20_hip_vulkan/buildcmd.txt @@ -1,3 +1,5 @@ +Windows +-------- • Install hip and visual studio • Install vulkan sdk from vulkan.lunarg.com • Download GLFW binaries from glfw.org @@ -14,3 +16,15 @@ to build with cmake on windows: • mkdir build; cd build • cmake.exe -GNinja -DCMAKE_CXX_COMPILER_ID=ROCMClang -DCMAKE_C_COMPILER_ID=ROCMClang -DCMAKE_PREFIX_PATH=d:\driver2\drivers\drivers\compute\hip_sdk +Linux +------ +• Ideally, vulkan should be picked up by cmake from the location where it is installed. eg: /usr/lib +• If a specific version of vulkan is needed, install vulkan sdk from vulkan.lunarg.com following the steps +• To run this sample, connect to the machine where display is enabled using NoMachine app + +Build with CMake: +• mkdir build; cd build +• cmake -DCMAKE_PREFIX_PATH=path\to\rocm -DHIP_CXX_COMPILER=path\to\clang +• make +• run hipVulkan executable + diff --git a/samples/2_Cookbook/3_shared_memory/CMakeLists.txt b/samples/2_Cookbook/3_shared_memory/CMakeLists.txt index bab322511d..d1d87dccb2 100644 --- a/samples/2_Cookbook/3_shared_memory/CMakeLists.txt +++ b/samples/2_Cookbook/3_shared_memory/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -22,13 +22,6 @@ project(sharedMemory) cmake_minimum_required(VERSION 3.10) -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # Find hip find_package(hip) diff --git a/samples/2_Cookbook/3_shared_memory/Makefile b/samples/2_Cookbook/3_shared_memory/Makefile deleted file mode 100644 index c8571cf21f..0000000000 --- a/samples/2_Cookbook/3_shared_memory/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (c) 2016 - 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 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. -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif - -HIPCC=$(HIP_PATH)/bin/hipcc - -TARGET=hcc - -SOURCES = sharedMemory.cpp -OBJECTS = $(SOURCES:.cpp=.o) -INCLUDES := -I../../common - -EXECUTABLE=./sharedMemory - -.PHONY: test - - -all: $(EXECUTABLE) test - -CXXFLAGS =-g $(INCLUDES) -CXX=$(HIPCC) - - -$(EXECUTABLE): $(OBJECTS) - $(HIPCC) $(OBJECTS) -o $@ - - -test: $(EXECUTABLE) - $(EXECUTABLE) - - -clean: - rm -f $(EXECUTABLE) - rm -f $(OBJECTS) - rm -f $(HIP_PATH)/src/*.o - diff --git a/samples/2_Cookbook/4_shfl/CMakeLists.txt b/samples/2_Cookbook/4_shfl/CMakeLists.txt index d1e8a4843f..e80ed36501 100644 --- a/samples/2_Cookbook/4_shfl/CMakeLists.txt +++ b/samples/2_Cookbook/4_shfl/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -22,13 +22,6 @@ project(shfl) cmake_minimum_required(VERSION 3.10) -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # Find hip find_package(hip) diff --git a/samples/2_Cookbook/4_shfl/Makefile b/samples/2_Cookbook/4_shfl/Makefile deleted file mode 100644 index 6305ad10e0..0000000000 --- a/samples/2_Cookbook/4_shfl/Makefile +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright (c) 2016 - 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 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. -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif - -ifeq (gfx701, $(findstring gfx701,$(HCC_AMDGPU_TARGET))) - $(error gfx701 is not a supported device for this sample) -endif - -HIPCC=$(HIP_PATH)/bin/hipcc - -TARGET=hcc - -SOURCES = shfl.cpp -OBJECTS = $(SOURCES:.cpp=.o) -INCLUDES := -I../../common - -EXECUTABLE=./shfl - -.PHONY: test - - -all: $(EXECUTABLE) test - -CXXFLAGS =-g $(INCLUDES) -CXX=$(HIPCC) - - -$(EXECUTABLE): $(OBJECTS) - $(HIPCC) $(OBJECTS) -o $@ - - -test: $(EXECUTABLE) - $(EXECUTABLE) - - -clean: - rm -f $(EXECUTABLE) - rm -f $(OBJECTS) - rm -f $(HIP_PATH)/src/*.o diff --git a/samples/2_Cookbook/5_2dshfl/CMakeLists.txt b/samples/2_Cookbook/5_2dshfl/CMakeLists.txt index 80fa6e08b3..942f17fc8d 100644 --- a/samples/2_Cookbook/5_2dshfl/CMakeLists.txt +++ b/samples/2_Cookbook/5_2dshfl/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -22,13 +22,6 @@ project(2dshfl) cmake_minimum_required(VERSION 3.10) -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # Find hip find_package(hip) diff --git a/samples/2_Cookbook/5_2dshfl/Makefile b/samples/2_Cookbook/5_2dshfl/Makefile deleted file mode 100644 index 116d38057a..0000000000 --- a/samples/2_Cookbook/5_2dshfl/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright (c) 2016 - 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 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. -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif - -ifeq (gfx701, $(findstring gfx701,$(HCC_AMDGPU_TARGET))) - $(error gfx701 is not a supported device for this sample) -endif - -HIPCC=$(HIP_PATH)/bin/hipcc - -TARGET=hcc - -SOURCES = 2dshfl.cpp -OBJECTS = $(SOURCES:.cpp=.o) -INCLUDES := -I../../common - -EXECUTABLE=./2dshfl - -.PHONY: test - - -all: $(EXECUTABLE) test - -CXXFLAGS =-g $(INCLUDES) -CXX=$(HIPCC) - - -$(EXECUTABLE): $(OBJECTS) - $(HIPCC) $(OBJECTS) -o $@ - - -test: $(EXECUTABLE) - $(EXECUTABLE) - - -clean: - rm -f $(EXECUTABLE) - rm -f $(OBJECTS) - rm -f $(HIP_PATH)/src/*.o - diff --git a/samples/2_Cookbook/6_dynamic_shared/CMakeLists.txt b/samples/2_Cookbook/6_dynamic_shared/CMakeLists.txt index cb90fb6b74..02bbe70ae6 100644 --- a/samples/2_Cookbook/6_dynamic_shared/CMakeLists.txt +++ b/samples/2_Cookbook/6_dynamic_shared/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -23,14 +23,6 @@ project(dynamic_shared) cmake_minimum_required(VERSION 3.10) include_directories(../../common) - -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # Find hip find_package(hip) diff --git a/samples/2_Cookbook/6_dynamic_shared/Makefile b/samples/2_Cookbook/6_dynamic_shared/Makefile deleted file mode 100644 index 8db78af246..0000000000 --- a/samples/2_Cookbook/6_dynamic_shared/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (c) 2016 - 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 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. -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif - -HIPCC=$(HIP_PATH)/bin/hipcc - -TARGET=hcc - -SOURCES = dynamic_shared.cpp -OBJECTS = $(SOURCES:.cpp=.o) -INCLUDES := -I../../common - -EXECUTABLE=./dynamic_shared - -.PHONY: test - - -all: $(EXECUTABLE) test - -CXXFLAGS =-g $(INCLUDES) -CXX=$(HIPCC) - - -$(EXECUTABLE): $(OBJECTS) - $(HIPCC) $(OBJECTS) -o $@ - - -test: $(EXECUTABLE) - $(EXECUTABLE) - - -clean: - rm -f $(EXECUTABLE) - rm -f $(OBJECTS) - rm -f $(HIP_PATH)/src/*.o - diff --git a/samples/2_Cookbook/7_streams/CMakeLists.txt b/samples/2_Cookbook/7_streams/CMakeLists.txt index e1133da770..04bec0b422 100644 --- a/samples/2_Cookbook/7_streams/CMakeLists.txt +++ b/samples/2_Cookbook/7_streams/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -22,13 +22,6 @@ project(stream) cmake_minimum_required(VERSION 3.10) -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # Find hip find_package(hip) diff --git a/samples/2_Cookbook/7_streams/Makefile b/samples/2_Cookbook/7_streams/Makefile deleted file mode 100644 index e55d9c8191..0000000000 --- a/samples/2_Cookbook/7_streams/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (c) 2016 - 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 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. -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif - -HIPCC=$(HIP_PATH)/bin/hipcc - -TARGET=hcc - -SOURCES = stream.cpp -OBJECTS = $(SOURCES:.cpp=.o) -INCLUDES := -I../../common - -EXECUTABLE=./stream - -.PHONY: test - - -all: $(EXECUTABLE) test - -CXXFLAGS =-g $(INCLUDES) -CXX=$(HIPCC) - - -$(EXECUTABLE): $(OBJECTS) - $(HIPCC) $(OBJECTS) -o $@ - - -test: $(EXECUTABLE) - $(EXECUTABLE) - - -clean: - rm -f $(EXECUTABLE) - rm -f $(OBJECTS) - rm -f $(HIP_PATH)/src/*.o - diff --git a/samples/2_Cookbook/8_peer2peer/CMakeLists.txt b/samples/2_Cookbook/8_peer2peer/CMakeLists.txt index ad34ee44df..7d66525389 100644 --- a/samples/2_Cookbook/8_peer2peer/CMakeLists.txt +++ b/samples/2_Cookbook/8_peer2peer/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -22,13 +22,6 @@ project(peer2peer) cmake_minimum_required(VERSION 3.10) -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # Find hip find_package(hip) diff --git a/samples/2_Cookbook/8_peer2peer/Makefile b/samples/2_Cookbook/8_peer2peer/Makefile deleted file mode 100644 index 4112c75696..0000000000 --- a/samples/2_Cookbook/8_peer2peer/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (c) 2016 - 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 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. -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif - -HIPCC=$(HIP_PATH)/bin/hipcc - -TARGET=hcc - -SOURCES = peer2peer.cpp -OBJECTS = $(SOURCES:.cpp=.o) - -EXECUTABLE=./peer2peer - -.PHONY: test - - -all: $(EXECUTABLE) test - -CXXFLAGS =-g -CXX=$(HIPCC) - - -$(EXECUTABLE): $(OBJECTS) - $(HIPCC) $(OBJECTS) -o $@ - - -test: $(EXECUTABLE) - $(EXECUTABLE) - - -clean: - rm -f $(EXECUTABLE) - rm -f $(OBJECTS) - rm -f $(HIP_PATH)/src/*.o - diff --git a/samples/2_Cookbook/9_unroll/CMakeLists.txt b/samples/2_Cookbook/9_unroll/CMakeLists.txt index 070f66fe23..dfc34b641b 100644 --- a/samples/2_Cookbook/9_unroll/CMakeLists.txt +++ b/samples/2_Cookbook/9_unroll/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All Rights Reserved. +# Copyright (c) 2020 - 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 @@ -22,13 +22,6 @@ project(unroll) cmake_minimum_required(VERSION 3.10) -if (NOT DEFINED ROCM_PATH ) - set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) -endif () - -# Search for rocm in common locations -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) - # Find hip find_package(hip) diff --git a/samples/2_Cookbook/9_unroll/Makefile b/samples/2_Cookbook/9_unroll/Makefile deleted file mode 100644 index 49bf51ece1..0000000000 --- a/samples/2_Cookbook/9_unroll/Makefile +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright (c) 2017 - 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 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. -ifeq ($(OS),Windows_NT) - $(error Makefile is not supported on windows platform. Please use cmake instead to build sample.) -endif -ROCM_PATH?= $(wildcard /opt/rocm/) -HIP_PATH?= $(wildcard $(ROCM_PATH)/hip) -ifeq (,$(HIP_PATH)) - HIP_PATH=../../.. -endif - -ifeq (gfx701, $(findstring gfx701,$(HCC_AMDGPU_TARGET))) - $(error gfx701 is not a supported device for this sample) -endif - -HIPCC=$(HIP_PATH)/bin/hipcc - -TARGET=hcc - -SOURCES = unroll.cpp -OBJECTS = $(SOURCES:.cpp=.o) -INCLUDES := -I../../common - -EXECUTABLE=./unroll - -.PHONY: test - - -all: $(EXECUTABLE) test - -CXXFLAGS =-g $(INCLUDES) -CXX=$(HIPCC) - - -$(EXECUTABLE): $(OBJECTS) - $(HIPCC) $(OBJECTS) -o $@ - - -test: $(EXECUTABLE) - $(EXECUTABLE) - - -clean: - rm -f $(EXECUTABLE) - rm -f $(OBJECTS) - rm -f $(HIP_PATH)/src/*.o diff --git a/samples/README.md b/samples/README.md index 8f0551bf91..a5184a6ee9 100644 --- a/samples/README.md +++ b/samples/README.md @@ -12,6 +12,7 @@ make 2.CMakeLists.txt can support shared and static libs of hip-rocclr runtime. +The same steps can be followed for both. To build a sample, run in the sample folder, @@ -19,15 +20,7 @@ mkdir -p build && cd build rm -rf * (to clear up) -a. to build with shared libs, run - -cmake .. - -make - -b. to build with static libs, run - -cmake -DCMAKE_PREFIX_PATH="/llvm/lib/cmake" .. +cmake -DCMAKE_PREFIX_PATH= -DHIP_CXX_COMPILER= .. Then run, From 9c24abc77b8e6d1a4b1c79405ab3321232d887b9 Mon Sep 17 00:00:00 2001 From: Satyanvesh Dittakavi <53337087+satyanveshd@users.noreply.github.com> Date: Mon, 14 Aug 2023 12:07:05 +0530 Subject: [PATCH 02/30] SWDEV-395996 - Disable hiprtc tests temporarily (#379) --- .../config/config_amd_linux_MI2xx.json | 12 +++++++++++- .../config/config_amd_linux_common.json | 13 ++++++++++++- .../config/config_amd_windows_MI2xx.json | 16 +++++++++++++--- .../config/config_amd_windows_common.json | 12 +++++++++++- 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/catch/hipTestMain/config/config_amd_linux_MI2xx.json b/catch/hipTestMain/config/config_amd_linux_MI2xx.json index f1a914fa6c..74b6c2bf4a 100644 --- a/catch/hipTestMain/config/config_amd_linux_MI2xx.json +++ b/catch/hipTestMain/config/config_amd_linux_MI2xx.json @@ -17,7 +17,17 @@ "Unit_hipSignalExternalSemaphoresAsync_Vulkan_Negative_Parameters", "Unit_hipImportExternalSemaphore_Vulkan_Negative_Parameters", "Unit_hipDestroyExternalSemaphore_Vulkan_Negative_Parameters", - "Unit_Grid_Group_Sync_Positive_Basic" + "Unit_Grid_Group_Sync_Positive_Basic", + "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", + "Unit_hiprtc_saxpy.Unit_hiprtc_saxpy", + "Unit_hiprtc_warpsize.Unit_hiprtc_warpsize", + "Unit_hiprtc_functional.Unit_hiprtc_functional", + "Unit_hipStreamCaptureRtc.Unit_hipStreamCaptureRtc", + "Unit_hiprtc_cpp17.Unit_hiprtc_cpp17", + "Unit_hiprtc_namehandling.Unit_hiprtc_namehandling", + "Unit_hiprtc_getloweredname.Unit_hiprtc_getloweredname", + "Unit_hiprtc_test_hip_bfloat16.Unit_hiprtc_test_hip_bfloat16", + "Unit_RTC_LinkerAPI.Unit_RTC_LinkerAPI" ] } diff --git a/catch/hipTestMain/config/config_amd_linux_common.json b/catch/hipTestMain/config/config_amd_linux_common.json index e6b83d620a..940eed28fc 100644 --- a/catch/hipTestMain/config/config_amd_linux_common.json +++ b/catch/hipTestMain/config/config_amd_linux_common.json @@ -113,6 +113,17 @@ "Unit_hipStreamValue_Wait32_Blocking_Mask_Eq_1", "=== Below tests fail in stress test on 24/07/23 ===", "Unit_hipStreamCreateWithPriority_ValidateWithEvents", - "Unit_hipEventIpc" + "Unit_hipEventIpc", + "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", + "Unit_hiprtc_saxpy.Unit_hiprtc_saxpy", + "Unit_hiprtc_warpsize.Unit_hiprtc_warpsize", + "Unit_hiprtc_functional.Unit_hiprtc_functional", + "Unit_hipStreamCaptureRtc.Unit_hipStreamCaptureRtc", + "Unit_hiprtc_cpp17.Unit_hiprtc_cpp17", + "Unit_hiprtc_namehandling.Unit_hiprtc_namehandling", + "Unit_hiprtc_getloweredname.Unit_hiprtc_getloweredname", + "Unit_hiprtc_test_hip_bfloat16.Unit_hiprtc_test_hip_bfloat16", + "Unit_RTC_LinkerAPI.Unit_RTC_LinkerAPI" + ] } diff --git a/catch/hipTestMain/config/config_amd_windows_MI2xx.json b/catch/hipTestMain/config/config_amd_windows_MI2xx.json index 7df6d38d78..f5d29920e0 100644 --- a/catch/hipTestMain/config/config_amd_windows_MI2xx.json +++ b/catch/hipTestMain/config/config_amd_windows_MI2xx.json @@ -93,10 +93,20 @@ "Unit_hipInit_Negative", "Unit_hipGraphAddEventRecordNode_Functional_ElapsedTime", "Unit_hipStreamBeginCapture_captureComplexGraph", - "Unit_hipGraphAddChildGraphNode_MultGraphsAsSingleGraph" - "Unit_hipMemGetAddressRange_Negative", + "Unit_hipGraphAddChildGraphNode_MultGraphsAsSingleGraph", + "Unit_hipMemGetAddressRange_Negative", "Unit_hipStreamValue_Wait64_Blocking_NoMask_Nor", "Unit_hipLaunchHostFunc_Graph", - "Unit_hipLaunchHostFunc_KernelHost" + "Unit_hipLaunchHostFunc_KernelHost", + "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", + "Unit_hiprtc_saxpy.Unit_hiprtc_saxpy", + "Unit_hiprtc_warpsize.Unit_hiprtc_warpsize", + "Unit_hiprtc_functional.Unit_hiprtc_functional", + "Unit_hipStreamCaptureRtc.Unit_hipStreamCaptureRtc", + "Unit_hiprtc_cpp17.Unit_hiprtc_cpp17", + "Unit_hiprtc_namehandling.Unit_hiprtc_namehandling", + "Unit_hiprtc_getloweredname.Unit_hiprtc_getloweredname", + "Unit_hiprtc_test_hip_bfloat16.Unit_hiprtc_test_hip_bfloat16", + "Unit_RTC_LinkerAPI.Unit_RTC_LinkerAPI" ] } diff --git a/catch/hipTestMain/config/config_amd_windows_common.json b/catch/hipTestMain/config/config_amd_windows_common.json index 372ae2bdca..141d5a35e0 100644 --- a/catch/hipTestMain/config/config_amd_windows_common.json +++ b/catch/hipTestMain/config/config_amd_windows_common.json @@ -211,6 +211,16 @@ "Unit_hipMemcpyAsync_Negative_Parameters", "Unit_hipMemcpyDtoHAsync_Negative_Parameters", "Unit_hipMemcpyHtoDAsync_Negative_Parameters", - "Unit_hipMemcpyDtoDAsync_Negative_Parameters" + "Unit_hipMemcpyDtoDAsync_Negative_Parameters", + "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", + "Unit_hiprtc_saxpy.Unit_hiprtc_saxpy", + "Unit_hiprtc_warpsize.Unit_hiprtc_warpsize", + "Unit_hiprtc_functional.Unit_hiprtc_functional", + "Unit_hipStreamCaptureRtc.Unit_hipStreamCaptureRtc", + "Unit_hiprtc_cpp17.Unit_hiprtc_cpp17", + "Unit_hiprtc_namehandling.Unit_hiprtc_namehandling", + "Unit_hiprtc_getloweredname.Unit_hiprtc_getloweredname", + "Unit_hiprtc_test_hip_bfloat16.Unit_hiprtc_test_hip_bfloat16", + "Unit_RTC_LinkerAPI.Unit_RTC_LinkerAPI" ] } From 7c7884a2d9e88d43f1137a3b48990c111cd5e965 Mon Sep 17 00:00:00 2001 From: milos-mozetic <118800401+milos-mozetic@users.noreply.github.com> Date: Mon, 14 Aug 2023 17:15:35 +0200 Subject: [PATCH 03/30] EXSWHTEC-224 - Test cases ID clean up and documentation for Texture Management (#92) - Update hipBindTextureToMipmappedArray.cc - Fix build error for undeclared identifier 'ret' - Disable tests which fail in external CI --- .../config/config_amd_linux_common.json | 3 + .../config/config_amd_windows_common.json | 24 +- .../config/config_nvidia_linux_common.json | 8 +- catch/include/hip_test_defgroups.hh | 7 + catch/unit/texture/CMakeLists.txt | 3 + .../texture/hipBindTextureToMipmappedArray.cc | 208 ++++++++++ .../hipCreateTextureObject_ArgValidation.cc | 34 +- .../texture/hipCreateTextureObject_Array.cc | 35 +- .../texture/hipCreateTextureObject_Linear.cc | 36 +- .../texture/hipCreateTextureObject_Pitch2D.cc | 46 ++- catch/unit/texture/hipGetChanDesc.cc | 74 +++- catch/unit/texture/hipTexObjPitch.cc | 22 +- catch/unit/texture/hipTexObjectTests.cc | 359 +++++++++++++++++ catch/unit/texture/hipTextureMipmapObj2D.cc | 19 + .../unit/texture/hipTextureObj1DCheckModes.cc | 18 + catch/unit/texture/hipTextureObj2D.cc | 18 + .../unit/texture/hipTextureObj2DCheckModes.cc | 18 + .../unit/texture/hipTextureObj3DCheckModes.cc | 126 +++--- catch/unit/texture/hipTextureObjectTests.cc | 369 ++++++++++++++++++ 19 files changed, 1321 insertions(+), 106 deletions(-) create mode 100644 catch/unit/texture/hipBindTextureToMipmappedArray.cc create mode 100644 catch/unit/texture/hipTexObjectTests.cc create mode 100644 catch/unit/texture/hipTextureObjectTests.cc diff --git a/catch/hipTestMain/config/config_amd_linux_common.json b/catch/hipTestMain/config/config_amd_linux_common.json index 940eed28fc..2e7d092244 100644 --- a/catch/hipTestMain/config/config_amd_linux_common.json +++ b/catch/hipTestMain/config/config_amd_linux_common.json @@ -111,6 +111,9 @@ "Unit_deviceAllocation_Malloc_ComplexDataType", "Unit_deviceAllocation_New_ComplexDataType", "Unit_hipStreamValue_Wait32_Blocking_Mask_Eq_1", + "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/92 ===", + "Unit_hipGetChannelDesc_Negative_Parameters", + "Unit_hipGraphAddChildGraphNode_CmplxNstGrph_UpdKerFun_Clone", "=== Below tests fail in stress test on 24/07/23 ===", "Unit_hipStreamCreateWithPriority_ValidateWithEvents", "Unit_hipEventIpc", diff --git a/catch/hipTestMain/config/config_amd_windows_common.json b/catch/hipTestMain/config/config_amd_windows_common.json index 141d5a35e0..405556ecc1 100644 --- a/catch/hipTestMain/config/config_amd_windows_common.json +++ b/catch/hipTestMain/config/config_amd_windows_common.json @@ -212,15 +212,19 @@ "Unit_hipMemcpyDtoHAsync_Negative_Parameters", "Unit_hipMemcpyHtoDAsync_Negative_Parameters", "Unit_hipMemcpyDtoDAsync_Negative_Parameters", - "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", - "Unit_hiprtc_saxpy.Unit_hiprtc_saxpy", - "Unit_hiprtc_warpsize.Unit_hiprtc_warpsize", - "Unit_hiprtc_functional.Unit_hiprtc_functional", - "Unit_hipStreamCaptureRtc.Unit_hipStreamCaptureRtc", - "Unit_hiprtc_cpp17.Unit_hiprtc_cpp17", - "Unit_hiprtc_namehandling.Unit_hiprtc_namehandling", - "Unit_hiprtc_getloweredname.Unit_hiprtc_getloweredname", - "Unit_hiprtc_test_hip_bfloat16.Unit_hiprtc_test_hip_bfloat16", - "Unit_RTC_LinkerAPI.Unit_RTC_LinkerAPI" + "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/92 ===", + "Unit_hipGetChannelDesc_Negative_Parameters", + "Unit_hipTextureMipmapRef2D_Positive_Check", + "Unit_hipTextureMipmapRef2D_Negative_Parameters", + "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", + "Unit_hiprtc_saxpy.Unit_hiprtc_saxpy", + "Unit_hiprtc_warpsize.Unit_hiprtc_warpsize", + "Unit_hiprtc_functional.Unit_hiprtc_functional", + "Unit_hipStreamCaptureRtc.Unit_hipStreamCaptureRtc", + "Unit_hiprtc_cpp17.Unit_hiprtc_cpp17", + "Unit_hiprtc_namehandling.Unit_hiprtc_namehandling", + "Unit_hiprtc_getloweredname.Unit_hiprtc_getloweredname", + "Unit_hiprtc_test_hip_bfloat16.Unit_hiprtc_test_hip_bfloat16", + "Unit_RTC_LinkerAPI.Unit_RTC_LinkerAPI" ] } diff --git a/catch/hipTestMain/config/config_nvidia_linux_common.json b/catch/hipTestMain/config/config_nvidia_linux_common.json index baa25636a0..691386f1a1 100644 --- a/catch/hipTestMain/config/config_nvidia_linux_common.json +++ b/catch/hipTestMain/config/config_nvidia_linux_common.json @@ -20,6 +20,12 @@ "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" + "Unit_hipFreeAsync_negative", + "=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/92 ===", + "Unit_hipGetTexObjectResourceDesc_positive", + "Unit_hipGetTexObjectResourceDesc_Negative_Parameters", + "Unit_hipGetTexObjectTextureDesc_positive", + "Unit_hipGetTexObjectTextureDesc_Negative_Parameters", + "Unit_hipTexObjectDestroy_positive" ] } diff --git a/catch/include/hip_test_defgroups.hh b/catch/include/hip_test_defgroups.hh index 92857a12bc..119b095dcc 100644 --- a/catch/include/hip_test_defgroups.hh +++ b/catch/include/hip_test_defgroups.hh @@ -94,6 +94,13 @@ THE SOFTWARE. */ /** + * @defgroup TextureTest Texture Management + * @{ + * This section describes tests for the texture management functions of HIP runtime API. + * @} + */ + + /** * @defgroup ShflTest warp shuffle function Management * @{ * This section describes the warp shuffle types & functions of HIP runtime API. diff --git a/catch/unit/texture/CMakeLists.txt b/catch/unit/texture/CMakeLists.txt index 93a188683c..9c7bbfa4a6 100644 --- a/catch/unit/texture/CMakeLists.txt +++ b/catch/unit/texture/CMakeLists.txt @@ -42,6 +42,9 @@ set(TEST_SRC hipTextureObj3DCheckModes.cc hipTextureObj1DCheckSRGBModes.cc hipTextureObj2DCheckSRGBModes.cc + hipTexObjectTests.cc + hipTextureObjectTests.cc + hipBindTextureToMipmappedArray.cc ) hip_add_exe_to_target(NAME TextureTest diff --git a/catch/unit/texture/hipBindTextureToMipmappedArray.cc b/catch/unit/texture/hipBindTextureToMipmappedArray.cc new file mode 100644 index 0000000000..670e4f75eb --- /dev/null +++ b/catch/unit/texture/hipBindTextureToMipmappedArray.cc @@ -0,0 +1,208 @@ +/* +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 + +/** + * @addtogroup hipBindTextureToMipmappedArray hipBindTextureToMipmappedArray + * @{ + * @ingroup TextureTest + * `hipBindTextureToMipmappedArray(const textureReference* tex, + * hipMipmappedArray_const_t mipmappedArray, const hipChannelFormatDesc* desc)` - + * Binds a mipmapped array to a texture. + */ + +texture texRef; + +// MipMap is currently supported only on windows +#if (defined(_WIN32) && !defined(__HIP_NO_IMAGE_SUPPORT)) +__global__ void tex2DKernel(float* outputData, int width, float level) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + int y = blockIdx.y * blockDim.y + threadIdx.y; + outputData[y * width + x] = tex2DLod(texRef, x, y, level); +} + +static void runMipMapTest(unsigned int width, unsigned int height, unsigned int mipmap_level) { + INFO("Width: " << width << "Height: " << height << "mip: " << mipmap_level); + + // Create new width & height to be tested + unsigned int orig_width = width; + unsigned int orig_height = height; + unsigned int i, j; + width /= pow(2, mipmap_level); + height /= pow(2, mipmap_level); + unsigned int size = width * height * sizeof(float); + + float* hData = reinterpret_cast(malloc(size)); + REQUIRE(hData != nullptr); + memset(hData, 0, size); + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + hData[i * width + j] = i * width + j; + } + } + + // Allocate memory for Mipmapped array and set data to mipmap_level + hipChannelFormatDesc channelDesc = hipCreateChannelDesc(); + + hipMipmappedArray* mip_array_ptr; + HIP_CHECK(hipMallocMipmappedArray(&mip_array_ptr, &channelDesc, + make_hipExtent(orig_width, orig_height, 0), 2 * mipmap_level, + hipArrayDefault)); + + hipArray* hipArray = nullptr; + HIP_CHECK(hipGetMipmappedArrayLevel(&hipArray, mip_array_ptr, mipmap_level)); + HIP_CHECK(hipMemcpy2DToArray(hipArray, 0, 0, hData, width * sizeof(float), width * sizeof(float), + height, hipMemcpyHostToDevice)); + + // Set texture parameters + texRef.addressMode[0] = hipAddressModeWrap; + texRef.addressMode[1] = hipAddressModeWrap; + texRef.filterMode = hipFilterModePoint; + texRef.normalized = 0; + + // Bind the array to the texture + HIP_CHECK(hipBindTextureToMipmappedArray(&texRef, mip_array_ptr, &channelDesc)); + + // Allocate device memory for result + float* dData = nullptr; + HIP_CHECK(hipMalloc(&dData, size)); + REQUIRE(dData != nullptr); + + dim3 dimBlock(16, 16, 1); + dim3 dimGrid(width / dimBlock.x, height / dimBlock.y, 1); + + hipLaunchKernelGGL(tex2DKernel, dim3(dimGrid), dim3(dimBlock), 0, 0, dData, width, mipmap_level); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipDeviceSynchronize()); + + // Allocate memory on host and copy result from device to host + float* hOutputData = reinterpret_cast(malloc(size)); + REQUIRE(hOutputData != nullptr); + memset(hOutputData, 0, size); + HIP_CHECK(hipMemcpy(hOutputData, dData, size, hipMemcpyDeviceToHost)); + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + if (hData[i * width + j] != hOutputData[i * width + j]) { + INFO("Difference found at [ " << i << j << " ]: " << hData[i * width + j] + << hOutputData[i * width + j]); + REQUIRE(false); + } + } + } + HIP_CHECK(hipUnbindTexture(texRef)); + HIP_CHECK(hipFree(dData)); + HIP_CHECK(hipFreeArray(hipArray)); + HIP_CHECK(hipFreeMipmappedArray(mip_array_ptr)); + free(hData); +} +#endif + +/** + * Test Description + * ------------------------ + * - Maps texture to the mipmapped array for different mipmapped array + * sizes and number of levels. + * Test source + * ------------------------ + * - unit/texture/hipBindTextureToMipmappedArray.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipTextureMipmapRef2D_Positive_Check") { + CHECK_IMAGE_SUPPORT + // Height Width Vector + std::vector hw_vec = {2048, 1024, 512, 256, 64}; + std::vector mip_vec = {8, 4, 2, 1}; +#ifdef _WIN32 + for (auto& hw : hw_vec) { + for (auto& mip : mip_vec) { + if ((hw / static_cast(pow(2, (mip * 2)))) > 0) { + runMipMapTest(hw, hw, mip); + } + } + } +#else + SUCCEED("Mipmaps are Supported only on windows, skipping the test."); +#endif +} + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When texture reference is `nullptr` + * - Expected output: do not return `hipSuccess` + * -# When mipmapped array handle is `nullptr` + * - Expected output: do not return `hipSuccess` + * -# When channel descriptor is `nullptr` + * - Expected output: do not return `hipSuccess` + * Test source + * ------------------------ + * - unit/texture/hipBindTextureToMipmappedArray.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipTextureMipmapRef2D_Negative_Parameters") { + CHECK_IMAGE_SUPPORT + +#ifdef _WIN32 + unsigned int width = 64; + unsigned int height = 64; + unsigned int mipmap_level = 1; + + hipChannelFormatDesc channelDesc = hipCreateChannelDesc(); + + hipMipmappedArray* mip_array_ptr; + HIP_CHECK(hipMallocMipmappedArray(&mip_array_ptr, &channelDesc, make_hipExtent(width, height, 0), + mipmap_level, hipArrayDefault)); + + texRef.addressMode[0] = hipAddressModeWrap; + texRef.addressMode[1] = hipAddressModeWrap; + texRef.filterMode = hipFilterModePoint; + texRef.normalized = 0; + hipError_t ret; + + SECTION("textureReference is nullptr") { + ret = hipBindTextureToMipmappedArray(nullptr, mip_array_ptr, &channelDesc); + REQUIRE(ret != hipSuccess); + } + + SECTION("MipmappedArray is nullptr") { + hipError_t ret = hipBindTextureToMipmappedArray(&texRef, nullptr, &channelDesc); + REQUIRE(ret != hipSuccess); + } + + SECTION("Channel descriptor is nullptr") { + ret = hipBindTextureToMipmappedArray(&texRef, mip_array_ptr, nullptr); + REQUIRE(ret != hipSuccess); + } + + HIP_CHECK(hipFreeMipmappedArray(mip_array_ptr)); +#else + SUCCEED("Mipmaps are Supported only on windows, skipping the test."); +#endif +} diff --git a/catch/unit/texture/hipCreateTextureObject_ArgValidation.cc b/catch/unit/texture/hipCreateTextureObject_ArgValidation.cc index 0ce2d51f2d..d0d3d965f7 100644 --- a/catch/unit/texture/hipCreateTextureObject_ArgValidation.cc +++ b/catch/unit/texture/hipCreateTextureObject_ArgValidation.cc @@ -19,10 +19,34 @@ THE SOFTWARE. #include +/** + * @addtogroup hipCreateTextureObject hipCreateTextureObject + * @{ + * @ingroup TextureTest + */ + #define N 512 -/* - * Validate argument list of texture object api. +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments for [hipCreateTextureObject](@ref hipCreateTextureObject): + * -# When output pointer to the texture object is `nullptr` + * - Expected output: do not return `hipSuccess` + * -# When resource descriptor is `nullptr` + * - Expected output: do not return `hipSuccess` + * -# When texture descriptor is `nullptr` + * - Expected output: do not return `hipSuccess` + * - Validates handling of invalid arguments for [hipDestroyTextureObject](@ref hipDestroyTextureObject): + * -# When texture object handle is `nullptr` + * - Expected output: return `hipSuccess` + * Test source + * ------------------------ + * - unit/texture/hipCreateTextureObject_ArgValidation.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipCreateTextureObject_ArgValidation") { CHECK_IMAGE_SUPPORT @@ -34,7 +58,7 @@ TEST_CASE("Unit_hipCreateTextureObject_ArgValidation") { hipTextureDesc texDesc; hipTextureObject_t texObj; - /** Initialization */ + // Initialization HIP_CHECK(hipMalloc(&texBuf, N * sizeof(float))); // Populate resource descriptor memset(&resDesc, 0, sizeof(resDesc)); @@ -49,7 +73,7 @@ TEST_CASE("Unit_hipCreateTextureObject_ArgValidation") { texDesc.readMode = hipReadModeElementType; - /** Sections */ + // Sections SECTION("TextureObject as nullptr") { ret = hipCreateTextureObject(nullptr, &resDesc, &texDesc, nullptr); REQUIRE(ret != hipSuccess); @@ -78,6 +102,6 @@ TEST_CASE("Unit_hipCreateTextureObject_ArgValidation") { REQUIRE(ret == hipSuccess); } - /** De-Initialization */ + // De-Initialization HIP_CHECK(hipFree(texBuf)); } diff --git a/catch/unit/texture/hipCreateTextureObject_Array.cc b/catch/unit/texture/hipCreateTextureObject_Array.cc index 366547d655..5395502f84 100644 --- a/catch/unit/texture/hipCreateTextureObject_Array.cc +++ b/catch/unit/texture/hipCreateTextureObject_Array.cc @@ -19,8 +19,24 @@ THE SOFTWARE. #include -/* - * Validates Array Resource texture object with negative/functional tests. +/** + * @addtogroup hipCreateTextureObject hipCreateTextureObject + * @{ + * @ingroup TextureTest + */ + +/** + * Test Description + * ------------------------ + * - Validates handling of a regular `nullptr` array + * - Expected output: do not return `hipSuccess` + * Test source + * ------------------------ + * - unit/texture/hipCreateTextureObject_Array.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipCreateTextureObject_ArrayResource") { CHECK_IMAGE_SUPPORT @@ -44,9 +60,18 @@ TEST_CASE("Unit_hipCreateTextureObject_ArrayResource") { REQUIRE(ret != hipSuccess); } -/* - * Validates MipMappedArray Resource texture object - * with negative/functional tests. +/** + * Test Description + * ------------------------ + * - Validates handling of a regular `nullptr` mipmapped array + * - Expected output: do not return `hipSuccess` + * Test source + * ------------------------ + * - unit/texture/hipCreateTextureObject_Array.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipCreateTextureObject_MmArrayResource") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/texture/hipCreateTextureObject_Linear.cc b/catch/unit/texture/hipCreateTextureObject_Linear.cc index fb12586d37..286c12bfc6 100644 --- a/catch/unit/texture/hipCreateTextureObject_Linear.cc +++ b/catch/unit/texture/hipCreateTextureObject_Linear.cc @@ -19,11 +19,37 @@ THE SOFTWARE. #include +/** + * @addtogroup hipCreateTextureObject hipCreateTextureObject + * @{ + * @ingroup TextureTest + */ + #define UNALIGN_OFFSET 1 #define N 512 -/* - * Validates Linear Resource texture object with negative/functional tests. +/** + * Test Description + * ------------------------ + * - Validates handling of invalid linear resource: + * -# When device pointer is `nullptr` + * - Expected output: do not return `hipSuccess` + * -# When size in bytes is 0 + * - Expected output: do not return `hipSuccess` + * -# When size in bytes is `size_t` maximum + * - Expected output: do not return `hipSuccess` + * -# When a valid resource view descriptor is provided + * - Platform specific (AMD) + * - Expected output: do not return `hipSuccess` + * -# When device pointer is not aligned appropriately + * - Expected output: do not return `hipSuccess` + * Test source + * ------------------------ + * - unit/texture/hipCreateTextureObject_Linear.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipCreateTextureObject_LinearResource") { CHECK_IMAGE_SUPPORT @@ -37,14 +63,14 @@ TEST_CASE("Unit_hipCreateTextureObject_LinearResource") { hipTextureObject_t texObj; hipDeviceProp_t devProp; - /** Initialization */ + // Initialization HIP_CHECK(hipMalloc(&texBuf, N * sizeof(float))); HIP_CHECK(hipGetDeviceProperties(&devProp, 0)); memset(&resDesc, 0, sizeof(resDesc)); memset(&texDesc, 0, sizeof(texDesc)); resDesc.resType = hipResourceTypeLinear; - /** Sections */ + // Sections SECTION("hipResourceTypeLinear and devPtr(nullptr)") { // Populate resource descriptor resDesc.res.linear.devPtr = nullptr; @@ -130,6 +156,6 @@ TEST_CASE("Unit_hipCreateTextureObject_LinearResource") { } } - /** De-Initialization */ + // De-Initialization HIP_CHECK(hipFree(texBuf)); } diff --git a/catch/unit/texture/hipCreateTextureObject_Pitch2D.cc b/catch/unit/texture/hipCreateTextureObject_Pitch2D.cc index fff56d7dd7..f81d03d021 100644 --- a/catch/unit/texture/hipCreateTextureObject_Pitch2D.cc +++ b/catch/unit/texture/hipCreateTextureObject_Pitch2D.cc @@ -19,14 +19,48 @@ THE SOFTWARE. #include +/** + * @addtogroup hipCreateTextureObject hipCreateTextureObject + * @{ + * @ingroup TextureTest + */ + #define UNALIGN_OFFSET 1 #define SIZE_H 20 #define SIZE_W 30 #define N 512 - -/* - * Validates Pitch2D Resource texture object with negative and functional tests +/** + * Test Description + * ------------------------ + * - Validates handling of invalid 2D pitch resource: + * -# When device pointer is `nullptr` + * - Expected output: do not return `hipSuccess` + * -# When device pointer is not aligned appropriately + * - Expected output: do not return `hipSuccess` + * -# When pitch is not aligned appropriately + * - Expected output: do not return `hipSuccess` + * -# When height is 0 + * - Expected output: do not return `hipSuccess` + * -# When height is 0 and device pointer is `nullptr` + * - Expected output: do not return `hipSuccess` + * -# When height is `size_t` maximum + * - Expected output: do not return `hipSuccess` + * -# When width is 0 + * - Expected output: do not return `hipSuccess` + * -# When width is 0 and device pointer is `nullptr` + * - Expected output: do not return `hipSuccess` + * -# When width is `size_t` maximum + * - Expected output: do not return `hipSuccess` + * -# When pitch is `size_t` maximum + * - Expected output: do not return `hipSuccess` + * Test source + * ------------------------ + * - unit/texture/hipCreateTextureObject_Pitch2D.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipCreateTextureObject_Pitch2DResource") { CHECK_IMAGE_SUPPORT @@ -39,7 +73,7 @@ TEST_CASE("Unit_hipCreateTextureObject_Pitch2DResource") { size_t devPitchA; float *devPtrA; - /** Initialization */ + // Initialization HIP_CHECK(hipMallocPitch(reinterpret_cast(&devPtrA), &devPitchA, SIZE_W*sizeof(float), SIZE_H)); HIP_CHECK(hipGetDeviceProperties(&devProp, 0)); @@ -47,7 +81,7 @@ TEST_CASE("Unit_hipCreateTextureObject_Pitch2DResource") { memset(&texDesc, 0, sizeof(texDesc)); resDesc.resType = hipResourceTypePitch2D; - /** Sections */ + // Sections SECTION("hipResourceTypePitch2D and devPtr(nullptr)") { // Populate resource descriptor resDesc.res.pitch2D.devPtr = nullptr; @@ -212,7 +246,7 @@ TEST_CASE("Unit_hipCreateTextureObject_Pitch2DResource") { REQUIRE(ret != hipSuccess); } - /** De-Initialization */ + // De-Initialization HIP_CHECK(hipFree(devPtrA)); } diff --git a/catch/unit/texture/hipGetChanDesc.cc b/catch/unit/texture/hipGetChanDesc.cc index b7585059c8..2f781254a7 100644 --- a/catch/unit/texture/hipGetChanDesc.cc +++ b/catch/unit/texture/hipGetChanDesc.cc @@ -19,27 +19,79 @@ THE SOFTWARE. #include +/** + * @addtogroup hipGetChannelDesc hipGetChannelDesc + * @{ + * @ingroup TextureTest + * `hipGetChannelDesc(hipChannelFormatDesc* desc, hipArray_const_t array)` - + * Gets the channel descriptor in an array. + */ + #define R 8 // rows, height #define C 8 // columns, width - +/** + * Test Description + * ------------------------ + * - Creates a regular channel description. + * - Creates array using previously created description. + * - Checks that valid description is returned. + * Test source + * ------------------------ + * - unit/texture/hipGetChanDesc.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipGetChannelDesc_CreateAndGet") { - CHECK_IMAGE_SUPPORT + CHECK_IMAGE_SUPPORT; hipChannelFormatDesc chan_test, chan_desc; - hipArray *hipArray; + hipArray* hip_array; chan_desc = hipCreateChannelDesc(32, 0, 0, 0, hipChannelFormatKindSigned); - HIP_CHECK(hipMallocArray(&hipArray, &chan_desc, C, R, 0)); - HIP_CHECK(hipGetChannelDesc(&chan_test, hipArray)); + HIP_CHECK(hipMallocArray(&hip_array, &chan_desc, C, R, 0)); + HIP_CHECK(hipGetChannelDesc(&chan_test, hip_array)); - if ((chan_test.x != 32) || (chan_test.y != 0) - || (chan_test.z != 0) || (chan_test.f != 0)) { - INFO("Mismatch observed : " << chan_test.x << chan_test.y - << chan_test.z << chan_test.f); + if ((chan_test.x != 32) || (chan_test.y != 0) || (chan_test.z != 0) || (chan_test.f != 0)) { + INFO("Mismatch observed : " << chan_test.x << chan_test.y << chan_test.z << chan_test.f); REQUIRE(false); } - - HIP_CHECK(hipFreeArray(hipArray)); + HIP_CHECK(hipFreeArray(hip_array)); +} + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When output pointer to the description is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When array handle is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/texture/hipGetChanDesc.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipGetChannelDesc_Negative_Parameters") { + CHECK_IMAGE_SUPPORT; + + hipChannelFormatDesc chan_test, chan_desc; + hipArray* hip_array; + + chan_desc = hipCreateChannelDesc(32, 0, 0, 0, hipChannelFormatKindSigned); + HIP_CHECK(hipMallocArray(&hip_array, &chan_desc, C, R, 0)); + + SECTION("desc is nullptr") { + HIP_CHECK_ERROR(hipGetChannelDesc(nullptr, hip_array), hipErrorInvalidValue); + } + + SECTION("array is nullptr") { + HIP_CHECK_ERROR(hipGetChannelDesc(&chan_test, nullptr), hipErrorInvalidHandle); + } + + HIP_CHECK(hipFreeArray(hip_array)); } diff --git a/catch/unit/texture/hipTexObjPitch.cc b/catch/unit/texture/hipTexObjPitch.cc index 364bc79a21..24f9c21aeb 100644 --- a/catch/unit/texture/hipTexObjPitch.cc +++ b/catch/unit/texture/hipTexObjPitch.cc @@ -20,6 +20,15 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipCreateTextureObject hipCreateTextureObject + * @{ + * @ingroup TextureTest + * `hipCreateTextureObject(hipTextureObject_t* pTexObject, const hipResourceDesc* pResDesc, + * const hipTextureDesc* pTexDesc, const struct hipResourceViewDesc* pResViewDesc)` - + * Creates a texture object. + */ + #define SIZE_H 20 #define SIZE_W 179 @@ -35,7 +44,18 @@ static __global__ void texture2dCopyKernel(hipTextureObject_t texObj, #endif } - +/** + * Test Description + * ------------------------ + * - Basic test where resource type is 2D pitch. + * Test source + * ------------------------ + * - unit/texture/hipTexObjPitch.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipTexObjPitch_texture2D", "", float, int, unsigned char, int16_t, char, unsigned int) { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/texture/hipTexObjectTests.cc b/catch/unit/texture/hipTexObjectTests.cc new file mode 100644 index 0000000000..f7285f93f8 --- /dev/null +++ b/catch/unit/texture/hipTexObjectTests.cc @@ -0,0 +1,359 @@ +/* +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, 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 + + +class TexObjectTestWrapper { + private: + float* host_data_; + bool ommit_destroy_; + + public: + hipTextureObject_t texture_object = 0; + HIP_RESOURCE_DESC res_desc; + HIP_TEXTURE_DESC tex_desc; + HIP_RESOURCE_VIEW_DESC res_view_desc; + HIP_ARRAY_DESCRIPTOR array_desc; + hiparray array_member; + size_t size; /* size in bytes*/ + int width; /* width in elements */ + + TexObjectTestWrapper(bool useResourceViewDescriptor, bool ommitDestroy = false) + : ommit_destroy_(ommitDestroy), width(128) { + int i; + size = width * sizeof(float); + + host_data_ = (float*)malloc(size); + memset(host_data_, 0, size); + + for (i = 0; i < width; i++) { + host_data_[i] = i; + } + + memset(&array_desc, 0, sizeof(array_desc)); + array_desc.Format = HIP_AD_FORMAT_FLOAT; + array_desc.NumChannels = 1; + array_desc.Width = width; + array_desc.Height = 0; + + HIP_CHECK(hipArrayCreate(&array_member, &array_desc)); + HIP_CHECK(hipMemcpyHtoA(reinterpret_cast(array_member), 0, host_data_, size)); + + memset(&res_desc, 0, sizeof(res_desc)); + res_desc.resType = HIP_RESOURCE_TYPE_ARRAY; + res_desc.res.array.hArray = array_member; + res_desc.flags = 0; + + memset(&tex_desc, 0, sizeof(tex_desc)); + tex_desc.filterMode = HIP_TR_FILTER_MODE_POINT; + tex_desc.flags = 0; + + memset(&res_view_desc, 0, sizeof(res_view_desc)); + + + if (useResourceViewDescriptor) { +#if HT_AMD + res_view_desc.format = HIP_RES_VIEW_FORMAT_FLOAT_1X32; + res_view_desc.width = size; +#else + /* Resource View Descriptors are not supported on NVIDIA currently */ + useResourceViewDescriptor = false; +#endif + } + + + HIP_CHECK(hipTexObjectCreate(&texture_object, &res_desc, &tex_desc, + useResourceViewDescriptor ? &res_view_desc : nullptr)); + } + + ~TexObjectTestWrapper() { + if (!ommit_destroy_) { + HIP_CHECK(hipTexObjectDestroy(texture_object)); + } + HIP_CHECK(hipArrayDestroy(array_member)); + free(host_data_); + } +}; + +/** + * @addtogroup hipTexObjectGetResourceDesc hipTexObjectGetResourceDesc + * @{ + * @ingroup TextureTest + * `hipTexObjectGetResourceDesc(HIP_RESOURCE_DESC* pResDesc, + * hipTextureObject_t texObject)` - + * Gets resource descriptor of a texture object. + */ + +/** + * Test Description + * ------------------------ + * - Creates new texture object and an empty resource descriptor. + * - Gets resource descriptor from the texture. + * - Compares it to the empty created one. + * Test source + * ------------------------ + * - unit/texture/hipTexObjectTests.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipGetTexObjectResourceDesc_positive") { + CHECK_IMAGE_SUPPORT; + + TexObjectTestWrapper tex_obj_wrapper(false); + + HIP_RESOURCE_DESC check_desc; + memset(&check_desc, 0, sizeof(check_desc)); + + HIP_CHECK(hipTexObjectGetResourceDesc(&check_desc, tex_obj_wrapper.texture_object)); + + REQUIRE(check_desc.resType == tex_obj_wrapper.res_desc.resType); + REQUIRE(check_desc.res.array.hArray == tex_obj_wrapper.res_desc.res.array.hArray); +} + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When output pointer to the resource descriptor is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the texture is not valid (0) + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/texture/hipTexObjectTests.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipGetTexObjectResourceDesc_Negative_Parameters") { + CHECK_IMAGE_SUPPORT; + + TexObjectTestWrapper tex_obj_wrapper(false); + + HIP_RESOURCE_DESC check_desc; + memset(&check_desc, 0, sizeof(check_desc)); + + SECTION("desc is nullptr") { + HIP_CHECK_ERROR(hipTexObjectGetResourceDesc(nullptr, tex_obj_wrapper.texture_object), + hipErrorInvalidValue); + } + + SECTION("texture is invalid") { + HIP_CHECK_ERROR(hipTexObjectGetResourceDesc(&check_desc, static_cast(0)), + hipErrorInvalidValue); + } +} + +/** + * End doxygen group hipTexObjectGetResourceDesc. + * @} + */ + +/** + * @addtogroup hipTexObjectGetResourceViewDesc hipTexObjectGetResourceViewDesc + * @{ + * @ingroup TextureTest + * `hipTexObjectGetResourceViewDesc(HIP_RESOURCE_VIEW_DESC* pResViewDesc, + * hipTextureObject_t texObject)` - + * Gets resource view descriptor of a texture object. + */ + +/** + * Test Description + * ------------------------ + * - Creates new texture object and an empty resource view descriptor. + * - Gets resource view descriptor from the texture. + * - Compares it to the empty created one. + * Test source + * ------------------------ + * - unit/texture/hipTexObjectTests.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ +#if HT_AMD +TEST_CASE("Unit_hipGetTexObjectResourceViewDesc_positive") { + CHECK_IMAGE_SUPPORT; + + TexObjectTestWrapper tex_obj_wrapper(true); + + HIP_RESOURCE_VIEW_DESC check_desc; + memset(&check_desc, 0, sizeof(check_desc)); + + HIP_CHECK(hipTexObjectGetResourceViewDesc(&check_desc, tex_obj_wrapper.texture_object)); + + REQUIRE(check_desc.format == tex_obj_wrapper.res_view_desc.format); + REQUIRE(check_desc.width == tex_obj_wrapper.res_view_desc.width); +} +#endif + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When output pointer to the resource view descriptor is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the texture is not valid (0) + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/texture/hipTexObjectTests.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ +#if HT_AMD +TEST_CASE("Unit_hipGetTexObjectResourceViewDesc_Negative_Parameters") { + CHECK_IMAGE_SUPPORT; + TexObjectTestWrapper tex_obj_wrapper(true); + + HIP_RESOURCE_VIEW_DESC check_desc; + memset(&check_desc, 0, sizeof(check_desc)); + + SECTION("desc is nullptr") { + HIP_CHECK_ERROR(hipTexObjectGetResourceViewDesc(nullptr, tex_obj_wrapper.texture_object), + hipErrorInvalidValue); + } + + SECTION("texture is invalid") { + HIP_CHECK_ERROR( + hipTexObjectGetResourceViewDesc(&check_desc, static_cast(0)), + hipErrorInvalidValue); + } +} +#endif + +/** + * End doxygen group hipTexObjectGetResourceViewDesc. + * @} + */ + +/** + * @addtogroup hipTexObjectGetTextureDesc hipTexObjectGetTextureDesc + * @{ + * @ingroup TextureTest + * `hipTexObjectGetTextureDesc(HIP_TEXTURE_DESC* pTexDesc, + * hipTextureObject_t texObject)` - + * Gets texture descriptor of a texture object. + */ + +/** + * Test Description + * ------------------------ + * - Creates new texture object and an empty texture descriptor. + * - Gets texture descriptor from the texture. + * - Compares it to the empty created one. + * Test source + * ------------------------ + * - unit/texture/hipTexObjectTests.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipGetTexObjectTextureDesc_positive") { + CHECK_IMAGE_SUPPORT; + + TexObjectTestWrapper tex_obj_wrapper(false); + + HIP_TEXTURE_DESC check_desc; + memset(&check_desc, 0, sizeof(check_desc)); + + HIP_CHECK(hipTexObjectGetTextureDesc(&check_desc, tex_obj_wrapper.texture_object)); + + REQUIRE(check_desc.filterMode == tex_obj_wrapper.tex_desc.filterMode); + REQUIRE(check_desc.flags == tex_obj_wrapper.tex_desc.flags); +} + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When output pointer to the texture descriptor is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the texture is not valid (0) + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/texture/hipTexObjectTests.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipGetTexObjectTextureDesc_Negative_Parameters") { + CHECK_IMAGE_SUPPORT; + + TexObjectTestWrapper tex_obj_wrapper(false); + + HIP_TEXTURE_DESC check_desc; + memset(&check_desc, 0, sizeof(check_desc)); + + SECTION("desc is nullptr") { + HIP_CHECK_ERROR(hipTexObjectGetTextureDesc(nullptr, tex_obj_wrapper.texture_object), + hipErrorInvalidValue); + } + + SECTION("texture is invalid") { + HIP_CHECK_ERROR(hipTexObjectGetTextureDesc(&check_desc, static_cast(0)), + hipErrorInvalidValue); + } +} + +/** + * End doxygen group hipTexObjectGetTextureDesc. + * @} + */ + +/** + * @addtogroup hipTexObjectDestroy hipTexObjectDestroy + * @{ + * @ingroup TextureTest + * `hipTexObjectDestroy(hipTextureObject_t texObject)` - + * Destroys a texture object. + */ + +/** + * Test Description + * ------------------------ + * - Successfully destroys regular texture object. + * Test source + * ------------------------ + * - unit/texture/hipTexObjectTests.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipTexObjectDestroy_positive") { + CHECK_IMAGE_SUPPORT; + + TexObjectTestWrapper tex_obj_wrapper(false, true); + REQUIRE(hipTexObjectDestroy(tex_obj_wrapper.texture_object) == hipSuccess); +} diff --git a/catch/unit/texture/hipTextureMipmapObj2D.cc b/catch/unit/texture/hipTextureMipmapObj2D.cc index 2b70c13c9f..72b6d196a0 100644 --- a/catch/unit/texture/hipTextureMipmapObj2D.cc +++ b/catch/unit/texture/hipTextureMipmapObj2D.cc @@ -19,6 +19,12 @@ THE SOFTWARE. #include +/** + * @addtogroup hipCreateTextureObject hipCreateTextureObject + * @{ + * @ingroup TextureTest + */ + // Height Width Vector std::vector hw_vector = {2048, 1024, 512, 256, 64}; std::vector mip_vector = {8, 4, 2, 1}; @@ -121,6 +127,19 @@ static void runMipMapTest(unsigned int width, unsigned int height, unsigned int } #endif +/** + * Test Description + * ------------------------ + * - Basic test where resource type is a mipmapped array. + * Test source + * ------------------------ + * - unit/texture/hipTextureMipmapObj2D.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - Textures supported on device + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipTextureMipmapObj2D_Check") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/texture/hipTextureObj1DCheckModes.cc b/catch/unit/texture/hipTextureObj1DCheckModes.cc index 390ef5abc0..a3e8e10f5e 100644 --- a/catch/unit/texture/hipTextureObj1DCheckModes.cc +++ b/catch/unit/texture/hipTextureObj1DCheckModes.cc @@ -21,6 +21,12 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipCreateTextureObject hipCreateTextureObject + * @{ + * @ingroup TextureTest + */ + template __global__ void tex1DKernel(float *outputData, hipTextureObject_t textureObject, int width, float offsetX) { @@ -100,6 +106,18 @@ static void runTest(const int width, const float offsetX) { REQUIRE(result); } +/** + * Test Description + * ------------------------ + * - Uses different addressing and filtering modes for 1D array. + * Test source + * ------------------------ + * - unit/texture/hipTextureObj1DCheckModes.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipTextureObj1DCheckModes") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/texture/hipTextureObj2D.cc b/catch/unit/texture/hipTextureObj2D.cc index d545962165..ee4e895b32 100644 --- a/catch/unit/texture/hipTextureObj2D.cc +++ b/catch/unit/texture/hipTextureObj2D.cc @@ -19,6 +19,12 @@ THE SOFTWARE. #include +/** + * @addtogroup hipCreateTextureObject hipCreateTextureObject + * @{ + * @ingroup TextureTest + */ + __global__ void tex2DKernel(float* outputData, hipTextureObject_t textureObject, int width) { #if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT @@ -28,6 +34,18 @@ __global__ void tex2DKernel(float* outputData, #endif } +/** + * Test Description + * ------------------------ + * - Basic test where the resource type is a 2D array. + * Test source + * ------------------------ + * - unit/texture/hipTextureObj2D.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipTextureObj2D_Check") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/texture/hipTextureObj2DCheckModes.cc b/catch/unit/texture/hipTextureObj2DCheckModes.cc index 84f1081a2a..0e95023dc0 100644 --- a/catch/unit/texture/hipTextureObj2DCheckModes.cc +++ b/catch/unit/texture/hipTextureObj2DCheckModes.cc @@ -21,6 +21,12 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipCreateTextureObject hipCreateTextureObject + * @{ + * @ingroup TextureTest + */ + template __global__ void tex2DKernel(float *outputData, hipTextureObject_t textureObject, int width, int height, float offsetX, @@ -112,6 +118,18 @@ line1: REQUIRE(result); } +/** + * Test Description + * ------------------------ + * - Uses different addressing and filtering modes for 2D arrays. + * Test source + * ------------------------ + * - unit/texture/hipTextureObj2DCheckModes.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipTextureObj2DCheckModes") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/texture/hipTextureObj3DCheckModes.cc b/catch/unit/texture/hipTextureObj3DCheckModes.cc index 538237b4ad..708caf1201 100644 --- a/catch/unit/texture/hipTextureObj3DCheckModes.cc +++ b/catch/unit/texture/hipTextureObj3DCheckModes.cc @@ -22,32 +22,38 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipCreateTextureObject hipCreateTextureObject + * @{ + * @ingroup TextureTest + */ + bool LinearFilter3D = false; -template -__global__ void tex3DKernel(float *outputData, hipTextureObject_t textureObject, - int width, int height, int depth, float offsetX, - float offsetY, float offsetZ) { +template +__global__ void tex3DKernel(float* outputData, hipTextureObject_t textureObject, int width, + int height, int depth, float offsetX, float offsetY, float offsetZ) { #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; int z = blockIdx.z * blockDim.z + threadIdx.z; - outputData[z * width * height + y * width + x] = tex3D(textureObject, - normalizedCoords ? (x + offsetX) / width : x + offsetX, - normalizedCoords ? (y + offsetY) / height : y + offsetY, - normalizedCoords ? (z + offsetZ) / depth : z + offsetZ); + outputData[z * width * height + y * width + x] = + tex3D(textureObject, normalizedCoords ? (x + offsetX) / width : x + offsetX, + normalizedCoords ? (y + offsetY) / height : y + offsetY, + normalizedCoords ? (z + offsetZ) / depth : z + offsetZ); #endif } -template -static void runTest(const int width, const int height, const int depth, const float offsetX, const float offsetY, - const float offsetZ) { - //printf("%s(addressMode=%d, filterMode=%d, normalizedCoords=%d, width=%d, height=%d, depth=%d, offsetX=%f, offsetY=%f, offsetZ=%f)\n", - // __FUNCTION__, addressMode, filterMode, normalizedCoords, width, height, - // depth, offsetX, offsetY, offsetZ); +template +static void runTest(const int width, const int height, const int depth, const float offsetX, + const float offsetY, const float offsetZ) { + // printf("%s(addressMode=%d, filterMode=%d, normalizedCoords=%d, width=%d, height=%d, depth=%d, + // offsetX=%f, offsetY=%f, offsetZ=%f)\n", + // __FUNCTION__, addressMode, filterMode, normalizedCoords, width, height, + // depth, offsetX, offsetY, offsetZ); bool result = true; unsigned int size = width * height * depth * sizeof(float); - float *hData = (float*) malloc(size); + float* hData = (float*)malloc(size); memset(hData, 0, size); for (int i = 0; i < depth; i++) { @@ -61,13 +67,14 @@ static void runTest(const int width, const int height, const int depth, const fl // Allocate array and copy image data hipChannelFormatDesc channelDesc = hipCreateChannelDesc(); - hipArray *arr; + hipArray* arr; - HIP_CHECK(hipMalloc3DArray(&arr, &channelDesc, make_hipExtent(width, height, depth), hipArrayDefault)); + HIP_CHECK( + hipMalloc3DArray(&arr, &channelDesc, make_hipExtent(width, height, depth), hipArrayDefault)); hipMemcpy3DParms myparms; memset(&myparms, 0, sizeof(myparms)); - myparms.srcPos = make_hipPos(0,0,0); - myparms.dstPos = make_hipPos(0,0,0); + myparms.srcPos = make_hipPos(0, 0, 0); + myparms.dstPos = make_hipPos(0, 0, 0); myparms.srcPtr = make_hipPitchedPtr(hData, width * sizeof(float), width, height); myparms.dstArray = arr; myparms.extent = make_hipExtent(width, height, depth); @@ -105,20 +112,20 @@ static void runTest(const int width, const int height, const int depth, const fl return; } - float *dData = nullptr; - HIP_CHECK(hipMalloc((void**) &dData, size)); + float* dData = nullptr; + HIP_CHECK(hipMalloc((void**)&dData, size)); HIP_CHECK(hipMemset(dData, 0, size)); - dim3 dimBlock(8, 8, 8); // 512 threads - dim3 dimGrid((width + dimBlock.x - 1) / dimBlock.x, (height + dimBlock.y -1)/ dimBlock.y, + dim3 dimBlock(8, 8, 8); // 512 threads + dim3 dimGrid((width + dimBlock.x - 1) / dimBlock.x, (height + dimBlock.y - 1) / dimBlock.y, (depth + dimBlock.z - 1) / dimBlock.z); - hipLaunchKernelGGL(tex3DKernel, dimGrid, dimBlock, 0, 0, dData, - textureObject, width, height, depth, offsetX, offsetY, offsetZ); - HIP_CHECK(hipGetLastError()); + hipLaunchKernelGGL(tex3DKernel, dimGrid, dimBlock, 0, 0, dData, textureObject, + width, height, depth, offsetX, offsetY, offsetZ); + HIP_CHECK(hipGetLastError()); HIP_CHECK(hipDeviceSynchronize()); - float *hOutputData = (float*) malloc(size); + float* hOutputData = (float*)malloc(size); memset(hOutputData, 0, size); HIP_CHECK(hipMemcpy(hOutputData, dData, size, hipMemcpyDeviceToHost)); @@ -130,8 +137,8 @@ static void runTest(const int width, const int height, const int depth, const fl width, height, depth, offsetX + k, offsetY + j, offsetZ + i, hData); if (!hipTextureSamplingVerify(hOutputData[index], expectedValue)) { - INFO("Mismatch at (" << offsetX + k << ", " << offsetY + j << ", " << offsetZ + i << "):" << - hOutputData[index] << " expected:" << expectedValue); + INFO("Mismatch at (" << offsetX + k << ", " << offsetY + j << ", " << offsetZ + i + << "):" << hOutputData[index] << " expected:" << expectedValue); result = false; goto line1; } @@ -145,9 +152,20 @@ line1: HIP_CHECK(hipFreeArray(arr)); free(hData); REQUIRE(result); - } +/** + * Test Description + * ------------------------ + * - Uses different addressing and filtering modes for 3D arrays. + * Test source + * ------------------------ + * - unit/texture/hipTextureObj3DCheckModes.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipTextureObj3DCheckModes") { CHECK_IMAGE_SUPPORT @@ -159,58 +177,42 @@ TEST_CASE("Unit_hipTextureObj3DCheckModes") { } SECTION("hipAddressModeClamp, hipFilterModePoint, regularCoords") { - runTest - (256, 256, 256, -3.9, 6.1, 9.5); - runTest - (256, 256, 256, 4.4, -7.0, 5.3); + runTest(256, 256, 256, -3.9, 6.1, 9.5); + runTest(256, 256, 256, 4.4, -7.0, 5.3); } SECTION("hipAddressModeBorder, hipFilterModePoint, regularCoords") { - runTest - (256, 256, 256, -8.5, 2.9, 5.8); - runTest - (256, 256, 256, 12.5, 6.7, 11.4); + runTest(256, 256, 256, -8.5, 2.9, 5.8); + runTest(256, 256, 256, 12.5, 6.7, 11.4); } SECTION("hipAddressModeClamp, hipFilterModeLinear, regularCoords") { - runTest - (256, 256, 256, -0.4, -0.4, -0.4); - runTest - (256, 256, 256, 4, 14.6, -0.3); + runTest(256, 256, 256, -0.4, -0.4, -0.4); + runTest(256, 256, 256, 4, 14.6, -0.3); } SECTION("hipAddressModeBorder, hipFilterModeLinear, regularCoords") { - runTest - (256, 256, 256, 6.9, 7.4, 0.4); - runTest - (256, 256, 256, 12.5, 23.7, 0.34); + runTest(256, 256, 256, 6.9, 7.4, 0.4); + runTest(256, 256, 256, 12.5, 23.7, 0.34); } SECTION("hipAddressModeClamp, hipFilterModePoint, normalizedCoords") { - runTest - (256, 256, 256, -3, 8.9, -4); - runTest - (256, 256, 256, 4, -0.1, 8.2); + runTest(256, 256, 256, -3, 8.9, -4); + runTest(256, 256, 256, 4, -0.1, 8.2); } SECTION("hipAddressModeBorder, hipFilterModePoint, normalizedCoords") { - runTest - (256, 256, 256, -8.5, 15.9, 0.1); - runTest - (256, 256, 256, 12.5, -17.9, -0.35); + runTest(256, 256, 256, -8.5, 15.9, 0.1); + runTest(256, 256, 256, 12.5, -17.9, -0.35); } SECTION("hipAddressModeClamp, hipFilterModeLinear, normalizedCoords") { - runTest - (256, 256, 256, -3, 5.8, 0.89); - runTest - (256, 256, 256, 4, 9.1, 2.08); + runTest(256, 256, 256, -3, 5.8, 0.89); + runTest(256, 256, 256, 4, 9.1, 2.08); } SECTION("hipAddressModeBorder, hipFilterModeLinear, normalizedCoords") { - runTest - (256, 256, 256, -8.5, 6.6, 3.67); - runTest - (256, 256, 256, 12.5, 0.01, -9.9); + runTest(256, 256, 256, -8.5, 6.6, 3.67); + runTest(256, 256, 256, 12.5, 0.01, -9.9); } } diff --git a/catch/unit/texture/hipTextureObjectTests.cc b/catch/unit/texture/hipTextureObjectTests.cc new file mode 100644 index 0000000000..aa19fe2520 --- /dev/null +++ b/catch/unit/texture/hipTextureObjectTests.cc @@ -0,0 +1,369 @@ +/* +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, 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 + + +class TextureObjectTestWrapper { + private: + float* host_data_; + bool ommit_destroy_; + + public: + hipTextureObject_t texture_object = 0; + hipResourceDesc res_desc; + hipTextureDesc tex_desc; + hipChannelFormatDesc channel_desc; + hipResourceViewDesc res_vew_desc; + hipArray* array_member; + size_t size; /* size in bytes*/ + int width; /* width in elements */ + + TextureObjectTestWrapper(bool useResourceViewDescriptor, bool ommitDestroy = false) + : ommit_destroy_(ommitDestroy), width(128) { + int i; + size = width * sizeof(float); + + host_data_ = (float*)malloc(size); + memset(host_data_, 0, size); + + for (i = 0; i < width; i++) { + host_data_[i] = i; + } + + channel_desc = hipCreateChannelDesc(32, 0, 0, 0, hipChannelFormatKindFloat); + hipMallocArray(&array_member, &channel_desc, width); + + HIP_CHECK( + hipMemcpy2DToArray(array_member, 0, 0, host_data_, size, size, 1, hipMemcpyHostToDevice)); + + memset(&res_desc, 0, sizeof(res_desc)); + res_desc.resType = hipResourceTypeArray; + res_desc.res.array.array = array_member; + + memset(&tex_desc, 0, sizeof(tex_desc)); + tex_desc.addressMode[0] = hipAddressModeClamp; + tex_desc.filterMode = hipFilterModePoint; + tex_desc.readMode = hipReadModeElementType; + tex_desc.normalizedCoords = false; + + memset(&res_vew_desc, 0, sizeof(res_vew_desc)); + + if (useResourceViewDescriptor) { +#if HT_AMD + res_vew_desc.format = hipResViewFormatFloat1; + res_vew_desc.width = size; +#else + std::cout << "Resource View Descriptors are not supported on NVIDIA currently" << std::endl; + useResourceViewDescriptor = false; +#endif + } + + + HIP_CHECK(hipCreateTextureObject(&texture_object, &res_desc, &tex_desc, + useResourceViewDescriptor ? &res_vew_desc : nullptr)); + } + + ~TextureObjectTestWrapper() { + if (!ommit_destroy_) { + HIP_CHECK(hipDestroyTextureObject(texture_object)); + } + HIP_CHECK(hipFreeArray(array_member)); + free(host_data_); + } +}; + +/** + * @addtogroup hipGetTextureObjectResourceDesc hipGetTextureObjectResourceDesc + * @{ + * @ingroup TextureTest + * `hipError_t hipGetTextureObjectResourceDesc(hipResourceDesc* pResDesc, + * hipTextureObject_t textureObject)` - + * Gets resource descriptor for the texture object. + */ + +/** + * Test Description + * ------------------------ + * - Creates new texture object and an empty resource descriptor. + * - Gets resource descriptor from the texture. + * - Compares it to the empty created one. + * Test source + * ------------------------ + * - unit/texture/hipTextureObjectTests.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipGetTextureObjectResourceDesc_positive") { + CHECK_IMAGE_SUPPORT; + + TextureObjectTestWrapper tex_obj_wrapper(false); + + hipResourceDesc check_desc; + memset(&check_desc, 0, sizeof(check_desc)); + + HIP_CHECK(hipGetTextureObjectResourceDesc(&check_desc, tex_obj_wrapper.texture_object)); + + REQUIRE(check_desc.resType == tex_obj_wrapper.res_desc.resType); + REQUIRE(check_desc.res.array.array == tex_obj_wrapper.res_desc.res.array.array); +} + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When output pointer to the resource descriptor is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the texture is not valid (0) + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/texture/hipTextureObjectTests.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipGetTextureObjectResourceDesc_Negative_Parameters") { + CHECK_IMAGE_SUPPORT; + + TextureObjectTestWrapper tex_obj_wrapper(false); + + hipResourceDesc check_desc; + memset(&check_desc, 0, sizeof(check_desc)); + + SECTION("desc is nullptr") { + HIP_CHECK_ERROR(hipGetTextureObjectResourceDesc(nullptr, tex_obj_wrapper.texture_object), + hipErrorInvalidValue); + } + + SECTION("texture is invalid") { + HIP_CHECK_ERROR( + hipGetTextureObjectResourceDesc(&check_desc, static_cast(0)), + hipErrorInvalidValue); + } +} + +/** + * End doxygen group hipGetTextureObjectResourceDesc. + * @} + */ + +/** + * @addtogroup hipGetTextureObjectResourceViewDesc hipGetTextureObjectResourceViewDesc + * @{ + * @ingroup TextureTest + * `hipGetTextureObjectResourceViewDesc(struct hipResourceViewDesc* pResViewDesc, + * hipTextureObject_t textureObject)` - + * Gets resource view descriptor for the texture object. + */ + +/** + * Test Description + * ------------------------ + * - Creates new texture object and an empty resource view descriptor. + * - Gets resource view descriptor from the texture. + * - Compares it to the empty created one. + * Test source + * ------------------------ + * - unit/texture/hipTextureObjectTests.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ +#if HT_AMD +TEST_CASE("Unit_hipGetTextureObjectResourceViewDesc_positive") { + CHECK_IMAGE_SUPPORT; + + TextureObjectTestWrapper tex_obj_wrapper(true); + + hipResourceViewDesc check_desc; + memset(&check_desc, 0, sizeof(check_desc)); + + HIP_CHECK(hipGetTextureObjectResourceViewDesc(&check_desc, tex_obj_wrapper.texture_object)); + + REQUIRE(check_desc.format == tex_obj_wrapper.res_vew_desc.format); + REQUIRE(check_desc.width == tex_obj_wrapper.res_vew_desc.width); +} +#endif + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When output pointer to the resource view descriptor is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the texture is not valid (0) + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/texture/hipTextureObjectTests.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ +#if HT_AMD +TEST_CASE("Unit_hipGetTextureObjectResourceViewDesc_Negative_Parameters") { + CHECK_IMAGE_SUPPORT; + + TextureObjectTestWrapper tex_obj_wrapper(true); + + hipResourceViewDesc check_desc; + memset(&check_desc, 0, sizeof(check_desc)); + + SECTION("desc is nullptr") { + HIP_CHECK_ERROR(hipGetTextureObjectResourceViewDesc(nullptr, tex_obj_wrapper.texture_object), + hipErrorInvalidValue); + } + + SECTION("texture is invalid") { + HIP_CHECK_ERROR( + hipGetTextureObjectResourceViewDesc(&check_desc, static_cast(0)), + hipErrorInvalidValue); + } + + HipTest::HIP_SKIP_TEST("Skipping on NVIDIA platform"); +} +#endif + +/** + * End doxygen group hipGetTextureObjectResourceViewDesc. + * @} + */ + +/** + * @addtogroup hipGetTextureObjectTextureDesc hipGetTextureObjectTextureDesc + * @{ + * @ingroup TextureTest + * `hipGetTextureObjectTextureDesc(hipTextureDesc* pTexDesc, + * hipTextureObject_t textureObject)` - + * Gets texture descriptor for the texture object. + */ + +/** + * Test Description + * ------------------------ + * - Creates new texture object and an empty texture descriptor. + * - Gets texture descriptor from the texture. + * - Compares it to the empty created one. + * Test source + * ------------------------ + * - unit/texture/hipTextureObjectTests.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ +#if HT_AMD +TEST_CASE("Unit_hipGetTextureObjectTextureDesc_positive") { + CHECK_IMAGE_SUPPORT; + + TextureObjectTestWrapper tex_obj_wrapper(false); + + hipTextureDesc check_desc; + memset(&check_desc, 0, sizeof(check_desc)); + + HIP_CHECK(hipGetTextureObjectTextureDesc(&check_desc, tex_obj_wrapper.texture_object)); + + REQUIRE(check_desc.addressMode[0] == tex_obj_wrapper.tex_desc.addressMode[0]); + REQUIRE(check_desc.filterMode == tex_obj_wrapper.tex_desc.filterMode); + REQUIRE(check_desc.readMode == tex_obj_wrapper.tex_desc.readMode); + REQUIRE(check_desc.normalizedCoords == tex_obj_wrapper.tex_desc.normalizedCoords); +} +#endif + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When output pointer to the texture descriptor is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the texture is not valid (0) + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/texture/hipTextureObjectTests.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ +#if HT_AMD +TEST_CASE("Unit_hipGetTextureObjectTextureDesc_Negative_Parameters") { + CHECK_IMAGE_SUPPORT; + + TextureObjectTestWrapper tex_obj_wrapper(false); + + hipTextureDesc check_desc; + memset(&check_desc, 0, sizeof(check_desc)); + + SECTION("desc is nullptr") { + HIP_CHECK_ERROR(hipGetTextureObjectTextureDesc(nullptr, tex_obj_wrapper.texture_object), + hipErrorInvalidValue); + } + + SECTION("texture is invalid") { + HIP_CHECK_ERROR(hipGetTextureObjectTextureDesc(&check_desc, static_cast(0)), + hipErrorInvalidValue); + } +} +#endif + +/** + * End doxygen group hipGetTextureObjectTextureDesc. + * @} + */ + +/** + * @addtogroup hipDestroyTextureObject hipDestroyTextureObject + * @{ + * @ingroup TextureTest + * `hipDestroyTextureObject(hipTextureObject_t textureObject)` - + * Destroys a texture object. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipCreateTextureObject_ArgValidation + */ + +/** + * Test Description + * ------------------------ + * - Successfully destroys regular texture object. + * Test source + * ------------------------ + * - unit/texture/hipTextureObjectTests.cc + * Test requirements + * ------------------------ + * - Textures supported on device + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipDestroyTextureObject_positive") { + CHECK_IMAGE_SUPPORT; + + TextureObjectTestWrapper tex_obj_wrapper(false, true); + REQUIRE(hipDestroyTextureObject(tex_obj_wrapper.texture_object) == hipSuccess); +} From bca87f46a628ccc6b9ac6f4d68c20a93a29d423f Mon Sep 17 00:00:00 2001 From: Marko Veniger <91256249+marko-veniger@users.noreply.github.com> Date: Mon, 14 Aug 2023 17:17:29 +0200 Subject: [PATCH 04/30] EXSWHTEC-250 - Implement Performance Tests for Event APIs (#133) * Introduce performance tests to project. * Improve benchmarking utilities. * Delete copy constructors from Timer and Benchmark classes. * Disable Catch2's benchmarking functionalities. * Implement Performance Tests for Event APIs * Implement microbenchmarks for the Event Management APIs. * Add output modifier to Benchmark class. * Seperate hipEventCreateWithFlags and hipEventDestroy into seperate files. * Introduce command line options. * Update performance_common.hh --- catch/performance/CMakeLists.txt | 1 + catch/performance/event/CMakeLists.txt | 34 ++++++++ catch/performance/event/hipEventCreate.cc | 56 +++++++++++++ .../event/hipEventCreateWithFlags.cc | 83 +++++++++++++++++++ catch/performance/event/hipEventDestroy.cc | 54 ++++++++++++ .../performance/event/hipEventElapsedTime.cc | 68 +++++++++++++++ catch/performance/event/hipEventQuery.cc | 58 +++++++++++++ catch/performance/event/hipEventRecord.cc | 73 ++++++++++++++++ .../performance/event/hipEventSynchronize.cc | 70 ++++++++++++++++ 9 files changed, 497 insertions(+) create mode 100644 catch/performance/event/CMakeLists.txt create mode 100644 catch/performance/event/hipEventCreate.cc create mode 100644 catch/performance/event/hipEventCreateWithFlags.cc create mode 100644 catch/performance/event/hipEventDestroy.cc create mode 100644 catch/performance/event/hipEventElapsedTime.cc create mode 100644 catch/performance/event/hipEventQuery.cc create mode 100644 catch/performance/event/hipEventRecord.cc create mode 100644 catch/performance/event/hipEventSynchronize.cc diff --git a/catch/performance/CMakeLists.txt b/catch/performance/CMakeLists.txt index 5412636ebc..e1e159c6e5 100644 --- a/catch/performance/CMakeLists.txt +++ b/catch/performance/CMakeLists.txt @@ -18,4 +18,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. +add_subdirectory(event) add_subdirectory(example) diff --git a/catch/performance/event/CMakeLists.txt b/catch/performance/event/CMakeLists.txt new file mode 100644 index 0000000000..02a2c565dc --- /dev/null +++ b/catch/performance/event/CMakeLists.txt @@ -0,0 +1,34 @@ +# 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 + hipEventCreate.cc + hipEventCreateWithFlags.cc + hipEventRecord.cc + hipEventDestroy.cc + hipEventSynchronize.cc + hipEventElapsedTime.cc + hipEventQuery.cc +) + +hip_add_exe_to_target(NAME EventPerformance + TEST_SRC ${TEST_SRC} + TEST_TARGET_NAME build_tests + COMPILE_OPTIONS -std=c++17) \ No newline at end of file diff --git a/catch/performance/event/hipEventCreate.cc b/catch/performance/event/hipEventCreate.cc new file mode 100644 index 0000000000..5af6214c6a --- /dev/null +++ b/catch/performance/event/hipEventCreate.cc @@ -0,0 +1,56 @@ +/* +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 + +/** + * @addtogroup event event + * @{ + * @ingroup PerformanceTest + * Contains performance tests for all hipEvent related HIP APIs. + */ + +class HipEventCreateBenchmark : public Benchmark { + public: + void operator()() { + hipEvent_t event; + + TIMED_SECTION(kTimerTypeCpu) { HIP_CHECK(hipEventCreate(&event)); } + + HIP_CHECK(hipEventDestroy(event)); + } +}; + +/** + * Test Description + * ------------------------ + * - Executes `hipEventCreate` + * Test source + * ------------------------ + * - performance/event/hipEventCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Performance_hipEventCreate") { + HipEventCreateBenchmark benchmark; + benchmark.Run(); +} \ No newline at end of file diff --git a/catch/performance/event/hipEventCreateWithFlags.cc b/catch/performance/event/hipEventCreateWithFlags.cc new file mode 100644 index 0000000000..f69c5bed76 --- /dev/null +++ b/catch/performance/event/hipEventCreateWithFlags.cc @@ -0,0 +1,83 @@ +/* +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 + +/** + * @addtogroup event event + * @{ + * @ingroup PerformanceTest + */ + +class HipEventCreateWithFlagsBenchmark : public Benchmark { + public: + void operator()(unsigned flag) { + hipEvent_t event; + + TIMED_SECTION(kTimerTypeCpu) { HIP_CHECK(hipEventCreateWithFlags(&event, flag)); } + + HIP_CHECK(hipEventDestroy(event)); + } +}; + +static std::string GetEventCreateFlagName(unsigned flag) { + switch (flag) { + case hipEventDefault: + return "hipEventDefault"; + case hipEventBlockingSync: + return "hipEventBlockingSync"; + case hipEventDisableTiming: + return "hipEventDisableTiming"; + case hipEventInterprocess: + return "hipEventInterprocess"; + default: + return "flag combination"; + } +} + +static void RunBenchmark(unsigned flag) { + HipEventCreateWithFlagsBenchmark benchmark; + benchmark.AddSectionName(GetEventCreateFlagName(flag)); + benchmark.Run(flag); +} + +/** + * Test Description + * ------------------------ + * - Executes `hipEventCreateWithFlags` with all flags: + * -# Flags + * - hipEventDefault + * - hipEventBlockingSync + * - hipEventDisableTiming + * - hipEventInterprocess (currently disabled) + * Test source + * ------------------------ + * - performance/event/hipEventCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Performance_hipEventCreateWithFlags") { + const auto flag = GENERATE( + hipEventDefault, hipEventBlockingSync, + hipEventDisableTiming /*, hipEventInterprocess disabled until fixed (EXSWHTEC-25) */); + RunBenchmark(flag); +} \ No newline at end of file diff --git a/catch/performance/event/hipEventDestroy.cc b/catch/performance/event/hipEventDestroy.cc new file mode 100644 index 0000000000..0f3a8f63e0 --- /dev/null +++ b/catch/performance/event/hipEventDestroy.cc @@ -0,0 +1,54 @@ +/* +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 + +/** + * @addtogroup event event + * @{ + * @ingroup PerformanceTest + */ + +class HipEventDestroyBenchmark : public Benchmark { + public: + void operator()() { + hipEvent_t event; + HIP_CHECK(hipEventCreate(&event)); + + TIMED_SECTION(kTimerTypeCpu) { HIP_CHECK(hipEventDestroy(event)); } + } +}; + +/** + * Test Description + * ------------------------ + * - Executes `hipEventDestroy` + * Test source + * ------------------------ + * - performance/event/hipEventCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Performance_hipEventDestroy") { + HipEventDestroyBenchmark benchmark; + benchmark.Run(); +} \ No newline at end of file diff --git a/catch/performance/event/hipEventElapsedTime.cc b/catch/performance/event/hipEventElapsedTime.cc new file mode 100644 index 0000000000..9c6ac5696b --- /dev/null +++ b/catch/performance/event/hipEventElapsedTime.cc @@ -0,0 +1,68 @@ +/* +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 + +/** + * @addtogroup event event + * @{ + * @ingroup PerformanceTest + */ + +class HipEventElapsedTimeBenchmark : public Benchmark { + public: + void operator()() { + hipEvent_t start, end; + float time; + + HIP_CHECK(hipEventCreate(&start)); + HIP_CHECK(hipEventCreate(&end)); + + HIP_CHECK(hipEventRecord(start)); + std::this_thread::sleep_for(std::chrono::milliseconds(5)); /* idle for 5 ms */ + HIP_CHECK(hipEventRecord(end)); + HIP_CHECK(hipEventSynchronize(end)); + + TIMED_SECTION(kTimerTypeCpu) { HIP_CHECK(hipEventElapsedTime(&time, start, end)); } + + HIP_CHECK(hipEventDestroy(start)); + HIP_CHECK(hipEventDestroy(end)); + } +}; + +/** + * Test Description + * ------------------------ + * - Executes `hipEventElapsedTime` + * Test source + * ------------------------ + * - performance/event/hipEventElapsedTime.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Performance_hipEventElapsedTime") { + HipEventElapsedTimeBenchmark benchmark; + benchmark.Run(); +} diff --git a/catch/performance/event/hipEventQuery.cc b/catch/performance/event/hipEventQuery.cc new file mode 100644 index 0000000000..bc1e0656fe --- /dev/null +++ b/catch/performance/event/hipEventQuery.cc @@ -0,0 +1,58 @@ +/* +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 + +/** + * @addtogroup event event + * @{ + * @ingroup PerformanceTest + */ + +class HipEventQueryBenchmark : public Benchmark { + public: + void operator()() { + hipEvent_t event; + HIP_CHECK(hipEventCreate(&event)); + HIP_CHECK(hipEventRecord(event)); + HIP_CHECK(hipEventSynchronize(event)); + + TIMED_SECTION(kTimerTypeCpu) { HIP_CHECK(hipEventQuery(event)); } + + HIP_CHECK(hipEventDestroy(event)); + } +}; + +/** + * Test Description + * ------------------------ + * - Executes `hipEventQuery` + * Test source + * ------------------------ + * - performance/event/hipEventQuery.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Performance_hipEventQuery") { + HipEventQueryBenchmark benchmark; + benchmark.Run(); +} diff --git a/catch/performance/event/hipEventRecord.cc b/catch/performance/event/hipEventRecord.cc new file mode 100644 index 0000000000..df5f331b95 --- /dev/null +++ b/catch/performance/event/hipEventRecord.cc @@ -0,0 +1,73 @@ +/* +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 + +/** + * @addtogroup event event + * @{ + * @ingroup PerformanceTest + */ + +class HipEventRecordBenchmark : public Benchmark { + public: + void operator()(hipStream_t stream) { + hipEvent_t event; + HIP_CHECK(hipEventCreate(&event)); + + TIMED_SECTION(kTimerTypeCpu) { HIP_CHECK(hipEventRecord(event, stream)); } + + HIP_CHECK(hipEventDestroy(event)); + } +}; + +static void RunBenchmark(hipStream_t stream) { + HipEventRecordBenchmark benchmark; + if (stream == NULL) { + benchmark.AddSectionName("Default stream"); + } else { + benchmark.AddSectionName("Created stream"); + } + benchmark.Run(stream); +} + +/** + * Test Description + * ------------------------ + * - Executes `hipEventRecord` + * -# Executed both on + * - default stream + * - created stream + * Test source + * ------------------------ + * - performance/event/hipEventRecord.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Performance_hipEventRecord") { + SECTION("default stream") { RunBenchmark(nullptr); } + + SECTION("created stream") { + StreamGuard stream(Streams::created); + RunBenchmark(stream.stream()); + } +} diff --git a/catch/performance/event/hipEventSynchronize.cc b/catch/performance/event/hipEventSynchronize.cc new file mode 100644 index 0000000000..422f852501 --- /dev/null +++ b/catch/performance/event/hipEventSynchronize.cc @@ -0,0 +1,70 @@ +/* +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 + +/** + * @addtogroup event event + * @{ + * @ingroup PerformanceTest + */ + +class HipEventSynchronizeBenchmark : public Benchmark { + public: + void operator()(unsigned flag) { + hipEvent_t event; + HIP_CHECK(hipEventCreateWithFlags(&event, flag)); + HIP_CHECK(hipEventRecord(event)); + + TIMED_SECTION(kTimerTypeCpu) { HIP_CHECK(hipEventSynchronize(event)); } + + HIP_CHECK(hipEventDestroy(event)); + } +}; + +static void RunBenchmark(unsigned flag) { + HipEventSynchronizeBenchmark benchmark; + if (flag == hipEventDefault) { + benchmark.AddSectionName("Default event"); + } else { + benchmark.AddSectionName("Blocking sync event"); + } + benchmark.Run(flag); +} + +/** + * Test Description + * ------------------------ + * - Executes `hipEventSynchronize` + * -# Checked on events created with flags: + * - hipEventDefault + * - hipEventBlockingSync + * Test source + * ------------------------ + * - performance/event/hipEventSynchronize.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Performance_hipEventSynchronize") { + const auto flag = GENERATE(hipEventDefault, hipEventBlockingSync); + RunBenchmark(flag); +} From 08fa8258ec8ae0192f238e520315a81aa1730d61 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Mon, 14 Aug 2023 20:47:53 +0530 Subject: [PATCH 05/30] SWDEV-384714 - Add RTC test for half data type warp shfl functions (#202) Change-Id: I7cbf6932c928974236df2a49c7b5dee863da72ed --- catch/unit/rtc/CMakeLists.txt | 1 + catch/unit/rtc/shfl.cc | 197 ++++++++++++++++++++++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 catch/unit/rtc/shfl.cc diff --git a/catch/unit/rtc/CMakeLists.txt b/catch/unit/rtc/CMakeLists.txt index a1aea77c78..57b17b7807 100644 --- a/catch/unit/rtc/CMakeLists.txt +++ b/catch/unit/rtc/CMakeLists.txt @@ -11,6 +11,7 @@ set(AMD_TEST_SRC customOptions.cc hipRtcBfloat16.cc linker.cc + shfl.cc ) if(HIP_PLATFORM MATCHES "nvidia") diff --git a/catch/unit/rtc/shfl.cc b/catch/unit/rtc/shfl.cc new file mode 100644 index 0000000000..7059d7934f --- /dev/null +++ b/catch/unit/rtc/shfl.cc @@ -0,0 +1,197 @@ +/* +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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static constexpr int n = 32; + +static constexpr auto shfl { +R"( +template +__global__ void shflUpSum(T* a, int size) { + T val = a[threadIdx.x]; + for (unsigned int i = size / 2; i > 0; i /= 2) { + val += __shfl_up(val, i, size); + } + a[threadIdx.x] = val; +} + +template +__global__ void shflDownSum(T* a, int size) { + T val = a[threadIdx.x]; + for (int i = size / 2; i > 0; i /= 2) { + val += __shfl_down(val, i, size); + } + a[threadIdx.x] = val; +} + +template +__global__ void shflXorSum(T* a, int size) { + T val = a[threadIdx.x]; + for (int i = size/2; i > 0; i /= 2) + val += __shfl_xor(val, i, size); + a[threadIdx.x] = val; +} +)"}; + +void getFactor(int& fact) { fact = 101; } +void getFactor(__half& fact) { fact = 2.5; } + +template T sum(T* a) { + T cpuSum = 0; + T factor; + getFactor(factor); + for (int i = 0; i < n; i++) { + a[i] = i + factor; + cpuSum += a[i]; + } + return cpuSum; +} + +template bool compare(T gpuSum, T cpuSum) { + if (gpuSum != cpuSum) { + return true; + } + return false; +} + +template <> __half sum(__half* a) { + __half cpuSum = 0; + __half factor; + getFactor(factor); + for (int i = 0; i < n; i++) { + a[i] = i + __half2float(factor); + cpuSum = __half2float(cpuSum) + __half2float(a[i]); + } + return cpuSum; +} + +template <> bool compare(__half gpuSum, __half cpuSum) { + if (__half2float(gpuSum) != __half2float(cpuSum)) { + return true; + } + return false; +} + +template +void runTestShfl(int option) { + using namespace std; + hiprtcProgram prog; + hiprtcCreateProgram(&prog, // prog + shfl, // buffer + "shfl.cu", // name + 0, nullptr, nullptr); + + string str; + switch(option) { + case 1: + str = "shflUpSum<__half>"; break; + case 2: + str = "shflDownSum<__half>"; break; + case 3: + str = "shflXorSum<__half>"; break; + default: + INFO("Options 1,2,3 are supported, but the passed option is: " << option); + REQUIRE(false); + } + + hiprtcAddNameExpression(prog, str.c_str()); + + hiprtcResult compileResult{hiprtcCompileProgram(prog, 0, 0)}; + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + std::cout << log << '\n'; + } + REQUIRE(compileResult == HIPRTC_SUCCESS); + size_t codeSize; + HIPRTC_CHECK(hiprtcGetCodeSize(prog, &codeSize)); + + vector code(codeSize); + HIPRTC_CHECK(hiprtcGetCode(prog, code.data())); + + // Do hip malloc first so that we donot need to do a cuInit manually before calling hipModule APIs + size_t bufferSize = n * sizeof(T); + + T a[n]; + T cpuSum = sum(a); + T* d_a; + HIP_CHECK(hipMalloc(&d_a, bufferSize)); + + hipModule_t module; + hipFunction_t kernel; + HIP_CHECK(hipModuleLoadData(&module, code.data())); + const char* name; + hiprtcGetLoweredName(prog, str.c_str(), &name); + HIP_CHECK(hipModuleGetFunction(&kernel, module, name)); + + HIP_CHECK(hipMemcpy(d_a, &a, bufferSize, hipMemcpyDefault)); + + struct { + T* a_; + int b_; + } args{d_a, n}; + + auto size = sizeof(args); + void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, + HIP_LAUNCH_PARAM_END}; + + HIP_CHECK(hipModuleLaunchKernel(kernel, 1, 1, 1, n, 1, 1, 0, nullptr, nullptr, config)); + + HIP_CHECK(hipMemcpy(&a, d_a, bufferSize, hipMemcpyDefault)); + bool result; + switch (option) { + case 1: //shflUpSum + result = compare(a[n - 1], cpuSum); break; + case 2: //shflDownSum + case 3: //shflXorSum + result = compare(a[0], cpuSum); break; + } + + if (result) { + HIP_CHECK(hipFree(d_a)); + REQUIRE(false); + } + + HIP_CHECK(hipFree(d_a)); + HIP_CHECK(hipModuleUnload(module)); + HIPRTC_CHECK(hiprtcDestroyProgram(&prog)); + +} + +TEST_CASE("Unit_hiprtc_half_shuffle") { + runTestShfl<__half>(1); + runTestShfl<__half>(2); + runTestShfl<__half>(3); +} From 0b56a9d38c10f657f7190ffd28dc40c3c91b0afc Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Mon, 14 Aug 2023 20:50:29 +0530 Subject: [PATCH 06/30] SWDEV-383372 - [catch2][dtest] Adding corner and stress tests for hipHostMalloc(). (#208) Change-Id: I2308059e50a951a1e70de4f90fef9e2c76af21f1 --- .../config/config_amd_windows_MI2xx.json | 23 +++--- catch/stress/memory/hipHostMallocStress.cc | 54 ++++++++++--- catch/unit/memory/hipHostMalloc.cc | 76 +++++++++++++++++-- 3 files changed, 125 insertions(+), 28 deletions(-) diff --git a/catch/hipTestMain/config/config_amd_windows_MI2xx.json b/catch/hipTestMain/config/config_amd_windows_MI2xx.json index f5d29920e0..92ce9593a5 100644 --- a/catch/hipTestMain/config/config_amd_windows_MI2xx.json +++ b/catch/hipTestMain/config/config_amd_windows_MI2xx.json @@ -94,19 +94,20 @@ "Unit_hipGraphAddEventRecordNode_Functional_ElapsedTime", "Unit_hipStreamBeginCapture_captureComplexGraph", "Unit_hipGraphAddChildGraphNode_MultGraphsAsSingleGraph", - "Unit_hipMemGetAddressRange_Negative", + "Unit_hipMemGetAddressRange_Negative", "Unit_hipStreamValue_Wait64_Blocking_NoMask_Nor", "Unit_hipLaunchHostFunc_Graph", "Unit_hipLaunchHostFunc_KernelHost", - "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", - "Unit_hiprtc_saxpy.Unit_hiprtc_saxpy", - "Unit_hiprtc_warpsize.Unit_hiprtc_warpsize", - "Unit_hiprtc_functional.Unit_hiprtc_functional", - "Unit_hipStreamCaptureRtc.Unit_hipStreamCaptureRtc", - "Unit_hiprtc_cpp17.Unit_hiprtc_cpp17", - "Unit_hiprtc_namehandling.Unit_hiprtc_namehandling", - "Unit_hiprtc_getloweredname.Unit_hiprtc_getloweredname", - "Unit_hiprtc_test_hip_bfloat16.Unit_hiprtc_test_hip_bfloat16", - "Unit_RTC_LinkerAPI.Unit_RTC_LinkerAPI" + "Unit_hipDeviceGetUuid_Positive", + "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", + "Unit_hiprtc_saxpy.Unit_hiprtc_saxpy", + "Unit_hiprtc_warpsize.Unit_hiprtc_warpsize", + "Unit_hiprtc_functional.Unit_hiprtc_functional", + "Unit_hipStreamCaptureRtc.Unit_hipStreamCaptureRtc", + "Unit_hiprtc_cpp17.Unit_hiprtc_cpp17", + "Unit_hiprtc_namehandling.Unit_hiprtc_namehandling", + "Unit_hiprtc_getloweredname.Unit_hiprtc_getloweredname", + "Unit_hiprtc_test_hip_bfloat16.Unit_hiprtc_test_hip_bfloat16", + "Unit_RTC_LinkerAPI.Unit_RTC_LinkerAPI" ] } diff --git a/catch/stress/memory/hipHostMallocStress.cc b/catch/stress/memory/hipHostMallocStress.cc index da9fa977ff..bb48e7f54a 100644 --- a/catch/stress/memory/hipHostMallocStress.cc +++ b/catch/stress/memory/hipHostMallocStress.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 @@ -17,8 +17,10 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "hip_test_common.hh" -#include "hip_test_helper.hh" +#include +#include + +#define ADDITIONAL_MEMORY_PERCENT 10 // Stress allocation tests // Try to allocate as much memory as possible @@ -27,26 +29,60 @@ THE SOFTWARE. TEST_CASE("Stress_hipHostMalloc_MaxAllocation") { size_t devMemAvail{0}, devMemFree{0}; HIP_CHECK(hipMemGetInfo(&devMemFree, &devMemAvail)); - auto hostMemFree = HipTest::getMemoryAmount() /* In MB */ * 1024 * 1024; // In bytes + auto hostMemFree = HipTest::getMemoryAmount() * 1024 * 1024; // In bytes REQUIRE(devMemFree > 0); REQUIRE(devMemAvail > 0); REQUIRE(hostMemFree > 0); - - size_t memFree = std::min(devMemFree, hostMemFree); // which is the limiter cpu or gpu + // which is the limiter cpu or gpu + size_t memFree = std::min(devMemFree, hostMemFree); char* d_ptr{nullptr}; size_t counter{0}; INFO("Max Allocation of " << memFree << " bytes!"); while (hipHostMalloc(&d_ptr, memFree) != hipSuccess && memFree > 1) { counter++; - INFO("Attempt to allocate " << memFree << " bytes out of " << devMemFree << "bytes Failed!"); + INFO("Attempt to allocate " << memFree << \ + " bytes out of " << devMemFree << "bytes Failed!"); memFree >>= 1; // reduce the memory to be allocated by half - REQUIRE(counter <= 2); // Make sure that we are atleast able to allocate 1/4th of max memory + REQUIRE(counter <= 2); // Make sure that we are atleast able to allocate + // 1/4th of max memory } HIP_CHECK(hipMemset(d_ptr, 1, memFree)); HIP_CHECK(hipDeviceSynchronize()); // Flush caches - REQUIRE(std::all_of(d_ptr, d_ptr + memFree, [](unsigned char n) { return n == 1; })); + REQUIRE(std::all_of(d_ptr, d_ptr + memFree, + [](unsigned char n) { return n == 1; })); HIP_CHECK(hipHostFree(d_ptr)); } +// Allocate more memory than total GPU memory in each available GPU. +// hipHostMalloc should return hipSuccess. + +TEST_CASE("Stress_hipHostMalloc_MaxAllocation_AllGpu") { + char* A = nullptr; + size_t maxGpuMem = 0, availableMem = 0; + int count = 0; + HIP_CHECK(hipGetDeviceCount(&count)); + for (int dev = 0; dev < count; dev++) { + // Get available GPU memory and total GPU memory + HIP_CHECK(hipSetDevice(dev)); + HIP_CHECK(hipMemGetInfo(&availableMem, &maxGpuMem)); + size_t allocsize = maxGpuMem + + ((maxGpuMem*ADDITIONAL_MEMORY_PERCENT)/100); + // Get free host In bytes + size_t hostMemFree = HipTest::getMemoryAmount() * 1024 * 1024; + if (allocsize < hostMemFree) { + HIP_CHECK(hipHostMalloc(reinterpret_cast(&A), allocsize)); + // Check accessibility of memory + constexpr size_t samplesize = 1024; + constexpr int val = 32; + // Write at beginning of memory chunk for a size of samplesize + HIP_CHECK(hipMemset(A, val, samplesize)); + // Write at end of memory chunk for a size of samplesize + HIP_CHECK(hipMemset((A + allocsize - 1 - samplesize), val, samplesize)); + HIP_CHECK(hipHostFree(A)); + } else { + WARN("Skipping test as CPU memory is less than GPU memory"); + } + } +} diff --git a/catch/unit/memory/hipHostMalloc.cc b/catch/unit/memory/hipHostMalloc.cc index f0b1fafe8d..bebea366bf 100644 --- a/catch/unit/memory/hipHostMalloc.cc +++ b/catch/unit/memory/hipHostMalloc.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2021 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 @@ -29,19 +29,30 @@ This testfile verifies the following scenarios of hipHostMalloc API 5. Allocating memory using hipHostMalloc with default flag */ -#include -#include -#include +#include +#include +#include #include +#include #define SYNC_EVENT 0 #define SYNC_STREAM 1 #define SYNC_DEVICE 2 +#define ADDITIONAL_MEMORY_PERCENT 10 +#define BLOCK_SIZE 512 +#define VALUE 32 std::vector syncMsg = {"event", "stream", "device"}; static constexpr int numElements{1024 * 16}; static constexpr size_t sizeBytes{numElements * sizeof(int)}; +#if HT_AMD +static __global__ void kerTestMemAccess(char *buf) { + int myId = threadIdx.x + blockDim.x * blockIdx.x; + buf[myId] = VALUE; +} +#endif + void CheckHostPointer(int numElements, int* ptr, unsigned eventFlags, int syncMethod, std::string msg) { std::cerr << "test: CheckHostPointer " @@ -134,8 +145,8 @@ TEST_CASE("Unit_hipHostMalloc_Basic") { dim3 dimGrid(LEN / 512, 1, 1); dim3 dimBlock(512, 1, 1); HipTest::launchKernel(HipTest::vectorADD, dimGrid, dimBlock, - 0, 0, static_cast(A_d), - static_cast(B_d), C_d, static_cast(LEN)); + 0, 0, static_cast(A_d), + static_cast(B_d), C_d, static_cast(LEN)); HIP_CHECK(hipMemcpy(C_h, C_d, LEN*sizeof(float), hipMemcpyDeviceToHost)); HIP_CHECK(hipDeviceSynchronize()); @@ -229,16 +240,65 @@ TEST_CASE("Unit_hipHostMalloc_Default") { CheckHostPointer(numElements, A, 0, SYNC_DEVICE, ptrType); CheckHostPointer(numElements, A, 0, SYNC_STREAM, ptrType); CheckHostPointer(numElements, A, 0, SYNC_EVENT, ptrType); - } TEST_CASE("Unit_hipHostGetDevicePointer_NullCheck") { int* d_a; HIP_CHECK(hipHostMalloc(reinterpret_cast(&d_a), sizeof(int))); - auto res = hipHostGetDevicePointer(nullptr,d_a,0); + auto res = hipHostGetDevicePointer(nullptr, d_a, 0); REQUIRE(res == hipErrorInvalidValue); HIP_CHECK(hipHostFree(d_a)); } +/* +This testcase verifies the hipHostMalloc API by +1. Allocating more memory than total GPU memory. Should return hipSuccess. +2. Allocating more memory than the total GPU memory and accessing the memory + in a device function. +*/ +TEST_CASE("Unit_hipHostMalloc_AllocateMoreThanAvailGPUMemory") { + char* A = nullptr; + size_t maxGpuMem = 0, availableMem = 0; + // Get available GPU memory and total GPU memory + HIP_CHECK(hipMemGetInfo(&availableMem, &maxGpuMem)); + size_t allocsize = maxGpuMem + + ((maxGpuMem*ADDITIONAL_MEMORY_PERCENT)/100); + // Get free host In bytes + size_t hostMemFree = HipTest::getMemoryAmount() * 1024 * 1024; + // Ensure that allocsize < hostMemFree + if (allocsize < hostMemFree) { + HIP_CHECK(hipHostMalloc(reinterpret_cast(&A), allocsize)); + HIP_CHECK(hipHostFree(A)); + } else { + WARN("Skipping test as CPU memory is less than GPU memory"); + } +} + +#if HT_AMD +TEST_CASE("Unit_hipHostMalloc_AllocateUseMoreThanAvailGPUMemory") { + char* A = nullptr; + size_t maxGpuMem = 0, availableMem = 0; + // Get available GPU memory and total GPU memory + HIP_CHECK(hipMemGetInfo(&availableMem, &maxGpuMem)); + size_t allocsize = maxGpuMem + + ((maxGpuMem*ADDITIONAL_MEMORY_PERCENT)/100); + // Get free host In bytes + size_t hostMemFree = HipTest::getMemoryAmount() * 1024 * 1024; + // Ensure that allocsize < hostMemFree + if (allocsize < hostMemFree) { + HIP_CHECK(hipHostMalloc(reinterpret_cast(&A), allocsize)); + constexpr int sample_size = 1024; + // memset a sample size to 0 + HIP_CHECK(hipMemset(A, 0, sample_size)); + unsigned int grid_size = allocsize/BLOCK_SIZE; + // Check if the allocated memory can be accessed in kernels + kerTestMemAccess<<>>(A); + HIP_CHECK(hipDeviceSynchronize()); + HIP_CHECK(hipHostFree(A)); + } else { + WARN("Skipping test as CPU memory is less than GPU memory"); + } +} +#endif From cdf434b3573f871000c72388a89f623a5f2941b2 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Mon, 14 Aug 2023 20:52:06 +0530 Subject: [PATCH 07/30] SWDEV-386902 - [catch2][dtest] Test case to verify hipStreamCreate Performance (#222) Change-Id: I8e6695a4e9214bc9ade598be993e1cbf0b1d210d --- .../config/config_nvidia_linux_common.json | 13 +- catch/unit/stream/CMakeLists.txt | 1 + .../unit/stream/hipStreamCreatePerformance.cc | 544 ++++++++++++++++++ 3 files changed, 554 insertions(+), 4 deletions(-) create mode 100644 catch/unit/stream/hipStreamCreatePerformance.cc diff --git a/catch/hipTestMain/config/config_nvidia_linux_common.json b/catch/hipTestMain/config/config_nvidia_linux_common.json index 691386f1a1..07b62e9329 100644 --- a/catch/hipTestMain/config/config_nvidia_linux_common.json +++ b/catch/hipTestMain/config/config_nvidia_linux_common.json @@ -21,11 +21,16 @@ "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", + "=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/222 ===", + "Unit_hipStreamCreate_Performance", + "Unit_hipStreamCreate_WithPriorityPerformance_Nonblocking_high", + "Unit_hipStreamCreate_WithPriorityPerformance_Default_low", + "Unit_hipStreamCreate_WithPriorityPerformance_Nonblocking_low", "=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/92 ===", "Unit_hipGetTexObjectResourceDesc_positive", - "Unit_hipGetTexObjectResourceDesc_Negative_Parameters", - "Unit_hipGetTexObjectTextureDesc_positive", - "Unit_hipGetTexObjectTextureDesc_Negative_Parameters", - "Unit_hipTexObjectDestroy_positive" + "Unit_hipGetTexObjectResourceDesc_Negative_Parameters", + "Unit_hipGetTexObjectTextureDesc_positive", + "Unit_hipGetTexObjectTextureDesc_Negative_Parameters", + "Unit_hipTexObjectDestroy_positive" ] } diff --git a/catch/unit/stream/CMakeLists.txt b/catch/unit/stream/CMakeLists.txt index 267b00d38a..5c0f349e27 100644 --- a/catch/unit/stream/CMakeLists.txt +++ b/catch/unit/stream/CMakeLists.txt @@ -17,6 +17,7 @@ set(TEST_SRC hipStreamACb_StrmSyncTiming.cc hipLaunchHostFunc.cc hipStreamGetDevice.cc + hipStreamCreatePerformance.cc ) if(HIP_PLATFORM MATCHES "amd") diff --git a/catch/unit/stream/hipStreamCreatePerformance.cc b/catch/unit/stream/hipStreamCreatePerformance.cc new file mode 100644 index 0000000000..999a4fe7bf --- /dev/null +++ b/catch/unit/stream/hipStreamCreatePerformance.cc @@ -0,0 +1,544 @@ +/* +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 +#include +#include +#include + +/** + * @addtogroup hipStreamCreate hipStreamCreate + * @{ + * @ingroup StreamTest + * `hipError_t hipStreamCreate(hipStream_t* stream)` - + * Create a new asynchronous stream. + */ + +/** + * Test Description + * ------------------------ + * - Test case to verify hipStreamCreate performance by recording below sets of time. + * create 4 set of streams and record that time taken as b1 + * create another 4 set of streams before destroying earlier streams and record time taken as b2 + * destroy streams and then create 4 streams again and record time taken as b3 + * and verify if the condition b1 > b2 > b3 is satisfied. + + * Test source + * ------------------------ + * - catch/unit/stream/hipStreamCreatePerformance.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ + +TEST_CASE("Unit_hipStreamCreate_Performance") { + HIP_CHECK(hipSetDevice(0)); // just to initialise HIP runtime. + // create stream + hipStream_t streamb1[4]; + // record time for batch1 stream creation + auto Startb1 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreate(&streamb1[k])); + } + auto Stopb1 = std::chrono::high_resolution_clock::now(); + double performb1 = std::chrono::duration(Stopb1 - Startb1).count(); // NOLINT + printf("Stream create performance for batch1 is %lf\n", performb1); + + // record time for batch2 stream creation before + // destroying already created streams + hipStream_t streamb2[4]; + auto Startb2 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreate(&streamb2[k])); + } + auto Stopb2 = std::chrono::high_resolution_clock::now(); + double performb2 = std::chrono::duration(Stopb2 - Startb2).count(); // NOLINT + printf("Stream create performance for batch2 is %lf\n", performb2); + // destroy batch 1 streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb1[k])); + } + // destroy batch 2 streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb2[k])); + } + // record time for batch3 stream creation after stream destroy + hipStream_t streamb3[4]; + auto Startb3 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreate(&streamb3[k])); + } + auto Stopb3 = std::chrono::high_resolution_clock::now(); + double performb3 = std::chrono::duration(Stopb3 - Startb3).count(); // NOLINT + printf("Stream create performance for batch3 is %lf\n", performb3); + + // destroy streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb3[k])); + } + REQUIRE(performb1 > performb2); + REQUIRE(performb2 > performb3); +} + +/** + * End doxygen group hipStreamCreate. + * @} + */ + +/** + * @addtogroup hipStreamCreateWithFlags hipStreamCreateWithFlags + * @{ + * @ingroup StreamTest + * `hipError_t hipStreamCreateWithFlags(hipStream_t* stream, unsigned int flags)` - + * Create a new asynchronous stream. + */ + +/** + * Test Description + * ------------------------ + * - Test case to verify hipStreamCreateWithFlags performance with + * hipStreamNonBlocking flagby recording below sets of time. + * create 4 set of streams and record that time taken as b1 + * create another 4 set of streams before destroying earlier streams + * and record time taken as b2 + * destroy streams and then create 4 streams again and record time taken as b3 + * and verify if the condition b1 > b2 > b3 is satisfied. + + * Test source + * ------------------------ + * - catch/unit/stream/hipStreamCreatePerformance.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ + +TEST_CASE("Unit_hipStreamCreate_WithFlagsPerformance_Nonblocking") { + HIP_CHECK(hipSetDevice(0)); // just to initialise HIP runtime. + // create stream + hipStream_t streamb1[4]; + // record time for batch1 stream creation + auto Startb1 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreateWithFlags(&streamb1[k], hipStreamNonBlocking)); + } + auto Stopb1 = std::chrono::high_resolution_clock::now(); + double performb1 = std::chrono::duration(Stopb1 - Startb1).count(); // NOLINT + printf("Stream create performance for batch1 is %lf\n", performb1); + + // record time for batch2 stream creation before + // destroying already created streams + hipStream_t streamb2[4]; + auto Startb2 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreateWithFlags(&streamb2[k], hipStreamNonBlocking)); + } + auto Stopb2 = std::chrono::high_resolution_clock::now(); + double performb2 = std::chrono::duration(Stopb2 - Startb2).count(); // NOLINT + printf("Stream create performance for batch2 is %lf\n", performb2); + // destroy batch 1 streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb1[k])); + } + // destroy batch 2 streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb2[k])); + } + // record time for batch3 stream creation after stream destroy + hipStream_t streamb3[4]; + auto Startb3 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreateWithFlags(&streamb3[k], hipStreamNonBlocking)); + } + auto Stopb3 = std::chrono::high_resolution_clock::now(); + double performb3 = std::chrono::duration(Stopb3 - Startb3).count(); // NOLINT + printf("Stream create performance for batch3 is %lf\n", performb3); + + // destroy streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb3[k])); + } + REQUIRE(performb1 > performb2); + REQUIRE(performb2 > performb3); +} + +/** + * Test Description + * ------------------------ + * - Test case to verify hipStreamCreateWithFlags performance + * with hipStreamDefault flagby recording below sets of time. + * create 4 set of streams and record that time taken as b1 + * create another 4 set of streams before destroying earlier streams + * and record time taken as b2 + * destroy streams and then create 4 streams again and record time taken as b3 + * and verify if the condition b1 > b2 > b3 is satisfied. + + * Test source + * ------------------------ + * - catch/unit/stream/hipStreamCreatePerformance.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ + +TEST_CASE("Unit_hipStreamCreate_WithFlagsPerformance_Default") { + HIP_CHECK(hipSetDevice(0)); // just to initialise HIP runtime. + // create stream + hipStream_t streamb1[4]; + // record time for batch1 stream creation + auto Startb1 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreateWithFlags(&streamb1[k], hipStreamDefault)); + } + auto Stopb1 = std::chrono::high_resolution_clock::now(); + double performb1 = std::chrono::duration(Stopb1 - Startb1).count(); // NOLINT + printf("Stream create performance for batch1 is %lf\n", performb1); + + // record time for batch2 stream creation before + // destroying already created streams + hipStream_t streamb2[4]; + auto Startb2 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreateWithFlags(&streamb2[k], hipStreamDefault)); + } + auto Stopb2 = std::chrono::high_resolution_clock::now(); + double performb2 = std::chrono::duration(Stopb2 - Startb2).count(); // NOLINT + printf("Stream create performance for batch2 is %lf\n", performb2); + // destroy batch 1 streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb1[k])); + } + // destroy batch 2 streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb2[k])); + } + // record time for batch3 stream creation after stream destroy + hipStream_t streamb3[4]; + auto Startb3 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreateWithFlags(&streamb3[k], hipStreamDefault)); + } + auto Stopb3 = std::chrono::high_resolution_clock::now(); + double performb3 = std::chrono::duration(Stopb3 - Startb3).count(); // NOLINT + printf("Stream create performance for batch3 is %lf\n", performb3); + + // destroy streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb3[k])); + } + REQUIRE(performb1 > performb2); + REQUIRE(performb2 > performb3); +} +/** + * End doxygen group hipStreamCreateWithFlags. + * @} + */ + +/** + * @addtogroup hipStreamCreateWithPriority hipStreamCreateWithPriority + * @{ + * @ingroup StreamTest + * `hipError_t hipStreamCreateWithPriority(hipStream_t* stream, unsigned int flags, int priority)` - + * Create a new asynchronous stream. + */ + +/** + * Test Description + * ------------------------ + * - Test case to verify hipStreamCreateWithPriority performance + * with hipStreamNonBlocking flag along with low priority + * by recording below sets of time. + * create 4 set of streams and record that time taken as b1 + * create another 4 set of streams before destroying earlier streams + * and record time taken as b2 + * destroy streams and then create 4 streams again and record time taken as b3 + * and verify if the condition b1 > b2 > b3 is satisfied. + + * Test source + * ------------------------ + * - catch/unit/stream/hipStreamCreatePerformance.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ + +TEST_CASE("Unit_hipStreamCreate_WithPriorityPerformance_Nonblocking_low") { + int priority_low, priority_high; + HIP_CHECK(hipSetDevice(0)); // just to initialise HIP runtime. + HIP_CHECK(hipDeviceGetStreamPriorityRange(&priority_low, &priority_high)); + // create stream + hipStream_t streamb1[4]; + // record time for batch1 stream creation + auto Startb1 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreateWithPriority(&streamb1[k], hipStreamNonBlocking, priority_low)); + } + auto Stopb1 = std::chrono::high_resolution_clock::now(); + double performb1 = std::chrono::duration(Stopb1 - Startb1).count(); // NOLINT + printf("Stream create performance for batch1 is %lf\n", performb1); + + // record time for batch2 stream creation before + // destroying already created streams + hipStream_t streamb2[4]; + auto Startb2 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreateWithPriority(&streamb2[k], hipStreamNonBlocking, priority_low)); + } + auto Stopb2 = std::chrono::high_resolution_clock::now(); + double performb2 = std::chrono::duration(Stopb2 - Startb2).count(); // NOLINT + printf("Stream create performance for batch2 is %lf\n", performb2); + // destroy batch 1 streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb1[k])); + } + // destroy batch 2 streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb2[k])); + } + // record time for batch3 stream creation after stream destroy + hipStream_t streamb3[4]; + auto Startb3 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreateWithPriority(&streamb3[k], hipStreamNonBlocking, priority_low)); + } + auto Stopb3 = std::chrono::high_resolution_clock::now(); + double performb3 = std::chrono::duration(Stopb3 - Startb3).count(); // NOLINT + printf("Stream create performance for batch3 is %lf\n", performb3); + + // destroy streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb3[k])); + } + REQUIRE(performb1 > performb2); + REQUIRE(performb2 > performb3); +} + +/** + * Test Description + * ------------------------ + * - Test case to verify hipStreamCreateWithPriority performance + * with hipStreamNonBlocking flag along with high priority + * by recording below sets of time. + * create 4 set of streams and record that time taken as b1 + * create another 4 set of streams before destroying earlier streams + * and record time taken as b2 + * destroy streams and then create 4 streams again and record time taken as b3 + * and verify if the condition b1 > b2 > b3 is satisfied. + + * Test source + * ------------------------ + * - catch/unit/stream/hipStreamCreatePerformance.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ + +TEST_CASE("Unit_hipStreamCreate_WithPriorityPerformance_Nonblocking_high") { + int priority_low, priority_high; + HIP_CHECK(hipSetDevice(0)); // just to initialise HIP runtime. + HIP_CHECK(hipDeviceGetStreamPriorityRange(&priority_low, &priority_high)); + // create stream + hipStream_t streamb1[4]; + // record time for batch1 stream creation + auto Startb1 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreateWithPriority(&streamb1[k], hipStreamNonBlocking, priority_high)); + } + auto Stopb1 = std::chrono::high_resolution_clock::now(); + double performb1 = std::chrono::duration(Stopb1 - Startb1).count(); // NOLINT + printf("Stream create performance for batch1 is %lf\n", performb1); + + // record time for batch2 stream creation before + // destroying already created streams + hipStream_t streamb2[4]; + auto Startb2 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreateWithPriority(&streamb2[k], hipStreamNonBlocking, priority_high)); + } + auto Stopb2 = std::chrono::high_resolution_clock::now(); + double performb2 = std::chrono::duration(Stopb2 - Startb2).count(); // NOLINT + printf("Stream create performance for batch2 is %lf\n", performb2); + // destroy batch 1 streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb1[k])); + } + // destroy batch 2 streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb2[k])); + } + // record time for batch3 stream creation after stream destroy + hipStream_t streamb3[4]; + auto Startb3 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreateWithPriority(&streamb3[k], hipStreamNonBlocking, priority_high)); + } + auto Stopb3 = std::chrono::high_resolution_clock::now(); + double performb3 = std::chrono::duration(Stopb3 - Startb3).count(); // NOLINT + printf("Stream create performance for batch3 is %lf\n", performb3); + + // destroy streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb3[k])); + } + REQUIRE(performb1 > performb2); + REQUIRE(performb2 > performb3); +} + +/** + * Test Description + * ------------------------ + * - Test case to verify hipStreamCreateWithPriority performance + * with hipStreamDefault flag along with low priority by recording below sets of time. + * create 4 set of streams and record that time taken as b1 + * create another 4 set of streams before destroying earlier streams + * and record time taken as b2 + * destroy streams and then create 4 streams again and record time taken as b3 + * and verify if the condition b1 > b2 > b3 is satisfied. + + * Test source + * ------------------------ + * - catch/unit/stream/hipStreamCreatePerformance.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ + +TEST_CASE("Unit_hipStreamCreate_WithPriorityPerformance_Default_low") { + int priority_low, priority_high; + HIP_CHECK(hipSetDevice(0)); // just to initialise HIP runtime. + HIP_CHECK(hipDeviceGetStreamPriorityRange(&priority_low, &priority_high)); + // create stream + hipStream_t streamb1[4]; + // record time for batch1 stream creation + auto Startb1 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreateWithPriority(&streamb1[k], hipStreamDefault, priority_low)); + } + auto Stopb1 = std::chrono::high_resolution_clock::now(); + double performb1 = std::chrono::duration(Stopb1 - Startb1).count(); // NOLINT + printf("Stream create performance for batch1 is %lf\n", performb1); + + // record time for batch2 stream creation before + // destroying already created streams + hipStream_t streamb2[4]; + auto Startb2 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreateWithPriority(&streamb2[k], hipStreamDefault, priority_low)); + } + auto Stopb2 = std::chrono::high_resolution_clock::now(); + double performb2 = std::chrono::duration(Stopb2 - Startb2).count(); // NOLINT + printf("Stream create performance for batch2 is %lf\n", performb2); + // destroy batch 1 streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb1[k])); + } + // destroy batch 2 streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb2[k])); + } + // record time for batch3 stream creation after stream destroy + hipStream_t streamb3[4]; + auto Startb3 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreateWithPriority(&streamb3[k], hipStreamDefault, priority_low)); + } + auto Stopb3 = std::chrono::high_resolution_clock::now(); + double performb3 = std::chrono::duration(Stopb3 - Startb3).count(); // NOLINT + printf("Stream create performance for batch3 is %lf\n", performb3); + + // destroy streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb3[k])); + } + REQUIRE(performb1 > performb2); + REQUIRE(performb2 > performb3); +} + +/** + * Test Description + * ------------------------ + * - Test case to verify hipStreamCreateWithPriority performance + * with hipStreamDefault flag along with high priority by recording below sets of time. + * create 4 set of streams and record that time taken as b1 + * create another 4 set of streams before destroying earlier streams + * and record time taken as b2 + * destroy streams and then create 4 streams again and record time taken as b3 + * and verify if the condition b1 > b2 > b3 is satisfied. + + * Test source + * ------------------------ + * - catch/unit/stream/hipStreamCreatePerformance.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ + +TEST_CASE("Unit_hipStreamCreate_WithPriorityPerformance_Default_high") { + int priority_low = 1, priority_high = 2; + HIP_CHECK(hipSetDevice(0)); // just to initialise HIP runtime. + HIP_CHECK(hipDeviceGetStreamPriorityRange(&priority_low, &priority_high)); + // create stream + hipStream_t streamb1[4]; + // record time for batch1 stream creation + auto Startb1 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreateWithPriority(&streamb1[k], hipStreamDefault, priority_high)); + } + auto Stopb1 = std::chrono::high_resolution_clock::now(); + double performb1 = std::chrono::duration(Stopb1 - Startb1).count(); // NOLINT + printf("Stream create performance for batch1 is %lf\n", performb1); + + // record time for batch2 stream creation before + // destroying already created streams + hipStream_t streamb2[4]; + auto Startb2 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreateWithPriority(&streamb2[k], hipStreamDefault, priority_high)); + } + auto Stopb2 = std::chrono::high_resolution_clock::now(); + double performb2 = std::chrono::duration(Stopb2 - Startb2).count(); // NOLINT + printf("Stream create performance for batch2 is %lf\n", performb2); + // destroy batch 1 streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb1[k])); + } + // destroy batch 2 streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb2[k])); + } + // record time for batch3 stream creation after stream destroy + hipStream_t streamb3[4]; + auto Startb3 = std::chrono::high_resolution_clock::now(); + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamCreateWithPriority(&streamb3[k], hipStreamDefault, priority_high)); + } + auto Stopb3 = std::chrono::high_resolution_clock::now(); + double performb3 = std::chrono::duration(Stopb3 - Startb3).count(); // NOLINT + printf("Stream create performance for batch3 is %lf\n", performb3); + + // destroy streams + for (int k = 0; k < 4; k++) { + HIP_CHECK(hipStreamDestroy(streamb3[k])); + } + REQUIRE(performb1 > performb2); + REQUIRE(performb2 > performb3); +} +/** + * End doxygen group hipStreamCreateWithPriority. + * @} + */ From 3447a59895cbd459e83a088a95d563f9faa3bf10 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Mon, 14 Aug 2023 20:52:26 +0530 Subject: [PATCH 08/30] SWDEV-380340 - [catch2][dtest] DeviceLib tests migrated from direct to catch2 (#225) Change-Id: Ie2ec1c7dabdfedbe0bd36fd2525df7dc9d9ba2e5 --- catch/unit/deviceLib/CMakeLists.txt | 46 ++ catch/unit/deviceLib/hipBfloat16.cc | 130 ++++ catch/unit/deviceLib/hipComplex.cc | 438 ++++++++++++ catch/unit/deviceLib/hipDeviceMemcpy.cc | 60 ++ catch/unit/deviceLib/hipTestDevice.cc | 736 ++++++++++++++++++++ catch/unit/deviceLib/hipTestDeviceDouble.cc | 630 +++++++++++++++++ catch/unit/deviceLib/hipTestDeviceLimit.cc | 24 + catch/unit/deviceLib/hipTestDeviceSymbol.cc | 124 ++-- catch/unit/deviceLib/hipTestDotFunctions.cc | 54 ++ catch/unit/deviceLib/hipTestFMA.cc | 183 +++++ catch/unit/deviceLib/hipTestHalf.cc | 245 +++++++ catch/unit/deviceLib/hipTestHost.cc | 408 +++++++++++ catch/unit/deviceLib/hipTestIncludeMath.cc | 134 ++++ catch/unit/deviceLib/hipTestNativeHalf.cc | 169 +++++ catch/unit/deviceLib/hipTestNew.cc | 54 ++ catch/unit/deviceLib/hipThreadFence.cc | 76 ++ catch/unit/deviceLib/hipVectorTypes.cc | 204 ++++++ catch/unit/deviceLib/hip_test_make_type.cc | 334 +++++++++ catch/unit/deviceLib/hip_trig.cc | 86 +++ 19 files changed, 4074 insertions(+), 61 deletions(-) create mode 100644 catch/unit/deviceLib/hipBfloat16.cc create mode 100644 catch/unit/deviceLib/hipComplex.cc create mode 100644 catch/unit/deviceLib/hipDeviceMemcpy.cc create mode 100644 catch/unit/deviceLib/hipTestDevice.cc create mode 100644 catch/unit/deviceLib/hipTestDeviceDouble.cc create mode 100644 catch/unit/deviceLib/hipTestDeviceLimit.cc create mode 100644 catch/unit/deviceLib/hipTestDotFunctions.cc create mode 100644 catch/unit/deviceLib/hipTestFMA.cc create mode 100644 catch/unit/deviceLib/hipTestHalf.cc create mode 100644 catch/unit/deviceLib/hipTestHost.cc create mode 100644 catch/unit/deviceLib/hipTestIncludeMath.cc create mode 100644 catch/unit/deviceLib/hipTestNativeHalf.cc create mode 100644 catch/unit/deviceLib/hipTestNew.cc create mode 100644 catch/unit/deviceLib/hipThreadFence.cc create mode 100644 catch/unit/deviceLib/hipVectorTypes.cc create mode 100644 catch/unit/deviceLib/hip_test_make_type.cc create mode 100644 catch/unit/deviceLib/hip_trig.cc diff --git a/catch/unit/deviceLib/CMakeLists.txt b/catch/unit/deviceLib/CMakeLists.txt index b2718f39bb..5317d42ca5 100644 --- a/catch/unit/deviceLib/CMakeLists.txt +++ b/catch/unit/deviceLib/CMakeLists.txt @@ -1,3 +1,23 @@ +# 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 set(TEST_SRC floatMath.cc @@ -27,7 +47,26 @@ set(TEST_SRC hipTestAtomicAdd.cc hipStdComplex.cc hipTestClock.cc + hip_trig.cc + hipDeviceMemcpy.cc + hipTestIncludeMath.cc + hipTestDotFunctions.cc + hipTestDeviceSymbol.cc + hipTestNew.cc + hipThreadFence.cc + hipTestDevice.cc + hipTestDeviceLimit.cc + hipTestDeviceDouble.cc + hipTestHost.cc ) +if(HIP_PLATFORM MATCHES "nvidia") + set_source_files_properties(hipTestHost.cc PROPERTIES COMPILE_OPTIONS "--expt-relaxed-constexpr") +endif() + +if(UNIX) + set(TEST_SRC ${TEST_SRC} + deviceAllocation.cc) +endif() # AMD only tests set(AMD_TEST_SRC @@ -38,6 +77,13 @@ set(AMD_TEST_SRC floatTM.cc hipMathFunctions.cc hmax_hmin.cc + hipBfloat16.cc + hipVectorTypes.cc + hipTestHalf.cc + hipComplex.cc + hipTestFMA.cc + hipTestNativeHalf.cc + hip_test_make_type.cc bfloat16.cc ) set(AMD_ARCH_SPEC_TEST_SRC diff --git a/catch/unit/deviceLib/hipBfloat16.cc b/catch/unit/deviceLib/hipBfloat16.cc new file mode 100644 index 0000000000..f87ab48ddf --- /dev/null +++ b/catch/unit/deviceLib/hipBfloat16.cc @@ -0,0 +1,130 @@ +/* +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 + +#define SIZE 100 + +static std::random_device dev; +static std::mt19937 rng(dev()); + +inline float getRandomFloat(int16_t min = 10, int64_t max = LONG_MAX) { + std::uniform_real_distribution gen(min, max); + return gen(rng); +} +__host__ __device__ bool testRelativeAccuracy(float a, hip_bfloat16 b) { + float c = static_cast(b); + // float relative error should be less than 1/(2^7) since bfloat16 + // has 7 bits mantissa. + if (fabs(c - a) / a <= 1.0 / 128) { + return true; + } + return false; +} +__host__ __device__ bool testOperations(const float &fa, const float &fb) { + bool testPass = true; + hip_bfloat16 bf_a(fa); + hip_bfloat16 bf_b(fb); + float fc = static_cast(bf_a); + float fd = static_cast(bf_b); + + testPass &= testRelativeAccuracy(fa, bf_a); + testPass &= testRelativeAccuracy(fb, bf_b); + + testPass &= testRelativeAccuracy(fc + fd, bf_a + bf_b); + // when checked as above for add, operation sub fails on GPU + if (hip_bfloat16(fc - fd) == (bf_a - bf_b)) { + testPass &= true; + } + testPass &= testRelativeAccuracy(fc * fd, bf_a * bf_b); + testPass &= testRelativeAccuracy(fc / fd, bf_a / bf_b); + + hip_bfloat16 bf_x; + bf_x = bf_a; + bf_x++; + bf_x--; + ++bf_x; + --bf_x; + // hip_bfloat16 is converted to float and then inc/decremented, + // hence check with reduced precision + testPass &= testRelativeAccuracy(bf_x, bf_a); + + bf_x = bf_a; + bf_x += bf_b; + bf_x = bf_a; + bf_x -= bf_b; + bf_x = bf_a; + bf_x *= bf_b; + bf_x = bf_a; + bf_x /= bf_b; + + hip_bfloat16 bf_rounded = hip_bfloat16::round_to_bfloat16(fa); + if (std::isnan(bf_rounded)) { + if (std::isnan(bf_rounded) || std::isinf(bf_rounded)) { + testPass &= true; + } + } + return testPass; +} +__global__ void testOperationsGPU(float* d_a, float* d_b, bool *testPass) { + int id = threadIdx.x; + if (id > SIZE) return; + float &a = d_a[id]; + float &b = d_b[id]; + *testPass = testOperations(a, b); +} +TEST_CASE("Unit_hipBfloat16") { + float *h_fa, *h_fb; + float *d_fa, *d_fb; + bool *d_fc, h_fc = false; + + h_fa = new float[SIZE]; + h_fb = new float[SIZE]; + + bool result = false; + for (int i = 0; i < SIZE; i++) { + h_fa[i] = getRandomFloat(); + h_fb[i] = getRandomFloat(); + result = testOperations(h_fa[i], h_fb[i]); + REQUIRE(result == true); + } + + HIP_CHECK(hipMalloc(&d_fa, sizeof(float) * SIZE)); + HIP_CHECK(hipMalloc(&d_fb, sizeof(float) * SIZE)); + HIP_CHECK(hipMalloc(&d_fc, sizeof(bool))); + + HIP_CHECK(hipMemcpy(d_fa, h_fa, sizeof(float) * SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(d_fb, h_fb, sizeof(float) * SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(d_fc, &h_fc, sizeof(bool), hipMemcpyHostToDevice)); + + hipLaunchKernelGGL(testOperationsGPU, 1, SIZE, 0, 0, d_fa, d_fb, d_fc); + HIP_CHECK(hipDeviceSynchronize()); + HIP_CHECK(hipMemcpy(&h_fc, d_fc, sizeof(bool), hipMemcpyDeviceToHost)); + + REQUIRE(h_fc == true); + + delete[] h_fa; + delete[] h_fb; + HIP_CHECK(hipFree(d_fa)); + HIP_CHECK(hipFree(d_fb)); + HIP_CHECK(hipFree(d_fc)); +} diff --git a/catch/unit/deviceLib/hipComplex.cc b/catch/unit/deviceLib/hipComplex.cc new file mode 100644 index 0000000000..04a4ecc737 --- /dev/null +++ b/catch/unit/deviceLib/hipComplex.cc @@ -0,0 +1,438 @@ +/* +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 + +#define LEN 64 +/* Comparing 2 floating point/double variables using floating point +precision. The precision is set at compile time using EPSILON. */ +#define COMPARE_REALNUM(A, B, EPSILON) (fabs(A-B) < EPSILON) + +enum ComplexFuncType { + COMPLEX_ADD, + COMPLEX_SUB, + COMPLEX_MUL, + COMPLEX_DIV, + COMPLEX_CONJ, + COMPLEX_REAL, + COMPLEX_IMAG, + COMPLEX_SQABS, + COMPLEX_ABS +}; + +__global__ static void testMakeComplexFunc(float* A, float* B, + hipFloatComplex* C) { + int tx = threadIdx.x + blockIdx.x * blockDim.x; + C[tx] = make_hipFloatComplex(A[tx], B[tx]); +} + +__global__ static void testMakeComplexFunc(double* A, double* B, + hipDoubleComplex* C) { + int tx = threadIdx.x + blockIdx.x * blockDim.x; + C[tx] = make_hipDoubleComplex(A[tx], B[tx]); +} + +__global__ static void testComplexMathFunc1(hipFloatComplex* A, + hipFloatComplex* B, + hipFloatComplex* C, + enum ComplexFuncType type) { + int tx = threadIdx.x + blockIdx.x * blockDim.x; + switch (type) { + case COMPLEX_ADD: + C[tx] = hipCaddf(A[tx], B[tx]); + break; + case COMPLEX_SUB: + C[tx] = hipCsubf(A[tx], B[tx]); + break; + case COMPLEX_MUL: + C[tx] = hipCmulf(A[tx], B[tx]); + break; + case COMPLEX_DIV: + C[tx] = hipCdivf(A[tx], B[tx]); + break; + case COMPLEX_CONJ: + C[tx] = hipConjf(A[tx]); + break; + default: + break; + } +} + +__global__ static void testComplexMathFunc1(hipDoubleComplex* A, + hipDoubleComplex* B, + hipDoubleComplex* C, + enum ComplexFuncType type) { + int tx = threadIdx.x + blockIdx.x * blockDim.x; + switch (type) { + case COMPLEX_ADD: + C[tx] = hipCadd(A[tx], B[tx]); + break; + case COMPLEX_SUB: + C[tx] = hipCsub(A[tx], B[tx]); + break; + case COMPLEX_MUL: + C[tx] = hipCmul(A[tx], B[tx]); + break; + case COMPLEX_DIV: + C[tx] = hipCdiv(A[tx], B[tx]); + break; + case COMPLEX_CONJ: + C[tx] = hipConj(A[tx]); + break; + default: + break; + } +} + +__global__ static void testComplexMathFunc2(hipFloatComplex* A, + float* B, + enum ComplexFuncType type) { + int tx = threadIdx.x + blockIdx.x * blockDim.x; + switch (type) { + case COMPLEX_REAL: + B[tx] = hipCrealf(A[tx]); + break; + case COMPLEX_IMAG: + B[tx] = hipCimagf(A[tx]); + break; + case COMPLEX_SQABS: + B[tx] = hipCsqabsf(A[tx]); + break; + case COMPLEX_ABS: + B[tx] = hipCabsf(A[tx]); + break; + default: + break; + } +} + +__global__ static void testComplexMathFunc2(hipDoubleComplex* A, + double* B, + enum ComplexFuncType type) { + int tx = threadIdx.x + blockIdx.x * blockDim.x; + switch (type) { + case COMPLEX_REAL: + B[tx] = hipCreal(A[tx]); + break; + case COMPLEX_IMAG: + B[tx] = hipCimag(A[tx]); + break; + case COMPLEX_SQABS: + B[tx] = hipCsqabs(A[tx]); + break; + case COMPLEX_ABS: + B[tx] = hipCabs(A[tx]); + break; + default: + break; + } +} +/** + * Validates all hipComplex inline functions on device + * Functions validated are: make_hipDoubleComplex, make_hipFloatComplex + */ +template bool test_makehipComplex_dev() { + T2 *A, *Ad, *B, *Bd; + T1 *C, *Cd; + bool TestPassed = true; + A = new T2[LEN]; + B = new T2[LEN]; + C = new T1[LEN]; + for (uint32_t i = 0; i < LEN; i++) { + A[i] = 2*i*1.0; + B[i] = (2*i + 1)*1.0; + } + unsigned int size2 = LEN * sizeof(T2); + unsigned int size1 = LEN * sizeof(T1); + HIPCHECK(hipMalloc(reinterpret_cast(&Ad), size2)); + HIPCHECK(hipMalloc(reinterpret_cast(&Bd), size2)); + HIPCHECK(hipMalloc(reinterpret_cast(&Cd), size1)); + HIPCHECK(hipMemcpy(Ad, A, size2, hipMemcpyHostToDevice)); + HIPCHECK(hipMemcpy(Bd, B, size2, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(testMakeComplexFunc, dim3(1), dim3(LEN), + 0, 0, Ad, Bd, Cd); + HIPCHECK(hipMemcpy(C, Cd, size1, hipMemcpyDeviceToHost)); + // Validate the output of the kernel functions. + for (uint32_t i = 0; i < LEN; i++) { + if ((A[i] != C[i].x) || (B[i] != C[i].y)) { + TestPassed = false; + break; + } + } + HIPCHECK(hipFree(Cd)); + HIPCHECK(hipFree(Bd)); + HIPCHECK(hipFree(Ad)); + delete[] C; + delete[] B; + delete[] A; + return TestPassed; +} +/** + * Validates all hipComplex inline functions on device + * Functions validated are: hipCaddf, hipCsubf, hipCmulf and hipCdivf + * hipCadd, hipCsub, hipCmul, hipCdiv + */ +template +bool test_complexMathFunc1_dev(enum ComplexFuncType mathFuncType) { + T1 *A, *Ad, *B, *Bd; + T1 *C, *Cd; + bool TestPassed = true; + A = new T1[LEN]; + B = new T1[LEN]; + C = new T1[LEN]; + for (uint32_t i = 0; i < LEN; i++) { + A[i].x = 2*i*1.0; + A[i].y = (2*i + 1)*1.0; + B[i].x = 2*i*1.0 + 0.5; + B[i].y = (2*i + 1)*1.0 + 0.5; + } + unsigned int size = LEN * sizeof(T1); + HIPCHECK(hipMalloc(reinterpret_cast(&Ad), size)); + HIPCHECK(hipMalloc(reinterpret_cast(&Bd), size)); + HIPCHECK(hipMalloc(reinterpret_cast(&Cd), size)); + HIPCHECK(hipMemcpy(Ad, A, size, hipMemcpyHostToDevice)); + HIPCHECK(hipMemcpy(Bd, B, size, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(testComplexMathFunc1, dim3(1), dim3(LEN), + 0, 0, Ad, Bd, Cd, mathFuncType); + HIPCHECK(hipMemcpy(C, Cd, size, hipMemcpyDeviceToHost)); + // Validate the output of the kernel functions. + T2 epsilon = 0.0001f; + T2 real, imag; + for (uint32_t i = 0; i < LEN; i++) { + if (mathFuncType == COMPLEX_ADD) { + real = (A[i].x + B[i].x); + imag = (A[i].y + B[i].y); + } else if (mathFuncType == COMPLEX_SUB) { + real = (A[i].x - B[i].x); + imag = (A[i].y - B[i].y); + } else if (mathFuncType == COMPLEX_MUL) { + real = (A[i].x*B[i].x - A[i].y*B[i].y); + imag = (A[i].y*B[i].x + A[i].x*B[i].y); + } else if (mathFuncType == COMPLEX_DIV) { + T2 sqabs = (B[i].x*B[i].x + B[i].y*B[i].y); + real = (A[i].x * B[i].x + A[i].y * B[i].y)/sqabs; + imag = (A[i].y * B[i].x - A[i].x * B[i].y)/sqabs; + } else if (mathFuncType == COMPLEX_CONJ) { + real = A[i].x; + imag = -A[i].y; + } + if (!COMPARE_REALNUM(real, C[i].x, epsilon) || + !COMPARE_REALNUM(imag, C[i].y, epsilon)) { + TestPassed = false; + break; + } + } + HIPCHECK(hipFree(Cd)); + HIPCHECK(hipFree(Bd)); + HIPCHECK(hipFree(Ad)); + delete[] C; + delete[] B; + delete[] A; + return TestPassed; +} +/** + * Validates all hipComplex inline functions on device + * Functions validated are: hipCrealf, hipCimagf, hipCsqabsf and hipCabsf + * hipCreal, hipCimag, hipCsqabs, hipCabs + */ +template +bool test_complexMathFunc2_dev(enum ComplexFuncType mathFuncType) { + T1 *A, *Ad; + T2 *B, *Bd; + bool TestPassed = true; + A = new T1[LEN]; + B = new T2[LEN]; + for (uint32_t i = 0; i < LEN; i++) { + A[i].x = 2*i*1.0; + A[i].y = (2*i + 1)*1.0; + } + unsigned int size1 = LEN * sizeof(T1); + unsigned int size2 = LEN * sizeof(T2); + HIPCHECK(hipMalloc(reinterpret_cast(&Ad), size1)); + HIPCHECK(hipMalloc(reinterpret_cast(&Bd), size2)); + HIPCHECK(hipMemcpy(Ad, A, size1, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(testComplexMathFunc2, dim3(1), dim3(LEN), + 0, 0, Ad, Bd, mathFuncType); + HIPCHECK(hipMemcpy(B, Bd, size2, hipMemcpyDeviceToHost)); + // Validate the output of the kernel functions. + T2 epsilon = 0.0001f; + if (mathFuncType == COMPLEX_REAL) { + for (uint32_t i = 0; i < LEN; i++) { + if (!COMPARE_REALNUM(A[i].x, B[i], epsilon)) { + TestPassed = false; + break; + } + } + } else if (mathFuncType == COMPLEX_IMAG) { + for (uint32_t i = 0; i < LEN; i++) { + if (!COMPARE_REALNUM(A[i].y, B[i], epsilon)) { + TestPassed = false; + break; + } + } + } else if (mathFuncType == COMPLEX_SQABS) { + for (uint32_t i = 0; i < LEN; i++) { + T2 sqabs = A[i].x * A[i].x + A[i].y * A[i].y; +#ifdef __HIP_PLATFORM_NVCC__ + /* Setting the Floating Point precision to 0.01 as this scenario + is failing on NVIDIA targets. */ + epsilon = 0.01f; +#endif + if (!COMPARE_REALNUM(sqabs, B[i], epsilon)) { + TestPassed = false; + break; + } + } + } else if (mathFuncType == COMPLEX_ABS) { + for (uint32_t i = 0; i < LEN; i++) { + T2 sqabs = A[i].x * A[i].x + A[i].y * A[i].y; + if (!COMPARE_REALNUM(sqrtf(sqabs), B[i], epsilon)) { + TestPassed = false; + break; + } + } + } + HIPCHECK(hipFree(Bd)); + HIPCHECK(hipFree(Ad)); + delete[] B; + delete[] A; + return TestPassed; +} + +// Validates all hipComplex inline functions on host +static bool test_allcomplexMathFunc_host() { + bool TestPassed = true; + float fa = 2.0, fb = 3.0; + hipFloatComplex fc = make_hipFloatComplex(fa, fb); + if ((fc.x != fa) || (fc.y != fb)) { + TestPassed &= false; + } + double da = 2.0, db = 3.0; + hipDoubleComplex dc = make_hipDoubleComplex(da, db); + if ((dc.x != da) || (dc.y != db)) { + TestPassed &= false; + } + hipFloatComplex fp, fq, fx; + fp.x = 2.0; + fp.y = 3.0; + fq.x = 4.0; + fq.y = 5.0; + fx = hipCaddf(fp, fq); + if ((fx.x != (fp.x + fq.x)) || (fx.y != (fp.y + fq.y))) { + TestPassed &= false; + } + fx = hipCsubf(fp, fq); + if ((fx.x != (fp.x - fq.x)) || (fx.y != (fp.y - fq.y))) { + TestPassed &= false; + } + fx = hipCmulf(fp, fq); + if ((fx.x != (fp.x*fq.x - fp.y*fq.y)) || + (fx.y != (fp.y*fq.x + fp.x*fq.y))) { + TestPassed &= false; + } + fx = hipCdivf(fp, fq); + float fsqabs = fq.x*fq.x + fq.y*fq.y; + float epsilon = 0.0001f; + if ((!COMPARE_REALNUM(fx.x, (fp.x*fq.x + fp.y*fq.y)/fsqabs, epsilon)) || + (!COMPARE_REALNUM(fx.y, (fp.y*fq.x - fp.x*fq.y)/fsqabs, epsilon))) { + TestPassed &= false; + } + if ((fp.x != hipCrealf(fp)) || (fp.y != hipCimagf(fp))) { + TestPassed &= false; + } + fx = hipConjf(fp); + if ((fx.x != fp.x) || (fx.y != -fp.y)) { + TestPassed &= false; + } + if (!COMPARE_REALNUM((fp.x*fp.x + fp.y*fp.y), hipCsqabsf(fp), epsilon)) { + TestPassed &= false; + } + if (!COMPARE_REALNUM(sqrtf(fp.x*fp.x + fp.y*fp.y), hipCabsf(fp), epsilon)) { + TestPassed &= false; + } + hipDoubleComplex dp, dq, dx; + dp.x = 2.0; + dp.y = 3.0; + dq.x = 4.0; + dq.y = 5.0; + dx = hipCadd(dp, dq); + if ((dx.x != (dp.x + dq.x)) || (dx.y != (dp.y + dq.y))) { + TestPassed &= false; + } + dx = hipCsub(dp, dq); + if ((dx.x != (dp.x - dq.x)) || (dx.y != (dp.y - dq.y))) { + TestPassed &= false; + } + dx = hipCmul(dp, dq); + if ((dx.x != (dp.x*dq.x - dp.y*dq.y)) || + (dx.y != (dp.y*dq.x + dp.x*dq.y))) { + TestPassed &= false; + } + dx = hipCdiv(dp, dq); + float dsqabs = dq.x*dq.x + dq.y*dq.y; + if ((!COMPARE_REALNUM(dx.x, (dp.x*dq.x + dp.y*dq.y)/dsqabs, epsilon)) || + (!COMPARE_REALNUM(dx.y, (dp.y*dq.x - dp.x*dq.y)/dsqabs, epsilon))) { + TestPassed &= false; + } + if ((dp.x != hipCreal(dp)) || (dp.y != hipCimag(dp))) { + TestPassed &= false; + } + dx = hipConj(dp); + if ((dx.x != dp.x) || (dx.y != -dp.y)) { + TestPassed &= false; + } + if (!COMPARE_REALNUM((dp.x*dp.x + dp.y*dp.y), hipCsqabs(dp), epsilon)) { + TestPassed &= false; + } + if (!COMPARE_REALNUM(sqrtf(dp.x*dp.x + dp.y*dp.y), hipCabs(dp), epsilon)) { + TestPassed &= false; + } + return TestPassed; +} + +TEST_CASE("Unit_TestMathFuncComplex") { + bool TestPassed = false; + TestPassed = test_makehipComplex_dev() && + test_makehipComplex_dev() && + test_makehipComplex_dev() && + test_makehipComplex_dev() && + test_complexMathFunc1_dev(COMPLEX_ADD) && + test_complexMathFunc1_dev(COMPLEX_ADD) + && test_complexMathFunc1_dev(COMPLEX_SUB) + && test_complexMathFunc1_dev + (COMPLEX_SUB) && test_complexMathFunc1_dev(COMPLEX_MUL) && test_complexMathFunc1_dev(COMPLEX_MUL) && test_complexMathFunc1_dev(COMPLEX_DIV) && test_complexMathFunc1_dev(COMPLEX_DIV) && test_complexMathFunc1_dev(COMPLEX_CONJ) && test_complexMathFunc1_dev< + hipDoubleComplex, double>(COMPLEX_CONJ) && test_complexMathFunc2_dev + (COMPLEX_REAL) && test_complexMathFunc2_dev + (COMPLEX_REAL) && test_complexMathFunc2_dev + (COMPLEX_IMAG) && test_complexMathFunc2_dev + (COMPLEX_IMAG) && test_complexMathFunc2_dev + (COMPLEX_SQABS) && test_complexMathFunc2_dev + (COMPLEX_SQABS) && test_complexMathFunc2_dev + (COMPLEX_ABS) && test_complexMathFunc2_dev + (COMPLEX_ABS) &&test_allcomplexMathFunc_host(); + REQUIRE(TestPassed == true); +} diff --git a/catch/unit/deviceLib/hipDeviceMemcpy.cc b/catch/unit/deviceLib/hipDeviceMemcpy.cc new file mode 100644 index 0000000000..df881aa454 --- /dev/null +++ b/catch/unit/deviceLib/hipDeviceMemcpy.cc @@ -0,0 +1,60 @@ +/* +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 + +#define LEN 1024 +#define SIZE (LEN << 2) + +__global__ static void cpy(uint32_t* Out, uint32_t* In) { + int tx = threadIdx.x; + memcpy(Out + tx, In + tx, sizeof(uint32_t)); +} + +__global__ static void set(uint32_t* ptr, uint8_t val) { + int tx = threadIdx.x; + memset(ptr + tx, val, sizeof(uint32_t)); +} + +TEST_CASE("Unit_ToAndFroMemCpyToDevice") { + uint32_t *A, *Ad, *B, *Bd; + A = new uint32_t[LEN]; + B = new uint32_t[LEN]; + for (int i = 0; i < LEN; i++) { + A[i] = i; + B[i] = 0; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + + hipLaunchKernelGGL(cpy, dim3(1), dim3(LEN), 0, 0, Bd, Ad); + + HIP_CHECK(hipMemcpy(B, Bd, SIZE, hipMemcpyDeviceToHost)); + for (int i = LEN - 16; i < LEN; i++) { + REQUIRE(A[i] == B[i]); + } + hipLaunchKernelGGL(set, dim3(1), dim3(LEN), 0, 0, Bd, 0x1); + + HIP_CHECK(hipMemcpy(B, Bd, SIZE, hipMemcpyDeviceToHost)); + for (int i = LEN - 16; i < LEN; i++) { + REQUIRE(0x01010101 == B[i]); + } + delete[] A; + delete[] B; +} diff --git a/catch/unit/deviceLib/hipTestDevice.cc b/catch/unit/deviceLib/hipTestDevice.cc new file mode 100644 index 0000000000..606ad7dfb4 --- /dev/null +++ b/catch/unit/deviceLib/hipTestDevice.cc @@ -0,0 +1,736 @@ +/* +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 N 512 +#define SIZE (N * sizeof(float)) + +__global__ void test_sincosf(float* a, float* b, float* c) { + int tid = threadIdx.x; + sincosf(a[tid], b + tid, c + tid); +} + +__global__ void test_sincospif(float* a, float* b, float* c) { + int tid = threadIdx.x; + sincospif(a[tid], b + tid, c + tid); +} + +__global__ void test_fdividef(float* a, float* b, float* c) { + int tid = threadIdx.x; + c[tid] = fdividef(a[tid], b[tid]); +} + +__global__ void test_llrintf(float* a, int64_t* b) { + int tid = threadIdx.x; + b[tid] = llrintf(a[tid]); +} + +__global__ void test_lrintf(float* a, int64_t* b) { + int tid = threadIdx.x; + b[tid] = lrintf(a[tid]); +} + +__global__ void test_rintf(float* a, float* b) { + int tid = threadIdx.x; + b[tid] = rintf(a[tid]); +} + +__global__ void test_llroundf(float* a, int64_t* b) { + int tid = threadIdx.x; + b[tid] = llroundf(a[tid]); +} + +__global__ void test_lroundf(float* a, int64_t* b) { + int tid = threadIdx.x; + b[tid] = lroundf(a[tid]); +} + +__global__ void test_rhypotf(float* a, float* b, float* c) { + int tid = threadIdx.x; + c[tid] = rhypotf(a[tid], b[tid]); +} + +__global__ void test_norm3df(float* a, float* b, float* c, float* d) { + int tid = threadIdx.x; + d[tid] = norm3df(a[tid], b[tid], c[tid]); +} + +__global__ void test_norm4df(float* a, float* b, float* c, float* d, float* e) { + int tid = threadIdx.x; + e[tid] = norm4df(a[tid], b[tid], c[tid], d[tid]); +} + +__global__ void test_normf(float* a, float* b) { + int tid = threadIdx.x; + b[tid] = normf(N, a); +} + +__global__ void test_rnorm3df(float* a, float* b, float* c, float* d) { + int tid = threadIdx.x; + d[tid] = rnorm3df(a[tid], b[tid], c[tid]); +} + +__global__ void test_rnorm4df(float* a, float* b, float* c, float* d, + float* e) { + int tid = threadIdx.x; + e[tid] = rnorm4df(a[tid], b[tid], c[tid], d[tid]); +} + +__global__ void test_rnormf(float* a, float* b) { + int tid = threadIdx.x; + b[tid] = rnormf(N, a); +} + +__global__ void test_erfinvf(float* a, float* b) { + int tid = threadIdx.x; + b[tid] = erff(erfinvf(a[tid])); +} + + +bool run_sincosf() { + float *A, *Ad, *B, *C, *Bd, *Cd; + A = new float[N]; + B = new float[N]; + C = new float[N]; + for (int i = 0; i < N; i++) { + A[i] = 1.0f; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Cd), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_sincosf, dim3(1), dim3(N), 0, 0, Ad, Bd, Cd); + HIP_CHECK(hipMemcpy(B, Bd, SIZE, hipMemcpyDeviceToHost)); + HIP_CHECK(hipMemcpy(C, Cd, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if (B[i] == sinf(1.0f)) { + passed = 1; + } + } + passed = 0; + for (int i = 0; i < 512; i++) { + if (C[i] == cosf(1.0f)) { + passed = 1; + } + } + + delete[] A; + delete[] B; + delete[] C; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + + if (passed == 1) { + return true; + } else { + return false; + } +} + +bool run_sincospif() { + float *A, *Ad, *B, *C, *Bd, *Cd; + A = new float[N]; + B = new float[N]; + C = new float[N]; + for (int i = 0; i < N; i++) { + A[i] = 1.0f; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Cd), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_sincospif, dim3(1), dim3(N), 0, 0, Ad, Bd, Cd); + HIP_CHECK(hipMemcpy(B, Bd, SIZE, hipMemcpyDeviceToHost)); + HIP_CHECK(hipMemcpy(C, Cd, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if (B[i] - sinf(3.14 * 1.0f) < 0.1) { + passed = 1; + } + } + passed = 0; + for (int i = 0; i < 512; i++) { + if (C[i] - cosf(3.14 * 1.0f) < 0.1) { + passed = 1; + } + } + + delete[] A; + delete[] B; + delete[] C; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + + if (passed == 1) { + return true; + } else { + return false; + } +} + +bool run_fdividef() { + float *A, *Ad, *B, *C, *Bd, *Cd; + A = new float[N]; + B = new float[N]; + C = new float[N]; + for (int i = 0; i < N; i++) { + A[i] = 1.0f; + B[i] = 2.0f; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Cd), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Bd, B, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_fdividef, dim3(1), dim3(N), 0, 0, Ad, Bd, Cd); + HIP_CHECK(hipMemcpy(C, Cd, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if (C[i] == A[i] / B[i]) { + passed = 1; + } + } + + delete[] A; + delete[] B; + delete[] C; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + + if (passed == 1) { + return true; + } else { + return false; + } +} + +bool run_llrintf() { + float *A, *Ad; + int64_t *B, *Bd; + A = new float[N]; + B = new int64_t[N]; + for (int i = 0; i < N; i++) { + A[i] = 1.345f; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), N * sizeof(int64_t))); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_llrintf, dim3(1), dim3(N), 0, 0, Ad, Bd); + HIP_CHECK(hipMemcpy(B, Bd, N * sizeof(int64_t), hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + int x = roundf(A[i]); + if (B[i] == x) { + passed = 1; + } + } + + delete[] A; + delete[] B; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + + if (passed == 1) { + return true; + } else { + return false; + } +} + +bool run_lrintf() { + float *A, *Ad; + int64_t *B, *Bd; + A = new float[N]; + B = new int64_t[N]; + for (int i = 0; i < N; i++) { + A[i] = 1.345f; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), N * sizeof(int64_t))); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_lrintf, dim3(1), dim3(N), 0, 0, Ad, Bd); + HIP_CHECK(hipMemcpy(B, Bd, N * sizeof(int64_t), hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + int x = roundf(A[i]); + if (B[i] == x) { + passed = 1; + } + } + + delete[] A; + delete[] B; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + + if (passed == 1) { + return true; + } else { + return false; + } +} + +bool run_rintf() { + float *A, *Ad; + float *B, *Bd; + A = new float[N]; + B = new float[N]; + for (int i = 0; i < N; i++) { + A[i] = 1.345f; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_rintf, dim3(1), dim3(N), 0, 0, Ad, Bd); + HIP_CHECK(hipMemcpy(B, Bd, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + float x = roundf(A[i]); + if (B[i] == x) { + passed = 1; + } + } + + delete[] A; + delete[] B; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + + if (passed == 1) { + return true; + } else { + return false; + } +} + +bool run_llroundf() { + float *A, *Ad; + int64_t *B, *Bd; + A = new float[N]; + B = new int64_t[N]; + for (int i = 0; i < N; i++) { + A[i] = 1.345f; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), N * sizeof(int64_t))); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_llroundf, dim3(1), dim3(N), 0, 0, Ad, Bd); + HIP_CHECK(hipMemcpy(B, Bd, N * sizeof(int64_t), hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + int x = roundf(A[i]); + if (B[i] == x) { + passed = 1; + } + } + + delete[] A; + delete[] B; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + + if (passed == 1) { + return true; + } else { + return false; + } +} + +bool run_lroundf() { + float *A, *Ad; + int64_t *B, *Bd; + A = new float[N]; + B = new int64_t[N]; + for (int i = 0; i < N; i++) { + A[i] = 1.345f; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), N * sizeof(int64_t))); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_lroundf, dim3(1), dim3(N), 0, 0, Ad, Bd); + HIP_CHECK(hipMemcpy(B, Bd, N * sizeof(int64_t), hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + int x = roundf(A[i]); + if (B[i] == x) { + passed = 1; + } + } + + delete[] A; + delete[] B; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + + if (passed == 1) { + return true; + } else { + return false; + } +} + +bool run_norm3df() { + float *A, *Ad, *B, *Bd, *C, *Cd, *D, *Dd; + A = new float[N]; + B = new float[N]; + C = new float[N]; + D = new float[N]; + float val = 0.0f; + for (int i = 0; i < N; i++) { + A[i] = 1.0f; + B[i] = 2.0f; + C[i] = 3.0f; + } + val = sqrtf(1.0f + 4.0f + 9.0f); + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Cd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Dd), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Bd, B, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Cd, C, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_norm3df, dim3(1), dim3(N), 0, 0, Ad, Bd, Cd, Dd); + HIP_CHECK(hipMemcpy(D, Dd, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if (D[i] - val < 0.000001) { + passed = 1; + } + } + + delete[] A; + delete[] B; + delete[] C; + delete[] D; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + HIP_CHECK(hipFree(Dd)); + + if (passed == 1) { + return true; + } else { + return false; + } +} + +bool run_norm4df() { + float *A, *Ad, *B, *Bd, *C, *Cd, *D, *Dd, *E, *Ed; + A = new float[N]; + B = new float[N]; + C = new float[N]; + D = new float[N]; + E = new float[N]; + float val = 0.0f; + for (int i = 0; i < N; i++) { + A[i] = 1.0f; + B[i] = 2.0f; + C[i] = 3.0f; + D[i] = 4.0f; + } + val = sqrtf(1.0f + 4.0f + 9.0f + 16.0f); + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Cd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Dd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Ed), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Bd, B, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Cd, C, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Dd, D, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_norm4df, dim3(1), dim3(N), 0, 0, Ad, + Bd, Cd, Dd, Ed); + HIP_CHECK(hipMemcpy(E, Ed, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if (E[i] - val < 0.000001) { + passed = 1; + } + } + + delete[] A; + delete[] B; + delete[] C; + delete[] D; + delete[] E; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + HIP_CHECK(hipFree(Dd)); + HIP_CHECK(hipFree(Ed)); + + if (passed == 1) { + return true; + } else { + return false; + } +} + +bool run_normf() { + float *A, *Ad, *B, *Bd; + A = new float[N]; + B = new float[N]; + float val = 0.0f; + for (int i = 0; i < N; i++) { + A[i] = 1.0f; + B[i] = 0.0f; + val += 1.0f; + } + val = sqrtf(val); + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_normf, dim3(1), dim3(N), 0, 0, Ad, Bd); + HIP_CHECK(hipMemcpy(B, Bd, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if (B[0] - val < 0.000001) { + passed = 1; + } + } + + delete[] A; + delete[] B; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + + if (passed == 1) { + return true; + } else { + return false; + } +} + +bool run_rhypotf() { + float *A, *Ad, *B, *Bd, *C, *Cd; + A = new float[N]; + B = new float[N]; + C = new float[N]; + float val = 0.0f; + for (int i = 0; i < N; i++) { + A[i] = 1.0f; + B[i] = 2.0f; + } + val = 1 / sqrtf(1.0f + 4.0f); + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Cd), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Bd, B, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_rhypotf, dim3(1), dim3(N), 0, 0, Ad, Bd, Cd); + HIP_CHECK(hipMemcpy(C, Cd, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if (C[i] - val < 0.000001) { + passed = 1; + } + } + + delete[] A; + delete[] B; + delete[] C; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + + if (passed == 1) { + return true; + } else { + return false; + } +} + +bool run_rnorm3df() { + float *A, *Ad, *B, *Bd, *C, *Cd, *D, *Dd; + A = new float[N]; + B = new float[N]; + C = new float[N]; + D = new float[N]; + float val = 0.0f; + for (int i = 0; i < N; i++) { + A[i] = 1.0f; + B[i] = 2.0f; + C[i] = 3.0f; + } + val = 1 / sqrtf(1.0f + 4.0f + 9.0f); + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Cd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Dd), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Bd, B, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Cd, C, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_rnorm3df, dim3(1), dim3(N), 0, 0, Ad, Bd, Cd, Dd); + HIP_CHECK(hipMemcpy(D, Dd, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if (D[i] - val < 0.000001) { + passed = 1; + } + } + + delete[] A; + delete[] B; + delete[] C; + delete[] D; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + HIP_CHECK(hipFree(Dd)); + + if (passed == 1) { + return true; + } else { + return false; + } +} + +bool run_rnorm4df() { + float *A, *Ad, *B, *Bd, *C, *Cd, *D, *Dd, *E, *Ed; + A = new float[N]; + B = new float[N]; + C = new float[N]; + D = new float[N]; + E = new float[N]; + float val = 0.0f; + for (int i = 0; i < N; i++) { + A[i] = 1.0f; + B[i] = 2.0f; + C[i] = 3.0f; + D[i] = 4.0f; + } + val = 1 / sqrtf(1.0f + 4.0f + 9.0f + 16.0f); + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Cd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Dd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Ed), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Bd, B, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Cd, C, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Dd, D, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_rnorm4df, dim3(1), dim3(N), 0, 0, Ad, + Bd, Cd, Dd, Ed); + HIP_CHECK(hipMemcpy(E, Ed, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if (E[i] - val < 0.000001) { + passed = 1; + } + } + + delete[] A; + delete[] B; + delete[] C; + delete[] D; + delete[] E; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + HIP_CHECK(hipFree(Dd)); + HIP_CHECK(hipFree(Ed)); + + if (passed == 1) { + return true; + } else { + return false; + } +} + +bool run_rnormf() { + float *A, *Ad, *B, *Bd; + A = new float[N]; + B = new float[N]; + float val = 0.0f; + for (int i = 0; i < N; i++) { + A[i] = 1.0f; + B[i] = 0.0f; + val += 1.0f; + } + val = 1 / sqrtf(val); + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_rnormf, dim3(1), dim3(N), 0, 0, Ad, Bd); + HIP_CHECK(hipMemcpy(B, Bd, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if (B[0] - val < 0.000001) { + passed = 1; + } + } + + delete[] A; + delete[] B; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + + if (passed == 1) { + return true; + } else { + return false; + } +} + +bool run_erfinvf() { + float *A, *Ad, *B, *Bd; + A = new float[N]; + B = new float[N]; + for (int i = 0; i < N; i++) { + A[i] = -0.6f; + B[i] = 0.0f; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_erfinvf, dim3(1), dim3(N), 0, 0, Ad, Bd); + HIP_CHECK(hipMemcpy(B, Bd, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if (B[i] - A[i] < 0.000001) { + passed = 1; + } + } + + delete[] A; + delete[] B; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + + if (passed == 1) { + return true; + } else { + return false; + } +} + +TEST_CASE("Unit_hipDeviceTrigFunc_Float") { + bool result = false; + result = run_sincosf() && run_sincospif() && run_fdividef() && + run_llrintf() && run_norm3df() && run_norm4df() && + run_normf() && run_rnorm3df() && run_rnorm4df() && + run_rnormf() && run_lroundf() && run_llroundf() && + run_rintf() && run_rhypotf() && run_erfinvf(); + REQUIRE(result == true); +} diff --git a/catch/unit/deviceLib/hipTestDeviceDouble.cc b/catch/unit/deviceLib/hipTestDeviceDouble.cc new file mode 100644 index 0000000000..865d54e9bd --- /dev/null +++ b/catch/unit/deviceLib/hipTestDeviceDouble.cc @@ -0,0 +1,630 @@ +/* +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 N 512 +#define SIZE (N * sizeof(double)) + +__global__ void test_sincos(double* a, double* b, double* c) { + int tid = threadIdx.x; + sincos(a[tid], b + tid, c + tid); +} + +__global__ void test_sincospi(double* a, double* b, double* c) { + int tid = threadIdx.x; + sincospi(a[tid], b + tid, c + tid); +} + +__global__ void test_llrint(double* a, int64_t* b) { + int tid = threadIdx.x; + b[tid] = llrint(a[tid]); +} + +__global__ void test_lrint(double* a, int64_t* b) { + int tid = threadIdx.x; + b[tid] = lrint(a[tid]); +} + +__global__ void test_rint(double* a, double* b) { + int tid = threadIdx.x; + b[tid] = rint(a[tid]); +} + +__global__ void test_llround(double* a, int64_t* b) { + int tid = threadIdx.x; + b[tid] = llround(a[tid]); +} + +__global__ void test_lround(double* a, int64_t* b) { + int tid = threadIdx.x; + b[tid] = lround(a[tid]); +} + +__global__ void test_rhypot(double* a, double* b, double* c) { + int tid = threadIdx.x; + c[tid] = rhypot(a[tid], b[tid]); +} + +__global__ void test_norm3d(double* a, double* b, double* c, double* d) { + int tid = threadIdx.x; + d[tid] = norm3d(a[tid], b[tid], c[tid]); +} + +__global__ void test_norm4d(double* a, double* b, double* c, double* d, + double* e) { + int tid = threadIdx.x; + e[tid] = norm4d(a[tid], b[tid], c[tid], d[tid]); +} + +__global__ void test_rnorm3d(double* a, double* b, double* c, double* d) { + int tid = threadIdx.x; + d[tid] = rnorm3d(a[tid], b[tid], c[tid]); +} + +__global__ void test_rnorm4d(double* a, double* b, double* c, double* d, + double* e) { + int tid = threadIdx.x; + e[tid] = rnorm4d(a[tid], b[tid], c[tid], d[tid]); +} + +__global__ void test_rnorm(double* a, double* b) { + int tid = threadIdx.x; + b[tid] = rnorm(N, a); +} + +__global__ void test_erfinv(double* a, double* b) { + int tid = threadIdx.x; + b[tid] = erf(erfinv(a[tid])); +} + +bool run_sincos() { + double *A, *Ad, *B, *C, *Bd, *Cd; + A = new double[N]; + B = new double[N]; + C = new double[N]; + for (int i = 0; i < N; i++) { + A[i] = 1.0; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Cd), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_sincos, dim3(1), dim3(N), 0, 0, Ad, Bd, Cd); + HIP_CHECK(hipMemcpy(B, Bd, SIZE, hipMemcpyDeviceToHost)); + HIP_CHECK(hipMemcpy(C, Cd, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if ((B[i] == sin(1.0)) && (C[i] == cos(1.0))) { + passed = 1; + } + } + + delete[] A; + delete[] B; + delete[] C; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + + if (passed == 1) { + return true; + } + return false; +} + +bool run_sincospi() { + double *A, *Ad, *B, *C, *Bd, *Cd; + A = new double[N]; + B = new double[N]; + C = new double[N]; + for (int i = 0; i < N; i++) { + A[i] = 1.0; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Cd), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_sincospi, dim3(1), dim3(N), 0, 0, Ad, Bd, Cd); + HIP_CHECK(hipMemcpy(B, Bd, SIZE, hipMemcpyDeviceToHost)); + HIP_CHECK(hipMemcpy(C, Cd, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if ((B[i] - sin(3.14 * 1.0) < 0.1) && (C[i] - cos(3.14 * 1.0) < 0.1)) { + passed = 1; + } + } + delete[] A; + delete[] B; + delete[] C; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + + if (passed == 1) { + return true; + } + return false; +} + +bool run_llrint() { + double *A, *Ad; + int64_t *B, *Bd; + A = new double[N]; + B = new int64_t[N]; + for (int i = 0; i < N; i++) { + A[i] = 1.345; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), + N * sizeof(int64_t))); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_llrint, dim3(1), dim3(N), 0, 0, Ad, Bd); + HIP_CHECK(hipMemcpy(B, Bd, N * sizeof(int64_t), + hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + int x = round(A[i]); + int64_t y = x; + if (B[i] == x) { + passed = 1; + } + } + + delete[] A; + delete[] B; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + + if (passed == 1) { + return true; + } + return false; +} + +bool run_lrint() { + double *A, *Ad; + int64_t *B, *Bd; + A = new double[N]; + B = new int64_t[N]; + for (int i = 0; i < N; i++) { + A[i] = 1.345; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), N * sizeof(int64_t))); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_lrint, dim3(1), dim3(N), 0, 0, Ad, Bd); + HIP_CHECK(hipMemcpy(B, Bd, N * sizeof(int64_t), hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + int64_t x = round(A[i]); + if (B[i] == x) { + passed = 1; + } + } + + delete[] A; + delete[] B; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + + if (passed == 1) { + return true; + } + return false; +} + +bool run_rint() { + double *A, *Ad; + double *B, *Bd; + A = new double[N]; + B = new double[N]; + for (int i = 0; i < N; i++) { + A[i] = 1.345; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_rint, dim3(1), dim3(N), 0, 0, Ad, Bd); + HIP_CHECK(hipMemcpy(B, Bd, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + double x = round(A[i]); + if (B[i] == x) { + passed = 1; + } + } + + delete[] A; + delete[] B; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + + if (passed == 1) { + return true; + } + return false; +} + +bool run_llround() { + double *A, *Ad; + int64_t *B, *Bd; + A = new double[N]; + B = new int64_t[N]; + for (int i = 0; i < N; i++) { + A[i] = 1.345; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), + N * sizeof(int64_t))); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_llround, dim3(1), dim3(N), 0, 0, Ad, Bd); + HIP_CHECK(hipMemcpy(B, Bd, N * sizeof(int64_t), + hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + int64_t x = round(A[i]); + if (B[i] == x) { + passed = 1; + } + } + + delete[] A; + delete[] B; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + + if (passed == 1) { + return true; + } + return false; +} + +bool run_lround() { + double *A, *Ad; + int64_t *B, *Bd; + A = new double[N]; + B = new int64_t[N]; + for (int i = 0; i < N; i++) { + A[i] = 1.345; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), N * sizeof(int64_t))); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_lround, dim3(1), dim3(N), 0, 0, Ad, Bd); + HIP_CHECK(hipMemcpy(B, Bd, N * sizeof(int64_t), hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + int64_t x = round(A[i]); + if (B[i] == x) { + passed = 1; + } + } + + delete[] A; + delete[] B; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + + if (passed == 1) { + return true; + } + return false; +} + +bool run_norm3d() { + double *A, *Ad, *B, *Bd, *C, *Cd, *D, *Dd; + A = new double[N]; + B = new double[N]; + C = new double[N]; + D = new double[N]; + double val = 0.0; + for (int i = 0; i < N; i++) { + A[i] = 1.0; + B[i] = 2.0; + C[i] = 3.0; + } + val = sqrt(1.0 + 4.0 + 9.0); + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Cd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Dd), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Bd, B, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Cd, C, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_norm3d, dim3(1), dim3(N), 0, 0, Ad, Bd, Cd, Dd); + HIP_CHECK(hipMemcpy(D, Dd, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if (D[i] - val < 0.000001) { + passed = 1; + } + } + + delete[] A; + delete[] B; + delete[] C; + delete[] D; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + HIP_CHECK(hipFree(Dd)); + + if (passed == 1) { + return true; + } + return false; +} + +bool run_norm4d() { + double *A, *Ad, *B, *Bd, *C, *Cd, *D, *Dd, *E, *Ed; + A = new double[N]; + B = new double[N]; + C = new double[N]; + D = new double[N]; + E = new double[N]; + double val = 0.0; + for (int i = 0; i < N; i++) { + A[i] = 1.0; + B[i] = 2.0; + C[i] = 3.0; + D[i] = 4.0; + } + val = sqrt(1.0 + 4.0 + 9.0 + 16.0); + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Cd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Dd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Ed), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Bd, B, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Cd, C, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Dd, D, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_norm4d, dim3(1), dim3(N), 0, 0, Ad, Bd, Cd, Dd, Ed); + HIP_CHECK(hipMemcpy(E, Ed, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if (E[i] - val < 0.000001) { + passed = 1; + } + } + + delete[] A; + delete[] B; + delete[] C; + delete[] D; + delete[] E; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + HIP_CHECK(hipFree(Dd)); + HIP_CHECK(hipFree(Ed)); + + if (passed == 1) { + return true; + } + return false; +} + +bool run_rhypot() { + double *A, *Ad, *B, *Bd, *C, *Cd; + A = new double[N]; + B = new double[N]; + C = new double[N]; + double val = 0.0; + for (int i = 0; i < N; i++) { + A[i] = 1.0; + B[i] = 2.0; + } + val = 1 / sqrt(1.0 + 4.0); + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Cd), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Bd, B, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_rhypot, dim3(1), dim3(N), 0, 0, Ad, Bd, Cd); + HIP_CHECK(hipMemcpy(C, Cd, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if (C[i] - val < 0.000001) { + passed = 1; + } + } + + delete[] A; + delete[] B; + delete[] C; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + + if (passed == 1) { + return true; + } + return false; +} + +bool run_rnorm3d() { + double *A, *Ad, *B, *Bd, *C, *Cd, *D, *Dd; + A = new double[N]; + B = new double[N]; + C = new double[N]; + D = new double[N]; + double val = 0.0; + for (int i = 0; i < N; i++) { + A[i] = 1.0; + B[i] = 2.0; + C[i] = 3.0; + } + val = 1 / sqrt(1.0 + 4.0 + 9.0); + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Cd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Dd), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Bd, B, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Cd, C, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_rnorm3d, dim3(1), dim3(N), 0, 0, Ad, Bd, Cd, Dd); + HIP_CHECK(hipMemcpy(D, Dd, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if (D[i] - val < 0.000001) { + passed = 1; + } + } + + delete[] A; + delete[] B; + delete[] C; + delete[] D; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + HIP_CHECK(hipFree(Dd)); + + if (passed == 1) { + return true; + } + return false; +} + +bool run_rnorm4d() { + double *A, *Ad, *B, *Bd, *C, *Cd, *D, *Dd, *E, *Ed; + A = new double[N]; + B = new double[N]; + C = new double[N]; + D = new double[N]; + E = new double[N]; + double val = 0.0; + for (int i = 0; i < N; i++) { + A[i] = 1.0; + B[i] = 2.0; + C[i] = 3.0; + D[i] = 4.0; + } + val = 1 / sqrt(1.0 + 4.0 + 9.0 + 16.0); + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Cd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Dd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Ed), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Bd, B, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Cd, C, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Dd, D, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_rnorm4d, dim3(1), dim3(N), 0, 0, Ad, + Bd, Cd, Dd, Ed); + HIP_CHECK(hipMemcpy(E, Ed, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if (E[i] - val < 0.000001) { + passed = 1; + } + } + + delete[] A; + delete[] B; + delete[] C; + delete[] D; + delete[] E; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + HIP_CHECK(hipFree(Cd)); + HIP_CHECK(hipFree(Dd)); + HIP_CHECK(hipFree(Ed)); + + if (passed == 1) { + return true; + } + return false; +} + +bool run_rnorm() { + double *A, *Ad, *B, *Bd; + A = new double[N]; + B = new double[N]; + double val = 0.0; + for (int i = 0; i < N; i++) { + A[i] = 1.0; + B[i] = 0.0; + val += 1.0; + } + val = 1 / sqrt(val); + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_rnorm, dim3(1), dim3(N), 0, 0, Ad, Bd); + HIP_CHECK(hipMemcpy(B, Bd, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if (B[0] - val < 0.000001) { + passed = 1; + } + } + + delete[] A; + delete[] B; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + + if (passed == 1) { + return true; + } + return false; +} + +bool run_erfinv() { + double *A, *Ad, *B, *Bd; + A = new double[N]; + B = new double[N]; + for (int i = 0; i < N; i++) { + A[i] = -0.6; + B[i] = 0.0; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Bd), SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(test_erfinv, dim3(1), dim3(N), 0, 0, Ad, Bd); + HIP_CHECK(hipMemcpy(B, Bd, SIZE, hipMemcpyDeviceToHost)); + int passed = 0; + for (int i = 0; i < 512; i++) { + if (B[i] - A[i] < 0.000001) { + passed = 1; + } + } + + delete[] A; + delete[] B; + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + + if (passed == 1) { + return true; + } + return false; +} + +TEST_CASE("Unit_hipTrigDeviceFunc_Double") { + bool result = false; + result = run_sincos() && run_sincospi() && run_llrint() && + run_norm3d() && run_norm4d() && run_rnorm3d() && + run_rnorm4d() && run_rnorm() && run_lround() && run_llround() + && run_rint() && run_rhypot() && run_erfinv(); + REQUIRE(result == true); +} diff --git a/catch/unit/deviceLib/hipTestDeviceLimit.cc b/catch/unit/deviceLib/hipTestDeviceLimit.cc new file mode 100644 index 0000000000..d085efde34 --- /dev/null +++ b/catch/unit/deviceLib/hipTestDeviceLimit.cc @@ -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 +TEST_CASE("Unit_hipTestDeviceLimit_Basic") { + size_t heap; + HIP_CHECK(hipDeviceGetLimit(&heap, hipLimitMallocHeapSize)); + REQUIRE(heap != NULL); +} diff --git a/catch/unit/deviceLib/hipTestDeviceSymbol.cc b/catch/unit/deviceLib/hipTestDeviceSymbol.cc index c7bfa59283..3a2a103906 100644 --- a/catch/unit/deviceLib/hipTestDeviceSymbol.cc +++ b/catch/unit/deviceLib/hipTestDeviceSymbol.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 @@ -33,25 +33,32 @@ constexpr size_t SIZE = 1024 * 4; __device__ int globalIn[NUM]; __device__ int globalOut[NUM]; -__global__ void Assign(int* Out) { +__global__ static void Assign(int* Out) { int tid = threadIdx.x + blockIdx.x * blockDim.x; Out[tid] = globalIn[tid]; globalOut[tid] = globalIn[tid]; } __device__ __constant__ int globalConst[NUM]; +__device__ static __constant__ float statConstVar[NUM]; -__global__ void checkAddress(int* addr, bool* out) { *out = (globalConst == addr); } +__global__ void checkAddress(int* addr, bool* out) { + *out = (globalConst == addr); +} +__global__ void checkStaticConstVarAddress(float* addr, bool* out) { + *out = (statConstVar == addr); +} TEST_CASE("Unit_hipMemcpyToSymbolAsync_ToNFrom") { - int *A{nullptr}, *Am{nullptr}, *B{nullptr}, *Ad{nullptr}, *C{nullptr}, *Cm{nullptr}; + int *A{nullptr}, *Am{nullptr}, *B{nullptr}, *Ad{nullptr}, + *C{nullptr}, *Cm{nullptr}; A = new int[NUM]; B = new int[NUM]; C = new int[NUM]; - HIP_CHECK(hipMalloc((void**)&Ad, SIZE)); - HIP_CHECK(hipHostMalloc((void**)&Am, SIZE)); - HIP_CHECK(hipHostMalloc((void**)&Cm, SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + HIP_CHECK(hipHostMalloc(reinterpret_cast(&Am), SIZE)); + HIP_CHECK(hipHostMalloc(reinterpret_cast(&Cm), SIZE)); for (size_t i = 0; i < NUM; i++) { A[i] = -1 * static_cast(i); @@ -66,13 +73,14 @@ TEST_CASE("Unit_hipMemcpyToSymbolAsync_ToNFrom") { hipStream_t stream{}; HIP_CHECK(hipStreamCreate(&stream)); HIP_CHECK( - hipMemcpyToSymbolAsync(HIP_SYMBOL(globalIn), Am, SIZE, 0, hipMemcpyHostToDevice, stream)); + hipMemcpyToSymbolAsync(HIP_SYMBOL(globalIn), Am, SIZE, 0, + hipMemcpyHostToDevice, stream)); HIP_CHECK(hipStreamSynchronize(stream)); hipLaunchKernelGGL(Assign, dim3(1, 1, 1), dim3(NUM, 1, 1), 0, 0, Ad); - HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipGetLastError()); HIP_CHECK(hipMemcpy(B, Ad, SIZE, hipMemcpyDeviceToHost)); - HIP_CHECK(hipMemcpyFromSymbolAsync(Cm, HIP_SYMBOL(globalOut), SIZE, 0, hipMemcpyDeviceToHost, - stream)); + HIP_CHECK(hipMemcpyFromSymbolAsync(Cm, HIP_SYMBOL(globalOut), SIZE, 0, + hipMemcpyDeviceToHost, stream)); HIP_CHECK(hipStreamSynchronize(stream)); HIP_CHECK(hipStreamDestroy(stream)); for (size_t i = 0; i < NUM; i++) { @@ -82,11 +90,13 @@ TEST_CASE("Unit_hipMemcpyToSymbolAsync_ToNFrom") { } SECTION("Calling hipMemcpyTo/FromSymbol - validate value in host memory") { - HIP_CHECK(hipMemcpyToSymbol(HIP_SYMBOL(globalIn), A, SIZE, 0, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpyToSymbol(HIP_SYMBOL(globalIn), A, SIZE, 0, + hipMemcpyHostToDevice)); hipLaunchKernelGGL(Assign, dim3(1, 1, 1), dim3(NUM, 1, 1), 0, 0, Ad); - HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipGetLastError()); HIP_CHECK(hipMemcpy(B, Ad, SIZE, hipMemcpyDeviceToHost)); - HIP_CHECK(hipMemcpyFromSymbol(C, HIP_SYMBOL(globalOut), SIZE, 0, hipMemcpyDeviceToHost)); + HIP_CHECK(hipMemcpyFromSymbol(C, HIP_SYMBOL(globalOut), SIZE, 0, + hipMemcpyDeviceToHost)); for (size_t i = 0; i < NUM; i++) { REQUIRE(A[i] == B[i]); @@ -98,13 +108,15 @@ TEST_CASE("Unit_hipMemcpyToSymbolAsync_ToNFrom") { hipStream_t stream{}; HIP_CHECK(hipStreamCreate(&stream)); HIP_CHECK( - hipMemcpyToSymbolAsync(HIP_SYMBOL(globalIn), A, SIZE, 0, hipMemcpyHostToDevice, stream)); + hipMemcpyToSymbolAsync(HIP_SYMBOL(globalIn), A, SIZE, 0, + hipMemcpyHostToDevice, stream)); HIP_CHECK(hipStreamSynchronize(stream)); hipLaunchKernelGGL(Assign, dim3(1, 1, 1), dim3(NUM, 1, 1), 0, 0, Ad); - HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipGetLastError()); HIP_CHECK(hipMemcpy(B, Ad, SIZE, hipMemcpyDeviceToHost)); HIP_CHECK( - hipMemcpyFromSymbolAsync(C, HIP_SYMBOL(globalOut), SIZE, 0, hipMemcpyDeviceToHost, stream)); + hipMemcpyFromSymbolAsync(C, HIP_SYMBOL(globalOut), SIZE, 0, + hipMemcpyDeviceToHost, stream)); HIP_CHECK(hipStreamSynchronize(stream)); HIP_CHECK(hipStreamDestroy(stream)); @@ -115,14 +127,14 @@ TEST_CASE("Unit_hipMemcpyToSymbolAsync_ToNFrom") { } SECTION("Calling hipMemcpyTo/FromSymbol using hipStreamPerThread") { - HIP_CHECK(hipMemcpyToSymbolAsync(HIP_SYMBOL(globalIn), A, SIZE, 0, hipMemcpyHostToDevice, - hipStreamPerThread)); + HIP_CHECK(hipMemcpyToSymbolAsync(HIP_SYMBOL(globalIn), A, SIZE, 0, + hipMemcpyHostToDevice, hipStreamPerThread)); HIP_CHECK(hipStreamSynchronize(hipStreamPerThread)); hipLaunchKernelGGL(Assign, dim3(1, 1, 1), dim3(NUM, 1, 1), 0, 0, Ad); - HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipGetLastError()); HIP_CHECK(hipMemcpy(B, Ad, SIZE, hipMemcpyDeviceToHost)); - HIP_CHECK(hipMemcpyFromSymbolAsync(C, HIP_SYMBOL(globalOut), SIZE, 0, hipMemcpyDeviceToHost, - hipStreamPerThread)); + HIP_CHECK(hipMemcpyFromSymbolAsync(C, HIP_SYMBOL(globalOut), SIZE, 0, + hipMemcpyDeviceToHost, hipStreamPerThread)); HIP_CHECK(hipStreamSynchronize(hipStreamPerThread)); for (size_t i = 0; i < NUM; i++) { @@ -140,14 +152,18 @@ TEST_CASE("Unit_hipMemcpyToSymbolAsync_ToNFrom") { size_t symbolSize = 0; int* symbolAddress{nullptr}; HIP_CHECK(hipGetSymbolSize(&symbolSize, HIP_SYMBOL(globalConst))); - HIP_CHECK(hipGetSymbolAddress((void**)&symbolAddress, HIP_SYMBOL(globalConst))); - HIP_CHECK(hipMalloc((void**)&checkOkD, sizeof(bool))); - hipLaunchKernelGGL(checkAddress, dim3(1, 1, 1), dim3(1, 1, 1), 0, 0, symbolAddress, checkOkD); - HIP_CHECK(hipGetLastError()); - HIP_CHECK(hipMemcpy(&checkOk, checkOkD, sizeof(bool), hipMemcpyDeviceToHost)); + HIP_CHECK(hipGetSymbolAddress(reinterpret_cast(&symbolAddress), + HIP_SYMBOL(globalConst))); + HIP_CHECK(hipMalloc(reinterpret_cast(&checkOkD), + sizeof(bool))); + hipLaunchKernelGGL(checkAddress, dim3(1, 1, 1), dim3(1, 1, 1), 0, 0, + symbolAddress, checkOkD); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipMemcpy(&checkOk, checkOkD, sizeof(bool), + hipMemcpyDeviceToHost)); HIP_CHECK(hipFree(checkOkD)); - HIP_ASSERT(checkOk); - HIP_ASSERT((symbolSize == SIZE)); + REQUIRE(checkOk); + REQUIRE((symbolSize == SIZE)); } HIP_CHECK(hipHostFree(Am)); @@ -157,11 +173,9 @@ TEST_CASE("Unit_hipMemcpyToSymbolAsync_ToNFrom") { delete[] B; delete[] C; } - -/** - 1) Validate get symbol address/size for global const array. - 2) Validate get symbol address/size for static const variable. - */ +/* + 1) Validate get symbol address/size for static const variable. +*/ TEST_CASE("Unit_hipGetSymbolAddressAndSize_Validation") { bool* checkOkD{nullptr}; bool checkOk = false; @@ -169,32 +183,20 @@ TEST_CASE("Unit_hipGetSymbolAddressAndSize_Validation") { int* symbolArrAddress{}; float* symbolVarAddress{}; - SECTION("Validate symbol size/address of global const array") { - HIP_CHECK(hipGetSymbolSize(&symbolSize, HIP_SYMBOL(globalConstArr))); - HIP_CHECK(hipGetSymbolAddress(reinterpret_cast(&symbolArrAddress), - HIP_SYMBOL(globalConstArr))); - HIP_CHECK(hipMalloc(&checkOkD, sizeof(bool))); - hipLaunchKernelGGL(checkGlobalConstAddress, dim3(1, 1, 1), dim3(1, 1, 1), 0, 0, - symbolArrAddress, checkOkD); - HIP_CHECK(hipGetLastError()); - HIP_CHECK(hipMemcpy(&checkOk, checkOkD, sizeof(bool), hipMemcpyDeviceToHost)); - HIP_CHECK(hipFree(checkOkD)); - HIP_ASSERT(checkOk); - HIP_ASSERT(symbolSize == SIZE); - } - SECTION("Validate symbol size/address of static const variable") { HIP_CHECK(hipGetSymbolSize(&symbolSize, HIP_SYMBOL(statConstVar))); HIP_CHECK( - hipGetSymbolAddress(reinterpret_cast(&symbolVarAddress), HIP_SYMBOL(statConstVar))); + hipGetSymbolAddress(reinterpret_cast(&symbolVarAddress), + HIP_SYMBOL(statConstVar))); HIP_CHECK(hipMalloc(&checkOkD, sizeof(bool))); - hipLaunchKernelGGL(checkStaticConstVarAddress, dim3(1, 1, 1), dim3(1, 1, 1), 0, 0, - symbolVarAddress, checkOkD); - HIP_CHECK(hipGetLastError()); - HIP_CHECK(hipMemcpy(&checkOk, checkOkD, sizeof(bool), hipMemcpyDeviceToHost)); + hipLaunchKernelGGL(checkStaticConstVarAddress, dim3(1, 1, 1), + dim3(1, 1, 1), 0, 0, symbolVarAddress, checkOkD); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipMemcpy(&checkOk, checkOkD, sizeof(bool), + hipMemcpyDeviceToHost)); HIP_CHECK(hipFree(checkOkD)); - HIP_ASSERT(checkOk); - HIP_ASSERT(symbolSize == sizeof(float)); + REQUIRE(checkOk); + REQUIRE(symbolSize == SIZE); } } @@ -202,15 +204,14 @@ TEST_CASE("Unit_hipGetSymbolAddress_Negative") { SECTION("Invalid symbol") { int notADeviceSymbol{0}; int* addr{nullptr}; - HIP_CHECK_ERROR( - hipGetSymbolAddress(reinterpret_cast(&addr), HIP_SYMBOL(notADeviceSymbol)), - hipErrorInvalidSymbol); + HIP_CHECK_ERROR(hipGetSymbolAddress(reinterpret_cast(&addr), + HIP_SYMBOL(notADeviceSymbol)), hipErrorInvalidSymbol); } SECTION("Nullptr symbol") { int* addr{nullptr}; - HIP_CHECK_ERROR(hipGetSymbolAddress(reinterpret_cast(&addr), nullptr), - hipErrorInvalidSymbol); + HIP_CHECK_ERROR(hipGetSymbolAddress(reinterpret_cast(&addr), + nullptr), hipErrorInvalidSymbol); } } @@ -218,7 +219,8 @@ TEST_CASE("Unit_hipGetSymbolSize_Negative") { SECTION("Invalid symbol") { int notADeviceSymbol{0}; size_t dsize{0}; - HIP_CHECK_ERROR(hipGetSymbolSize(&dsize, HIP_SYMBOL(notADeviceSymbol)), hipErrorInvalidSymbol); + HIP_CHECK_ERROR(hipGetSymbolSize(&dsize, HIP_SYMBOL(notADeviceSymbol)), + hipErrorInvalidSymbol); } SECTION("Nullptr symbol") { diff --git a/catch/unit/deviceLib/hipTestDotFunctions.cc b/catch/unit/deviceLib/hipTestDotFunctions.cc new file mode 100644 index 0000000000..43f0492da5 --- /dev/null +++ b/catch/unit/deviceLib/hipTestDotFunctions.cc @@ -0,0 +1,54 @@ +/* +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 + +__global__ static void DotFunctions(bool* result) { + // Dot Functions + #if HT_AMD + short2 sa{1}, sb{1}; + result[0] = amd_mixed_dot(sa, sb, 1, result[0]) && result[0]; + + ushort2 usa{1}, usb{1}; + result[0] = amd_mixed_dot(usa, usb, (uint) 1, result[0]) && result[0]; + + char4 ca{1}, cb{1}; + result[0] = amd_mixed_dot(ca, cb, 1, result[0]) && result[0]; + + uchar4 uca{1}, ucb{1}; + result[0] = amd_mixed_dot(uca, ucb, (uint) 1, result[0]) && result[0]; + + int ia{1}, ib{1}; + result[0] = amd_mixed_dot(ia, ib, 1, result[0]) && result[0]; + + uint ua{1}, ub{1}; + result[0] = amd_mixed_dot(ua, ub, (uint) 1, result[0]) && result[0]; + #endif +} + +TEST_CASE("Unit_hipTestDotFunctions") { + bool* result{nullptr}; + hipHostMalloc(&result, 1); + result[0] = true; + hipLaunchKernelGGL(DotFunctions, dim3(1, 1, 1), dim3(1, 1, 1), 0, 0, result); + hipDeviceSynchronize(); + REQUIRE(result[0] == true); + hipHostFree(result); +} diff --git a/catch/unit/deviceLib/hipTestFMA.cc b/catch/unit/deviceLib/hipTestFMA.cc new file mode 100644 index 0000000000..3e496f4d17 --- /dev/null +++ b/catch/unit/deviceLib/hipTestFMA.cc @@ -0,0 +1,183 @@ +/* +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 50 +#define SIZE (LEN * sizeof(bool)) + +__global__ void kernelTestFMA(bool *Ad) { + float f = 1.0f / 3.0f; + double d = f; + int i = 0; + auto Check = [&](bool Cond) { Ad[i++] = Cond; }; + // f * f + 3.0f will be different if promoted to double. + float floatResult = fma(f, f, 3.0f); + double doubleResult = fma(d, d, 3.0); + Check(floatResult != doubleResult); + + if (sizeof(decltype(fma(f, f, 3))) == 8) { + // To align with libcxx, if any argument has integral type, + // it is cast to double. + // Check type promotes to double. + Check(fma(f, f, 3) == doubleResult); + Check(fma(f, f, static_cast(3)) == doubleResult); + Check(fma(f, f, (unsigned char)3) == doubleResult); + Check(fma(f, f, (int32_t)3) == doubleResult); + Check(fma(f, f, (uint32_t)3) == doubleResult); + Check(fma(f, f, static_cast(3)) == doubleResult); + Check(fma(f, f, (unsigned int)3) == doubleResult); + Check(fma(f, f, (int64_t)3) == doubleResult); + Check(fma(f, f, (uint64_t)3) == doubleResult); + Check(fma(f, f, true) == fma(static_cast(f), + static_cast(f), 1.0)); + } else if (sizeof(decltype(fma(f, f, 3))) == 4) { + // Previous HIP headers returns float type. + // Delete this to support backwards compatibility. + // check promote to float. + Check(fma(f, f, 3) == floatResult); + Check(fma(f, f, static_cast(3)) == floatResult); + Check(fma(f, f, (unsigned char)3) == floatResult); + Check(fma(f, f, (int32_t)3) == floatResult); + Check(fma(f, f, (uint32_t)3) == floatResult); + Check(fma(f, f, static_cast(3)) == floatResult); + Check(fma(f, f, (unsigned int)3) == floatResult); + Check(fma(f, f, (int64_t)3) == floatResult); + Check(fma(f, f, (uint64_t)3) == floatResult); + Check(fma(f, f, true) == fma(f, f, 1.0f)); + } else { + Check(false); + } + + Check(fma(d, static_cast(f), 3) == doubleResult); + Check(fma(d, static_cast(f), static_cast(3)) == doubleResult); + Check(fma(d, static_cast(f), (unsigned char)3) == doubleResult); + Check(fma(d, static_cast(f), (int32_t)3) == doubleResult); + Check(fma(d, static_cast(f), (uint32_t)3) == doubleResult); + Check(fma(d, static_cast(f), static_cast(3)) == doubleResult); + Check(fma(d, static_cast(f), (unsigned int)3) == doubleResult); + Check(fma(d, static_cast(f), (int64_t)3) == doubleResult); + Check(fma(d, static_cast(f), (int64_t)3) == doubleResult); + Check(fma(d, static_cast(f), true) == + fma(static_cast(f), static_cast(f), 1.0)); + + while (i < LEN) + Check(true); + } + +void runTestFMA() { + bool *Ad; + bool A[LEN]; + for (unsigned i = 0; i < LEN; i++) { + A[i] = 0; + } + + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + hipLaunchKernelGGL(kernelTestFMA, dim3(1, 1, 1), dim3(1, 1, 1), 0, 0, Ad); + HIP_CHECK(hipMemcpy(A, Ad, SIZE, hipMemcpyDeviceToHost)); + + for (unsigned i = 0; i < LEN; i++) { + REQUIRE(A[i] == true); + } +} + +__global__ void kernelTestHalfFMA(bool *Ad) { + _Float16 h = (_Float16)(1.0f/3.0f); + float f = h; + double d = f; + int i = 0; + auto Check = [&](bool Cond) { Ad[i++] = Cond; }; + // h * h + 3 will be different if promoted to float. + _Float16 halfResult = fma(h, h, (_Float16)3); + float floatResult = fma(f, f, 3.0f); + double doubleResult = fma(d, d, 3.0); + Check(halfResult != floatResult); + Check(halfResult != doubleResult); + + // check promote to half. + // fma(_Float16, _Float16, int) should resolve to + // fma(double, double, double). This is similar to + // fma(float, float, int) resolving to fma(double, double, double) + // as required Standard C++ header . + if (sizeof(decltype(fma(h, h, 3))) == 8) { + Check(fma(h, h, 3) == doubleResult); + Check(fma(h, h, static_cast(3)) == doubleResult); + Check(fma(h, h, (unsigned char)3) == doubleResult); + Check(fma(h, h, (int32_t)3) == doubleResult); + Check(fma(h, h, (uint32_t)3) == doubleResult); + Check(fma(h, h, static_cast(3)) == doubleResult); + Check(fma(h, h, (unsigned int)3) == doubleResult); + Check(fma(h, h, (int64_t)3) == doubleResult); + Check(fma(h, h, (uint64_t)3) == doubleResult); + Check(fma(h, h, true) == fma(static_cast(h), + static_cast(h), 1.0)); + } else if (sizeof(decltype(fma(h, h, 3))) == 2) { + // ToDo: Currently there is a bug in clang header + // __clang_hip_cmath.h due to using + // std::numeric_limits::is_specified to define + // overloaded math functions. Since numeric_limits is + // not specicialized for _Float16, overloaded template + // functions with argument promotion are not defined + // for _Float16. As a result, fma(_Float16, _Float16, int) + // is resolved to fma(_Float16, _Float16, _Float16). + // This part should be removed after __clang_hip_cmath.h + // is fixed. + Check(fma(h, h, 3) == halfResult); + Check(fma(h, h, static_cast(3)) == halfResult); + Check(fma(h, h, (unsigned char)3) == halfResult); + Check(fma(h, h, (int32_t)3) == halfResult); + Check(fma(h, h, (uint32_t)3) == halfResult); + Check(fma(h, h, static_cast(3)) == halfResult); + Check(fma(h, h, (unsigned int)3) == halfResult); + Check(fma(h, h, (int64_t)3) == halfResult); + Check(fma(h, h, (int64_t)3) == halfResult); + Check(fma(h, h, true) == fma(h, h, (_Float16)1)); + } else { + Check(false); + } + + while (i < LEN) + Check(true); +} + +void runTestHalfFMA() { + bool *Ad; + bool A[LEN]; + for (unsigned i = 0; i < LEN; i++) { + A[i] = 0; + } + + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), SIZE)); + hipLaunchKernelGGL(kernelTestHalfFMA, dim3(1, 1, 1), dim3(1, 1, 1), + 0, 0, Ad); + HIP_CHECK(hipMemcpy(A, Ad, SIZE, hipMemcpyDeviceToHost)); + + for (unsigned i = 0; i < LEN; i++) { + REQUIRE(A[i] == true); + } +} + +TEST_CASE("Unit_hipTestFMA") { + SECTION("test FMA") { + runTestFMA(); + } + SECTION("test HalfFMA") { + runTestHalfFMA(); + } +} diff --git a/catch/unit/deviceLib/hipTestHalf.cc b/catch/unit/deviceLib/hipTestHalf.cc new file mode 100644 index 0000000000..936625ef56 --- /dev/null +++ b/catch/unit/deviceLib/hipTestHalf.cc @@ -0,0 +1,245 @@ +/* +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 + +__device__ void test_convert() { + __half x; + float y = static_cast(x); +} + +__global__ +void __halfMath(bool* result, __half a) { + result[0] = __heq(__hadd(a, __half{1}), __half{2}); + result[0] = __heq(__hadd_sat(a, __half{1}), __half{1}) && result[0]; + result[0] = __heq(__hfma(a, __half{2}, __half{3}), __half{5}) && result[0]; + result[0] = + __heq(__hfma_sat(a, __half{2}, __half{3}), __half{1}) && result[0]; + result[0] = __heq(__hsub(a, __half{1}), __half{0}) && result[0]; + result[0] = __heq(__hsub_sat(a, __half{2}), __half{0}) && result[0]; + result[0] = __heq(__hmul(a, __half{2}), __half{2}) && result[0]; + result[0] = __heq(__hmul_sat(a, __half{2}), __half{1}) && result[0]; + result[0] = __heq(__hdiv(a, __half{2}), __half{0.5}) && result[0]; +} + +__device__ +bool to_bool(const __half2& x) { + auto r = static_cast(x); + + return r.data.x != 0 && r.data.y != 0; +} + +__global__ +void __half2Math(bool* result, __half2 a) { + result[0] = + to_bool(__heq2(__hadd2(a, __half2{1, 1}), __half2{2, 2})); + result[0] = to_bool(__heq2(__hadd2_sat(a, __half2{1, 1}), __half2{1, 1})) && + result[0]; + result[0] = to_bool(__heq2( + __hfma2(a, __half2{2, 2}, __half2{3, 3}), __half2{5, 5})) && result[0]; + result[0] = to_bool(__heq2( + __hfma2_sat(a, __half2{2, 2}, __half2{3, 3}), __half2{1, 1})) && result[0]; + result[0] = to_bool(__heq2(__hsub2(a, __half2{1, 1}), __half2{0, 0})) && + result[0]; + result[0] = to_bool(__heq2(__hsub2_sat(a, __half2{2, 2}), __half2{0, 0})) && + result[0]; + result[0] = to_bool(__heq2(__hmul2(a, __half2{2, 2}), __half2{2, 2})) && + result[0]; + result[0] = to_bool(__heq2(__hmul2_sat(a, __half2{2, 2}), __half2{1, 1})) && + result[0]; + result[0] = to_bool(__heq2(__h2div(a, __half2{2, 2}), __half2{0.5, 0.5})) && + result[0]; +} + +__global__ +void kernel_hisnan(__half* input, int* output) { + int tx = threadIdx.x; + output[tx] = __hisnan(input[tx]); +} + +__global__ +void kernel_hisinf(__half* input, int* output) { + int tx = threadIdx.x; + output[tx] = __hisinf(input[tx]); +} + +__global__ void testHalfAbs(float* p) { + auto a = __float2half(*p); + a = __habs(a); + *p = __half2float(a); +} + +__global__ void testHalf2Abs(float2* p) { + auto a = __float22half2_rn(*p); + a = __habs2(a); + *p = __half22float2(a); +} + +__half host_ushort_as_half(uint32_t s) { + union {__half h; uint32_t s; } converter; + converter.s = s; + return converter.h; +} + +void check_hisnan(int NUM_INPUTS, __half* inputCPU, __half* inputGPU) { + // allocate memory + auto memsize = NUM_INPUTS * sizeof(int); + int* outputGPU = nullptr; + HIP_CHECK(hipMalloc(reinterpret_cast(&outputGPU), memsize)); + + // launch the kernel + hipLaunchKernelGGL( + kernel_hisnan, dim3(1), dim3(NUM_INPUTS), 0, 0, inputGPU, outputGPU); + + // copy output from device + int* outputCPU = reinterpret_cast (malloc(memsize)); + HIP_CHECK(hipMemcpy(outputCPU, outputGPU, memsize, hipMemcpyDeviceToHost)); + + // check output + for (int i=0; i < NUM_INPUTS; i++) { + if ((2 <= i) && (i <= 5)) { // inputs are nan, output should be true + REQUIRE(outputCPU[i] == true); + } else { // inputs are NOT nan, output should be false + REQUIRE(outputCPU[i] == false); + } + } + + // free memory + free(outputCPU); + HIP_CHECK(hipFree(outputGPU)); +} + + +void check_hisinf(int NUM_INPUTS, __half* inputCPU, __half* inputGPU) { + // allocate memory + auto memsize = NUM_INPUTS * sizeof(int); + int* outputGPU = nullptr; + HIP_CHECK(hipMalloc(reinterpret_cast(&outputGPU), memsize)); + + // launch the kernel + hipLaunchKernelGGL( + kernel_hisinf, dim3(1), dim3(NUM_INPUTS), 0, 0, inputGPU, outputGPU); + + // copy output from device + int* outputCPU = reinterpret_cast (malloc(memsize)); + HIP_CHECK(hipMemcpy(outputCPU, outputGPU, memsize, hipMemcpyDeviceToHost)); + + // check output + for (int i=0; i < NUM_INPUTS; i++) { + if ((0 <= i) && (i <= 1)) { // inputs are inf, output should be true + REQUIRE(outputCPU[i] == true); + } else { // inputs are NOT inf, output should be false + REQUIRE(outputCPU[i] == false); + } + } + // free memory + free(outputCPU); + HIP_CHECK(hipFree(outputGPU)); +} + + +void checkFunctional() { + // allocate memory + const int NUM_INPUTS = 16; + auto memsize = NUM_INPUTS * sizeof(__half); + __half* inputCPU = reinterpret_cast<__half*> (malloc(memsize)); + + // populate inputs + inputCPU[0] = host_ushort_as_half(0x7c00); // inf + inputCPU[1] = host_ushort_as_half(0xfc00); // -inf + inputCPU[2] = host_ushort_as_half(0x7c01); // nan + inputCPU[3] = host_ushort_as_half(0x7e00); // nan + inputCPU[4] = host_ushort_as_half(0xfc01); // nan + inputCPU[5] = host_ushort_as_half(0xfe00); // nan + inputCPU[6] = host_ushort_as_half(0x0000); // 0 + inputCPU[7] = host_ushort_as_half(0x8000); // -0 + inputCPU[8] = host_ushort_as_half(0x7bff); // max +ve normal + inputCPU[9] = host_ushort_as_half(0xfbff); // max -ve normal + inputCPU[10] = host_ushort_as_half(0x0400); // min +ve normal + inputCPU[11] = host_ushort_as_half(0x8400); // min -ve normal + inputCPU[12] = host_ushort_as_half(0x03ff); // max +ve sub-normal + inputCPU[13] = host_ushort_as_half(0x83ff); // max -ve sub-normal + inputCPU[14] = host_ushort_as_half(0x0001); // min +ve sub-normal + inputCPU[15] = host_ushort_as_half(0x8001); // min -ve sub-normal + + // copy inputs to the GPU + __half* inputGPU = nullptr; + HIP_CHECK(hipMalloc(reinterpret_cast(&inputGPU), memsize)); + HIP_CHECK(hipMemcpy(inputGPU, inputCPU, memsize, hipMemcpyHostToDevice)); + + // run checks + check_hisnan(NUM_INPUTS, inputCPU, inputGPU); + check_hisinf(NUM_INPUTS, inputCPU, inputGPU); + + // free memory + HIP_CHECK(hipFree(inputGPU)); + free(inputCPU); +} + +void checkHalfAbs() { + SECTION("Half Abs") { + float *p; + HIP_CHECK(hipMalloc(&p, sizeof(float))); + float pp = -2.1f; + HIP_CHECK(hipMemcpy(p, &pp, sizeof(float), hipMemcpyDefault)); + hipLaunchKernelGGL(testHalfAbs, 1, 1, 0, 0, p); + HIP_CHECK(hipMemcpy(&pp, p, sizeof(float), hipMemcpyDefault)); + HIP_CHECK(hipFree(p)); + REQUIRE(pp >= 0.0f); + } + SECTION("Half2 Abs") { + float2 *p; + HIP_CHECK(hipMalloc(&p, sizeof(float2))); + float2 pp; + pp.x = -2.1f; + pp.y = -1.1f; + HIP_CHECK(hipMemcpy(p, &pp, sizeof(float2), hipMemcpyDefault)); + hipLaunchKernelGGL(testHalf2Abs, 1, 1, 0, 0, p); + HIP_CHECK(hipMemcpy(&pp, p, sizeof(float2), hipMemcpyDefault)); + HIP_CHECK(hipFree(p)); + bool result = true; + if (pp.x < 0.0f || pp.y < 0.0f) { result = false; } + REQUIRE(result == true); + } +} + +TEST_CASE("Unit_hipTestHalf") { + bool* result{nullptr}; + HIP_CHECK(hipHostMalloc(&result, sizeof(result))); + + SECTION("Test half math") { + result[0] = false; + hipLaunchKernelGGL( + __halfMath, dim3(1, 1, 1), dim3(1, 1, 1), 0, 0, result, __half{1}); + HIP_CHECK(hipDeviceSynchronize()); + REQUIRE(result[0] == true); + } + SECTION("Test half math") { + result[0] = false; + hipLaunchKernelGGL( + __half2Math, dim3(1, 1, 1), dim3(1, 1, 1), 0, 0, result, __half2{1, 1}); + HIP_CHECK(hipDeviceSynchronize()); + REQUIRE(result[0] == true); + } + SECTION("Functional checks") { + checkFunctional(); + checkHalfAbs(); + } + HIP_CHECK(hipHostFree(result)); +} diff --git a/catch/unit/deviceLib/hipTestHost.cc b/catch/unit/deviceLib/hipTestHost.cc new file mode 100644 index 0000000000..e1e77ff9e3 --- /dev/null +++ b/catch/unit/deviceLib/hipTestHost.cc @@ -0,0 +1,408 @@ +/* +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 + +#define N 512 + +__device__ bool check_erfcinvf() { + uint32_t len = 4; + float Val[] = {0.1, 1.2, 1, 0.9}; + float Out[] = {1.16309, -0.179144, 0, 0.0889}; + for (int i = 0; i < len; i++) { + if ((Out[i] - erfcinvf(Val[i])) > 0.0001) { + return false; + } + } + return true; +} + +__device__ bool check_erfcxf() { + uint32_t len = 4; + float Val[] = {-0.5, 15, 3.2, 1}; + float Out[] = {1.9524, 0.0375, 0.1687, 0.4276}; + for (int i = 0; i < len; i++) { + if (Out[i] - erfcxf(Val[i]) > 0.0001) { + return false; + } + } + return true; +} + +__device__ bool check_erfinvf() { + uint32_t len = 4; + float Val[] = {0, -0.5, 0.9, -0.2}; + float Out[] = {0, -0.4769, 1.1631, -0.1791}; + for (int i = 0; i < len; i++) { + if (Out[i] - erfinvf(Val[i]) > 0.0001) { + return false; + } + } + return true; +} + +__device__ bool check_fdividef() { + uint32_t len = 4; + float Val[] = {0, -0.5, 0.9, -0.2}; + float Out[] = {1, -0.4769, 1.1631, -0.1791}; + for (int i = 0; i < len; i++) { + if (Val[i] / Out[i] - fdividef(Val[i], Out[i]) > 0.0001) { + return false; + } + } + return true; +} + +__device__ bool check_erfcinv() { + uint32_t len = 4; + double Val[] = {0.1, 1.2, 1, 0.9}; + double Out[] = {1.16309, -0.179144, 0, 0.0889}; + for (int i = 0; i < len; i++) { + if (Out[i] - erfcinv(Val[i]) > 0.0001) { + return false; + } + } + return true; +} + +__device__ bool check_erfcx() { + uint32_t len = 4; + double Val[] = {-0.5, 15, 3.2, 1}; + double Out[] = {1.9524, 0.0375, 0.1687, 0.4276}; + for (int i = 0; i < len; i++) { + if (Out[i] - erfcx(Val[i]) > 0.0001) { + return false; + } + } + return true; +} + +__device__ bool check_erfinv() { + uint32_t len = 4; + double Val[] = {0, -0.5, 0.9, -0.2}; + double Out[] = {0, -0.4769, 1.1631, -0.1791}; + for (int i = 0; i < len; i++) { + if (Out[i] - erfinv(Val[i]) > 0.0001) { + return false; + } + } + return true; +} + +__device__ bool check_fdivide() { + uint32_t len = 4; + double Val[] = {0, -0.5, 0.9, -0.2}; + double Out[] = {1, -0.4769, 1.1631, -0.1791}; + for (int i = 0; i < len; i++) { + if (Val[i] / Out[i] - fdividef(Val[i], Out[i]) > 0.0001) { + return false; + } + } + return true; +} + +__device__ bool check_modff() { + uint32_t len = 4; + float Val[] = {0, -0.5, 0.9, -0.2}; + float iPtr[] = {0, 0, 0, 0}; + float frac[] = {0, -0.5, 0.9, -0.2}; + float Out[] = {1, 1, 1, 1}; + for (int i = 0; i < len; i++) { + if (frac[i] - modff(Val[i], Out + i) > 0.0001 && iPtr[i] == Out[i]) { + return false; + } + } + return true; +} + +__device__ bool check_modf() { + uint32_t len = 4; + double Val[] = {0, -0.5, 0.9, -0.2}; + double iPtr[] = {0, 0, 0, 0}; + double frac[] = {0, -0.5, 0.9, -0.2}; + double Out[] = {1, 1, 1, 1}; + for (int i = 0; i < len; i++) { + if (frac[i] - modf(Val[i], Out + i) > 0.0001 && iPtr[i] == Out[i]) { + return false; + } + } + return true; +} + +__device__ bool check_nextafterf() { + uint32_t len = 4; + float Val[] = {0, -0.5, 0.9, -0.2}; + float iPtr[] = {0, 0, 0, 0}; + float frac[] = {0, -0.5, 0.9, -0.2}; + float Out[] = {1, 1, 1, 1}; + for (int i = 0; i < len; i++) { + if (nextafterf(Val[i], 1) - Val[i] > 0.0001) { + return false; + } + } + return true; +} + +__device__ bool check_nextafter() { + uint32_t len = 4; + double Val[] = {0, -0.5, 0.9, -0.2}; + double iPtr[] = {0, 0, 0, 0}; + double frac[] = {0, -0.5, 0.9, -0.2}; + double Out[] = {1, 1, 1, 1}; + for (int i = 0; i < len; i++) { + if (nextafter(Val[i], 1) - Val[i] > 0.0001) { + return false; + } + } + return true; +} + +__device__ bool check_norm3df(float* A) { + float f = norm3df(A[0], A[1], A[2]); + float out = sqrt(A[0] * A[0] + A[1] * A[1] + A[2] * A[2]); + if (f - out > 0.0001) { + return false; + } + return true; +} + +__device__ bool check_norm3d(double* A) { + double f = norm3d(A[0], A[1], A[2]); + double out = sqrt(A[0] * A[0] + A[1] * A[1] + A[2] * A[2]); + if (f - out > 0.0001) { + return false; + } + return true; +} + +__device__ bool check_norm4df(float* A) { + float f = norm4df(A[0], A[1], A[2], A[3]); + float out = sqrt(A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + A[3] * A[3]); + if (f - out > 0.0001) { + return false; + } + return true; +} + +__device__ bool check_norm4d(double* A) { + double f = norm4d(A[0], A[1], A[2], A[3]); + double out = sqrt(A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + A[3] * A[3]); + if (f - out > 0.0001) { + return false; + } + return true; +} + +__device__ bool check_normcdff() { + uint32_t len = 2; + float Val[] = {0, 1}; + float Out[] = {0.5, 0.8413}; + for (int i = 0; i < len; i++) { + if (Out[i] - normcdff(Val[i]) > 0.0001) { + return false; + } + } + return true; +} + +__device__ bool check_normcdf() { + uint32_t len = 2; + float Val[] = {0, 1}; + float Out[] = {0.5, 0.8413}; + for (int i = 0; i < len; i++) { + if (Out[i] - normcdf(Val[i]) > 0.0001) { + return false; + } + } + return true; +} + +__device__ bool check_normcdfinvf() { + uint32_t len = 2; + double Val[] = {0.5, 0.8413}; + for (int i = 0; i < len; i++) { + if (Val[i] - normcdfinvf(normcdff(Val[i])) > 0.0001) { + return false; + } + } + return true; +} + +__device__ bool check_normcdfinv() { + uint32_t len = 2; + double Val[] = {0.5, 0.8413}; + for (int i = 0; i < len; i++) { + if (Val[i] - normcdfinv(normcdf(Val[i])) > 0.0001) { + return false; + } + } + return true; +} + +__device__ bool check_rcbrtf() { + float f = 1.0f; + if (rcbrtf(f) != 1.0f) { + return false; + } + return true; +} + +__device__ bool check_rcbrt() { + double f = 1.0; + if (rcbrt(f) != 1.0) { + return false; + } + return true; +} + +__device__ bool check_rhypotf() { + float f = 1.0f; + float g = 2.0f; + float val = rhypotf(f, g); + float sq = f * f + g * g; + if (1 / (val * val) - sq > 0.0001) { + return false; + } + return true; +} + +__device__ bool check_rhypot() { + double f = 1.0f; + double g = 2.0f; + double val = rhypot(f, g); + double sq = f * f + g * g; + if (1 / (val * val) - sq > 0.0001) { + return false; + } + return true; +} + +__device__ bool check_rnorm3df(float* A) { + float f = rnorm3df(A[0], A[1], A[2]); + float out = sqrt(A[0] * A[0] + A[1] * A[1] + A[2] * A[2]); + if (f - 1 / out > 0.0001) { + return false; + } + return true; +} + +__device__ bool check_rnorm3d(double* A) { + double f = rnorm3d(A[0], A[1], A[2]); + double out = sqrt(A[0] * A[0] + A[1] * A[1] + A[2] * A[2]); + if (f - 1 / out > 0.0001) { + return false; + } + return true; +} + +__device__ bool check_rnorm4df(float* A) { + float f = rnorm4df(A[0], A[1], A[2], A[3]); + float out = sqrt(A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + A[3] * A[3]); + if (f - 1 / out > 0.0001) { + return false; + } + return true; +} + +__device__ bool check_rnorm4d(double* A) { + double f = rnorm4d(A[0], A[1], A[2], A[3]); + double out = sqrt(A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + A[3] * A[3]); + if (f - 1 / out > 0.0001) { + return false; + } + return true; +} + +__device__ bool check_rnormf(float* A) { + return (rnorm3df(A[0], A[1], A[2]) - rnormf(3, A) < 0.0001) && + (rnorm4df(A[0], A[1], A[2], A[3]) - rnormf(4, A) < 0.0001); +} + +__device__ bool check_rnorm(double* A) { + return (rnorm3d(A[0], A[1], A[2]) - rnorm(3, A) < 0.0001) && + (rnorm4d(A[0], A[1], A[2], A[3]) - rnorm(4, A) < 0.0001); +} + +__device__ bool check_sincospif() { + float s1, c1, s2, c2; + float in1 = 1, in2 = 0.5; + sincospif(in1, &s1, &c1); + sincospif(in2, &s2, &c2); + if ((s1 - 0 < 0.00001) && (s2 - 1 < 0.00001) && + (c1 + 1 < 0.00001) && (c2 - 0 < 0.00001)) { + return true; + } + return false; +} + +__device__ bool check_sincospi() { + double s1, c1, s2, c2; + double in1 = 1, in2 = 0.5; + sincospi(in1, &s1, &c1); + sincospi(in2, &s2, &c2); + if ((s1 - 0 < 0.00001) && (s2 - 1 < 0.00001) && + (c1 + 1 < 0.00001) && (c2 - 0 < 0.00001)) { + return true; + } + return false; +} +__global__ void testFunctions(bool *result, float *Af, double *A) { + result[0] &= check_erfcinvf() && check_erfcxf() && check_erfcinvf() + && check_erfcinv() && check_erfcx() && check_erfcinv() + && check_fdividef() && check_fdivide() && check_modff() + && check_modf() && check_nextafterf() && check_norm3df(Af) + && check_norm3d(A) && check_norm4df(Af) && check_norm4d(A) + && check_normcdff() && check_normcdf() && check_normcdfinvf() + && check_normcdfinv() && check_rcbrtf() && check_rcbrt() && + check_rhypotf() && check_rhypot() && check_rnorm3df(Af) && + check_rnorm3d(A) && check_rnorm4df(Af) && check_rnorm4d(A) && + check_rnormf(Af) && check_rnorm(A) && check_sincospif() && + check_sincospi() && check_nextafter(); +} + +TEST_CASE("Unit_TestDevice_DoublePrecisionMathFunc") { + float* Af = new float[N]; + double* A = new double[N]; + for (int i = 0; i < N; i++) { + Af[i] = i * 1.0f; + A[i] = i * 1.0; + } + float *Afd; + double *Ad; + bool *srcPtr, *devicePtr; + srcPtr = new bool; + srcPtr[0] = true; + // Device pointers + HIP_CHECK(hipMalloc(reinterpret_cast(&devicePtr), sizeof(bool))); + HIP_CHECK(hipMalloc(reinterpret_cast(&Afd), sizeof(float)*N)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), sizeof(double)*N)); + // MemCpy + HIP_CHECK(hipMemcpy(devicePtr, srcPtr, sizeof(bool), hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Afd, Af, sizeof(float)*N, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Ad, A, sizeof(double)*N, hipMemcpyHostToDevice)); + // Kernel Launch + hipLaunchKernelGGL(testFunctions, dim3(1), dim3(1), 0, 0, devicePtr, Afd, Ad); + HIP_CHECK(hipMemcpy(srcPtr, devicePtr, sizeof(bool), hipMemcpyDeviceToHost)); + // Validation + REQUIRE(srcPtr[0] == true); + + HIP_CHECK(hipFree(devicePtr)); + delete srcPtr; + delete [] Af; + delete [] A; +} diff --git a/catch/unit/deviceLib/hipTestIncludeMath.cc b/catch/unit/deviceLib/hipTestIncludeMath.cc new file mode 100644 index 0000000000..2bb78b03b2 --- /dev/null +++ b/catch/unit/deviceLib/hipTestIncludeMath.cc @@ -0,0 +1,134 @@ +/* +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 + +// Test __HIP_DEVICE_COMPILE__ is defined after math_functions.h +// is included. +__device__ __host__ inline void throw_std_bad_alloc() { + #ifndef __HIP_DEVICE_COMPILE__ + throw std::bad_alloc(); + #else + std::size_t kHuge = static_cast(-1); + new int[kHuge]; + #endif +} + +__global__ void FloatMathPreciseKernel() { + int iX; + float fX, fY; + acosf(1.0f); + acoshf(1.0f); + asinf(0.0f); + asinhf(0.0f); + atan2f(0.0f, 1.0f); + atanf(0.0f); + atanhf(0.0f); + cbrtf(0.0f); + fX = ceilf(0.0f); + fX = copysignf(1.0f, -2.0f); + cosf(0.0f); + coshf(0.0f); + cospif(0.0f); + cyl_bessel_i0f(0.0f); + cyl_bessel_i1f(0.0f); + erfcf(0.0f); + erfcinvf(2.0f); + erfcxf(0.0f); + erff(0.0f); + erfinvf(1.0f); + exp10f(0.0f); + exp2f(0.0f); + expf(0.0f); + expm1f(0.0f); + fX = fabsf(1.0f); + fdimf(1.0f, 0.0f); + fdividef(0.0f, 1.0f); + fX = floorf(0.0f); + fmaf(1.0f, 2.0f, 3.0f); + fX = fmaxf(0.0f, 0.0f); + fX = fminf(0.0f, 0.0f); + fmodf(0.0f, 1.0f); + frexpf(0.0f, &iX); + hypotf(1.0f, 0.0f); + ilogbf(1.0f); + isfinite(0.0f); + fX = isinf(0.0f); + fX = isnan(0.0f); + j0f(0.0f); + j1f(0.0f); + jnf(-1.0f, 1.0f); + ldexpf(0.0f, 0); + lgammaf(1.0f); + llrintf(0.0f); + llroundf(0.0f); + log10f(1.0f); + log1pf(-1.0f); + log2f(1.0f); + logbf(1.0f); + logf(1.0f); + lrintf(0.0f); + lroundf(0.0f); + modff(0.0f, &fX); + fX = nanf("1"); + fX = nearbyintf(0.0f); + nextafterf(0.0f, 0.0f); + norm3df(1.0f, 0.0f, 0.0f); + norm4df(1.0f, 0.0f, 0.0f, 0.0f); + normcdff(0.0f); + normcdfinvf(1.0f); + fX = 1.0f; + normf(1, &fX); + powf(1.0f, 0.0f); + rcbrtf(1.0f); + remainderf(2.0f, 1.0f); + remquof(1.0f, 2.0f, &iX); + rhypotf(0.0f, 1.0f); + fY = rintf(1.0f); + rnorm3df(0.0f, 0.0f, 1.0f); + rnorm4df(0.0f, 0.0f, 0.0f, 1.0f); + fX = 1.0f; + rnormf(1, &fX); + fY = roundf(0.0f); + rsqrtf(1.0f); + scalblnf(0.0f, 1); + scalbnf(0.0f, 1); + signbit(1.0f); + sincosf(0.0f, &fX, &fY); + sincospif(0.0f, &fX, &fY); + sinf(0.0f); + sinhf(0.0f); + sinpif(0.0f); + sqrtf(0.0f); + tanf(0.0f); + tanhf(0.0f); + tgammaf(2.0f); + fY = truncf(0.0f); + y0f(1.0f); + y1f(1.0f); + ynf(1, 1.0f); +} + +TEST_CASE("Unit_TestIncludeMathPreciseFloat") { + hipError_t err; + err = hipLaunchKernel(reinterpret_cast(FloatMathPreciseKernel), + dim3(1, 1, 1), + dim3(1, 1, 1), 0, 0, 0); + REQUIRE(err == hipSuccess); +} diff --git a/catch/unit/deviceLib/hipTestNativeHalf.cc b/catch/unit/deviceLib/hipTestNativeHalf.cc new file mode 100644 index 0000000000..521b09bca0 --- /dev/null +++ b/catch/unit/deviceLib/hipTestNativeHalf.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 + +__global__ +void __halfTest(bool* result, __half a) { + // Construction + result[0] &= std::is_default_constructible<__half>{}; + result[0] &= std::is_copy_constructible<__half>{}; + result[0] &= std::is_move_constructible<__half>{}; + result[0] &= std::is_constructible<__half, float>{}; + result[0] &= std::is_constructible<__half, double>{}; + result[0] &= std::is_constructible<__half, uint32_t>{}; + result[0] &= std::is_constructible<__half, int32_t>{}; + result[0] &= std::is_constructible<__half, uint32_t>{}; + result[0] &= std::is_constructible<__half, int>{}; + result[0] &= std::is_constructible<__half, uint64_t>{}; + result[0] &= std::is_constructible<__half, int64_t>{}; + result[0] &= std::is_constructible<__half, int64_t>{}; + result[0] &= std::is_constructible<__half, uint64_t>{}; + result[0] &= std::is_constructible<__half, __half_raw>{}; + + // Assignment + result[0] &= std::is_copy_assignable<__half>{}; + result[0] &= std::is_move_assignable<__half>{}; + result[0] &= std::is_assignable<__half, float>{}; + result[0] &= std::is_assignable<__half, double>{}; + result[0] &= std::is_assignable<__half, uint32_t>{}; + result[0] &= std::is_assignable<__half, int32_t>{}; + result[0] &= std::is_assignable<__half, uint32_t>{}; + result[0] &= std::is_assignable<__half, int>{}; + result[0] &= std::is_assignable<__half, uint64_t>{}; + result[0] &= std::is_assignable<__half, int64_t>{}; + result[0] &= std::is_assignable<__half, int64_t>{}; + result[0] &= std::is_assignable<__half, uint64_t>{}; + result[0] &= std::is_assignable<__half, __half_raw>{}; + result[0] &= std::is_assignable<__half, volatile __half_raw&>{}; + result[0] &= std::is_assignable<__half, volatile __half_raw&&>{}; + + // Conversion + result[0] &= std::is_convertible<__half, float>{}; + result[0] &= std::is_convertible<__half, uint32_t>{}; + result[0] &= std::is_convertible<__half, int32_t>{}; + result[0] &= std::is_convertible<__half, uint32_t>{}; + result[0] &= std::is_convertible<__half, int>{}; + result[0] &= std::is_convertible<__half, uint64_t>{}; + result[0] &= std::is_convertible<__half, int64_t>{}; + result[0] &= std::is_convertible<__half, int64_t>{}; + result[0] &= std::is_convertible<__half, bool>{}; + result[0] &= std::is_convertible<__half, uint64_t>{}; + result[0] &= std::is_convertible<__half, __half_raw>{}; + result[0] &= std::is_convertible<__half, volatile __half_raw>{}; + + // Nullary + result[0] &= __heq(a, +a) && result[0]; + result[0] &= __heq(__hneg(a), -a) && result[0]; + + // Unary arithmetic + result[0] &= __heq(a += 0, a) && result[0]; + result[0] &= __heq(a -= 0, a) && result[0]; + result[0] &= __heq(a *= 1, a) && result[0]; + result[0] &= __heq(a /= 1, a) && result[0]; + + // Binary arithmetic + result[0] &= __heq((a + a), __hadd(a, a)) && result[0]; + result[0] &= __heq((a - a), __hsub(a, a)) && result[0]; + result[0] &= __heq((a * a), __hmul(a, a)) && result[0]; + result[0] &= __heq((a / a), __hdiv(a, a)) && result[0]; + + // Relations + result[0] &= (a == a) && result[0]; + result[0] &= !(a != a) && result[0]; + result[0] &= (a <= a) && result[0]; + result[0] &= (a >= a) && result[0]; + result[0] &= !(a < a) && result[0]; + result[0] &= !(a > a) && result[0]; +} + +__device__ +static bool to_bool(const __half2& x) { + auto r = static_cast(x); + return r.data.x != 0 && r.data.y != 0; +} + +__global__ +void __half2Test(bool* result, __half2 a) { + // Construction + result[0] &= std::is_default_constructible<__half2>{}; + result[0] &= std::is_copy_constructible<__half2>{}; + result[0] &= std::is_move_constructible<__half2>{}; + result[0] &= std::is_constructible<__half2, __half, __half>{}; + result[0] &= std::is_constructible<__half2, __half2_raw>{}; + + // Assignment + result[0] &= std::is_copy_assignable<__half2>{}; + result[0] &= std::is_move_assignable<__half2>{}; + result[0] &= std::is_assignable<__half2, __half2_raw>{}; + + // Conversion + result[0] &= std::is_convertible<__half2, __half2_raw>{}; + + // Nullary + result[0] &= to_bool(__heq2(a, +a)) && result[0]; + result[0] &= to_bool(__heq2(__hneg2(a), -a)) && result[0]; + + // Unary arithmetic + result[0] &= to_bool(__heq2(a += 0, a)) && result[0]; + result[0] &= to_bool(__heq2(a -= 0, a)) && result[0]; + result[0] &= to_bool(__heq2(a *= 1, a)) && result[0]; + result[0] &= to_bool(__heq2(a /= 1, a)) && result[0]; + + // Binary arithmetic + result[0] &= to_bool(__heq2((a + a), __hadd2(a, a))) && result[0]; + result[0] &= to_bool(__heq2((a - a), __hsub2(a, a))) && result[0]; + result[0] &= to_bool(__heq2((a * a), __hmul2(a, a))) && result[0]; + result[0] &= to_bool(__heq2((a / a), __h2div(a, a))) && result[0]; + + // Relations + result[0] &= (a == a) && result[0]; + result[0] &= !(a != a) && result[0]; + result[0] &= (a <= a) && result[0]; + result[0] &= (a >= a) && result[0]; + result[0] &= !(a < a) && result[0]; + result[0] &= !(a > a) && result[0]; + + // Dot Functions + result[0] &= amd_mixed_dot(a, a, 1, 1) && result[0]; + + half X = a.x; + half Y = a.y; +} + +TEST_CASE("Unit_hipTestNativeHalf") { + bool* result{nullptr}; + HIP_CHECK(hipHostMalloc(&result, 1)); + SECTION("Half Test") { + result[0] = true; + hipLaunchKernelGGL( + __halfTest, dim3(1, 1, 1), dim3(1, 1, 1), 0, 0, result, __half{1}); + HIP_CHECK(hipDeviceSynchronize()); + REQUIRE(result[0] == true); + } + SECTION("Half2 Test") { + result[0] = true; + hipLaunchKernelGGL( + __half2Test, dim3(1, 1, 1), dim3(1, 1, 1), 0, 0, result, __half2{1, 1}); + HIP_CHECK(hipDeviceSynchronize()); + REQUIRE(result[0] == true); + } + HIP_CHECK(hipHostFree(result)); +} diff --git a/catch/unit/deviceLib/hipTestNew.cc b/catch/unit/deviceLib/hipTestNew.cc new file mode 100644 index 0000000000..35f0efb195 --- /dev/null +++ b/catch/unit/deviceLib/hipTestNew.cc @@ -0,0 +1,54 @@ +/* +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 + +#define LEN 512 +#define SIZE 2048 + +class A { + public: + __device__ A() { + a = threadIdx.x + blockIdx.x * blockDim.x; + } + private: + int a; +}; + +static __global__ void kernel(int* Ad) { + int tid = threadIdx.x + blockIdx.x * blockDim.x; + new(Ad+tid) A(); +} + +TEST_CASE("Unit_hipTest_DeviceNewOperator") { + 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)); + + // Validation + for (unsigned i = 0; i < LEN; i++) { + REQUIRE(i == A[i]); + } + delete[] A; +} diff --git a/catch/unit/deviceLib/hipThreadFence.cc b/catch/unit/deviceLib/hipThreadFence.cc new file mode 100644 index 0000000000..4272b6aa2d --- /dev/null +++ b/catch/unit/deviceLib/hipThreadFence.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 + +#define NUM 1024 +#define SIZE (NUM * sizeof(float)) + +__global__ static void vAdd(float* In1, float* In2, float* In3, + float* In4, float* Out) { + int tid = threadIdx.x + blockIdx.x * blockDim.x; + In4[tid] = In1[tid] + In2[tid]; + __threadfence(); + In3[tid] = In3[tid] + In4[tid]; + __threadfence_block(); + Out[tid] = In4[tid] + In3[tid]; +} + +TEST_CASE("Unit_hipThreadFence") { + float* In1 = new float[NUM]; + float* In2 = new float[NUM]; + float* In3 = new float[NUM]; + float* In4 = new float[NUM]; + float* Out = new float[NUM]; + // Initialization + for (uint32_t i = 0; i < NUM; i++) { + In1[i] = 1.0f; + In2[i] = 1.0f; + In3[i] = 1.0f; + In4[i] = 1.0f; + } + + float *In1d, *In2d, *In3d, *In4d, *Outd; + HIP_CHECK(hipMalloc(reinterpret_cast(&In1d), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&In2d), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&In3d), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&In4d), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&Outd), SIZE)); + + HIP_CHECK(hipMemcpy(In1d, In1, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(In2d, In2, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(In3d, In3, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(In4d, In4, SIZE, hipMemcpyHostToDevice)); + + hipLaunchKernelGGL(vAdd, dim3(32, 1, 1), dim3(32, 1, 1), 0, 0, + In1d, In2d, In3d, In4d, Outd); + HIP_CHECK(hipMemcpy(Out, Outd, SIZE, hipMemcpyDeviceToHost)); + for (uint32_t i = 0; i < NUM; i++) { + REQUIRE(Out[i] == 2 * In1[i] + 2 * In2[i] + In3[i]); + } + delete[] In1; + delete[] In2; + delete[] In3; + delete[] In4; + delete[] Out; + HIP_CHECK(hipFree(In1d)); + HIP_CHECK(hipFree(In2d)); + HIP_CHECK(hipFree(In3d)); + HIP_CHECK(hipFree(In4d)); + HIP_CHECK(hipFree(Outd)); +} diff --git a/catch/unit/deviceLib/hipVectorTypes.cc b/catch/unit/deviceLib/hipVectorTypes.cc new file mode 100644 index 0000000000..09d19b0397 --- /dev/null +++ b/catch/unit/deviceLib/hipVectorTypes.cc @@ -0,0 +1,204 @@ +/* +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 + +using namespace std; // NOLINT + +template().x)>{}>* = nullptr> +bool integer_unary_tests(V&, V&) { + return true; +} + +template().x)>{}>* = nullptr> +bool integer_binary_tests(V&, V&, V&...) { + return true; +} + +template().x)>{}>* = nullptr> +bool integer_unary_tests(V f1, V f2) { + f1 %= f2; + if (f1 != V{0}) return false; + f1 &= f2; + if (f1 != V{0}) return false; + f1 |= f2; + if (f1 != V{1}) return false; + f1 ^= f2; + if (f1 != V{0}) return false; + f1 = V{1}; + f1 <<= f2; + if (f1 != V{2}) return false; + f1 >>= f2; + if (f1 != V{1}) return false; + f2 = ~f1; + return f2 == V{~1}; +} + +template().x)>{}>* = nullptr> +bool integer_binary_tests(V f1, V f2, V f3) { + f3 = f1 % f2; + if (f3 != V{0}) return false; + f1 = f3 & f2; + if (f1 != V{0}) return false; + f2 = f1 ^ f3; + if (f2 != V{0}) return false; + f1 = V{1}; + f2 = V{2}; + f3 = f1 << f2; + if (f3 != V{4}) return false; + f2 = f3 >> f1; + return f2 == V{2}; +} + +template +bool constructor_tests() { + if (is_constructible{} && + is_constructible{} && + is_constructible{} && + is_constructible{} && + is_constructible{} && + is_constructible{} && + is_constructible{} && + is_constructible{} && + is_constructible{} && + is_constructible{} && + is_constructible{} && + is_constructible{}) { + return true; + } +} + +template +bool TestVectorType() { + constexpr V v1{1}; + constexpr V v2{2}; + constexpr V v3{3}; + constexpr V v4{4}; + + V f1{1}; + V f2{1}; + V f3 = f1 + f2; + if (f3 != v2) return false; + f2 = f3 - f1; + if (f2 != v1) return false; + f1 = f2 * f3; + if (f1 != v2) return false; + f2 = f1 / f3; + if (f2 != v1) return false; + if (!integer_binary_tests(f1, f2, f3)) return false; + + f1 = V{2}; + f2 = V{1}; + f1 += f2; + if (f1 != v3) return false; + f1 -= f2; + if (f1 != v2) return false; + f1 *= f2; + if (f1 != v2) return false; + f1 /= f2; + if (f1 != v2) return false; + if (!integer_unary_tests(f1, f2)) return false; + + f1 = v2; + f2 = f1++; + if (f1 != v3) return false; + if (f2 != v2) return false; + f2 = f1--; + if (f2 != v3) return false; + if (f1 != v2) return false; + f2 = ++f1; + if (f1 != v3) return false; + if (f2 != v3) return false; + f2 = --f1; + if (f1 != v2) return false; + if (f2 != v2) return false; + + if (!constructor_tests()) return false; + + f1 = v3; + f2 = v4; + f3 = v3; + if (f1 == f2) return false; + if (!(f1 != f2)) return false; + + using T = typename V::value_type; + + const T& x = f1.x; + T& y = f2.x; + const volatile T& z = f3.x; + volatile T& w = f2.x; + + if (x != T{3}) return false; + if (y != T{4}) return false; + if (z != T{3}) return false; + if (w != T{4}) return false; + + stringstream str; + str << f1.x; + str >> f2.x; + + if (f1.x != f2.x) return false; + + return true; +} + +template* = nullptr> +bool TestVectorTypes() { + return true; +} + +template +bool TestVectorTypes() { + if (!TestVectorType()) return false; + return TestVectorTypes(); +} + +bool CheckVectorTypes() { + return TestVectorTypes< + char1, char2, char3, char4, + uchar1, uchar2, uchar3, uchar4, + short1, short2, short3, short4, + ushort1, ushort2, ushort3, ushort4, + int1, int2, int3, int4, + uint1, uint2, uint3, uint4, + long1, long2, long3, long4, + ulong1, ulong2, ulong3, ulong4, + longlong1, longlong2, longlong3, longlong4, + ulonglong1, ulonglong2, ulonglong3, ulonglong4, + float1, float2, float3, float4, + double1, double2, double3, double4>(); +} +TEST_CASE("Unit_TestVectorTypes") { + REQUIRE(sizeof(float1) == 4); + REQUIRE(sizeof(float2) >= 8); + REQUIRE(sizeof(float3) == 12); + REQUIRE(sizeof(float4) >= 16); + + bool result = false; + result = CheckVectorTypes(); + REQUIRE(result == true); +} diff --git a/catch/unit/deviceLib/hip_test_make_type.cc b/catch/unit/deviceLib/hip_test_make_type.cc new file mode 100644 index 0000000000..32e889daee --- /dev/null +++ b/catch/unit/deviceLib/hip_test_make_type.cc @@ -0,0 +1,334 @@ +/* +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 WIDTH 8 +#define HEIGHT 8 + +#define NUM (WIDTH * HEIGHT) + +#define THREADS_PER_BLOCK_X 8 +#define THREADS_PER_BLOCK_Y 8 +#define THREADS_PER_BLOCK_Z 1 + + +__global__ void vectoradd_char1(char1* a, const char1* bm, const char1* cm, + int width, int height) { + int x = blockDim.x * blockIdx.x + threadIdx.x; + int y = blockDim.y * blockIdx.y + threadIdx.y; + + int i = y * width + x; + if (i < (width * height)) { + a[i] = make_char1(bm[i].x) + make_char1(cm[i].x); + } +} + +__global__ void vectoradd_char2(char2* a, const char2* bm, const char2* cm, + int width, int height) { + int x = blockDim.x * blockIdx.x + threadIdx.x; + int y = blockDim.y * blockIdx.y + threadIdx.y; + + int i = y * width + x; + if (i < (width * height)) { + a[i] = make_char2(bm[i].x, bm[i].y) + make_char2(cm[i].x, cm[i].y); + } +} + +__global__ void vectoradd_char3(char3* a, const char3* bm, const char3* cm, + int width, int height) { + int x = blockDim.x * blockIdx.x + threadIdx.x; + int y = blockDim.y * blockIdx.y + threadIdx.y; + + int i = y * width + x; + if (i < (width * height)) { + a[i] = make_char3(bm[i].x, bm[i].y, bm[i].z) + make_char3(cm[i].x, + cm[i].y, cm[i].z); + } +} +__global__ void vectoradd_char4(char4* a, const char4* bm, const char4* cm, + int width, int height) { + int x = blockDim.x * blockIdx.x + threadIdx.x; + int y = blockDim.y * blockIdx.y + threadIdx.y; + + int i = y * width + x; + if (i < (width * height)) { + a[i] = make_char4(bm[i].x, bm[i].y, bm[i].z, bm[i].w) + + make_char4(cm[i].x, cm[i].y, cm[i].z, cm[i].w); + } +} + +template +bool dataTypesRunChar1() { + T* hostA; + T* hostB; + T* hostC; + + T* deviceA; + T* deviceB; + T* deviceC; + + int i; + int errors; + + hostA = reinterpret_cast(malloc(NUM * sizeof(T))); + hostB = reinterpret_cast(malloc(NUM * sizeof(T))); + hostC = reinterpret_cast(malloc(NUM * sizeof(T))); + + // initialize the input data + for (i = 0; i < NUM; i++) { + hostB[i] = (T)i; + hostC[i] = (T)i; + } + + HIP_CHECK(hipMalloc(reinterpret_cast(&deviceA), NUM * sizeof(T))); + HIP_CHECK(hipMalloc(reinterpret_cast(&deviceB), NUM * sizeof(T))); + HIP_CHECK(hipMalloc(reinterpret_cast(&deviceC), NUM * sizeof(T))); + + HIP_CHECK(hipMemcpy(deviceB, hostB, NUM * sizeof(T), hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(deviceC, hostC, NUM * sizeof(T), hipMemcpyHostToDevice)); + + hipLaunchKernelGGL(HIP_KERNEL_NAME(vectoradd_char1), + dim3(WIDTH / THREADS_PER_BLOCK_X, HEIGHT / + THREADS_PER_BLOCK_Y), dim3(THREADS_PER_BLOCK_X, + THREADS_PER_BLOCK_Y), 0, 0, deviceA, deviceB, deviceC, + WIDTH, HEIGHT); + + HIP_CHECK(hipMemcpy(hostA, deviceA, NUM * sizeof(T), hipMemcpyDeviceToHost)); + + bool ret = false; + // verify the results + errors = 0; + for (i = 0; i < NUM; i++) { + if (hostA[i] != (hostB[i] + hostC[i])) { + errors++; + } + } + if (errors != 0) { + ret = false; + } else { + ret = true; + } + + HIP_CHECK(hipFree(deviceA)); + HIP_CHECK(hipFree(deviceB)); + HIP_CHECK(hipFree(deviceC)); + + free(hostA); + free(hostB); + free(hostC); + + return ret; +} + +template +bool dataTypesRunChar2() { + T* hostA; + T* hostB; + T* hostC; + + T* deviceA; + T* deviceB; + T* deviceC; + + int i; + int errors; + + hostA = reinterpret_cast(malloc(NUM * sizeof(T))); + hostB = reinterpret_cast(malloc(NUM * sizeof(T))); + hostC = reinterpret_cast(malloc(NUM * sizeof(T))); + + // initialize the input data + for (i = 0; i < NUM; i++) { + hostB[i] = (T)i; + hostC[i] = (T)i; + } + + HIP_CHECK(hipMalloc(reinterpret_cast(&deviceA), NUM * sizeof(T))); + HIP_CHECK(hipMalloc(reinterpret_cast(&deviceB), NUM * sizeof(T))); + HIP_CHECK(hipMalloc(reinterpret_cast(&deviceC), NUM * sizeof(T))); + + HIP_CHECK(hipMemcpy(deviceB, hostB, NUM * sizeof(T), hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(deviceC, hostC, NUM * sizeof(T), hipMemcpyHostToDevice)); + + hipLaunchKernelGGL(HIP_KERNEL_NAME(vectoradd_char2), + dim3(WIDTH / THREADS_PER_BLOCK_X, HEIGHT / + THREADS_PER_BLOCK_Y), dim3(THREADS_PER_BLOCK_X, + THREADS_PER_BLOCK_Y), 0, 0, deviceA, deviceB, deviceC, + WIDTH, HEIGHT); + + HIP_CHECK(hipMemcpy(hostA, deviceA, NUM * sizeof(T), hipMemcpyDeviceToHost)); + + bool ret = false; + // verify the results + errors = 0; + for (i = 0; i < NUM; i++) { + if (hostA[i] != (hostB[i] + hostC[i])) { + errors++; + } + } + if (errors != 0) { + ret = false; + } else { + ret = true; + } + + HIP_CHECK(hipFree(deviceA)); + HIP_CHECK(hipFree(deviceB)); + HIP_CHECK(hipFree(deviceC)); + + free(hostA); + free(hostB); + free(hostC); + + return ret; +} + +template +bool dataTypesRunChar3() { + T* hostA; + T* hostB; + T* hostC; + + T* deviceA; + T* deviceB; + T* deviceC; + + int i; + int errors; + + hostA = reinterpret_cast(malloc(NUM * sizeof(T))); + hostB = reinterpret_cast(malloc(NUM * sizeof(T))); + hostC = reinterpret_cast(malloc(NUM * sizeof(T))); + + // initialize the input data + for (i = 0; i < NUM; i++) { + hostB[i] = (T)i; + hostC[i] = (T)i; + } + + HIP_CHECK(hipMalloc(reinterpret_cast(&deviceA), NUM * sizeof(T))); + HIP_CHECK(hipMalloc(reinterpret_cast(&deviceB), NUM * sizeof(T))); + HIP_CHECK(hipMalloc(reinterpret_cast(&deviceC), NUM * sizeof(T))); + + HIP_CHECK(hipMemcpy(deviceB, hostB, NUM * sizeof(T), hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(deviceC, hostC, NUM * sizeof(T), hipMemcpyHostToDevice)); + + hipLaunchKernelGGL(HIP_KERNEL_NAME(vectoradd_char3), + dim3(WIDTH / THREADS_PER_BLOCK_X, HEIGHT / + THREADS_PER_BLOCK_Y), dim3(THREADS_PER_BLOCK_X, + THREADS_PER_BLOCK_Y), 0, 0, deviceA, deviceB, deviceC, + WIDTH, HEIGHT); + + HIP_CHECK(hipMemcpy(hostA, deviceA, NUM * sizeof(T), hipMemcpyDeviceToHost)); + + bool ret = false; + // verify the results + errors = 0; + for (i = 0; i < NUM; i++) { + if (hostA[i] != (hostB[i] + hostC[i])) { + errors++; + } + } + if (errors != 0) { + ret = false; + } else { + ret = true; + } + HIP_CHECK(hipFree(deviceA)); + HIP_CHECK(hipFree(deviceB)); + HIP_CHECK(hipFree(deviceC)); + + free(hostA); + free(hostB); + free(hostC); + + return ret; +} + +template +bool dataTypesRunChar4() { + char4* hostA; + char4* hostB; + char4* hostC; + + char4* deviceA; + char4* deviceB; + char4* deviceC; + + int i; + int errors; + + hostA = reinterpret_cast(malloc(NUM * sizeof(T))); + hostB = reinterpret_cast(malloc(NUM * sizeof(T))); + hostC = reinterpret_cast(malloc(NUM * sizeof(T))); + + // initialize the input data + for (i = 0; i < NUM; i++) { + hostB[i] = (T)i; + hostC[i] = (T)i; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&deviceA), NUM * sizeof(T))); + HIP_CHECK(hipMalloc(reinterpret_cast(&deviceB), NUM * sizeof(T))); + HIP_CHECK(hipMalloc(reinterpret_cast(&deviceC), NUM * sizeof(T))); + + HIP_CHECK(hipMemcpy(deviceB, hostB, NUM * sizeof(T), hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(deviceC, hostC, NUM * sizeof(T), hipMemcpyHostToDevice)); + + hipLaunchKernelGGL(HIP_KERNEL_NAME(vectoradd_char4), + dim3(WIDTH / THREADS_PER_BLOCK_X, HEIGHT / + THREADS_PER_BLOCK_Y), dim3(THREADS_PER_BLOCK_X, + THREADS_PER_BLOCK_Y), 0, 0, deviceA, + deviceB, deviceC, WIDTH, HEIGHT); + + HIP_CHECK(hipMemcpy(hostA, deviceA, NUM * sizeof(T), hipMemcpyDeviceToHost)); + + bool ret = false; + // verify the results + errors = 0; + for (i = 0; i < NUM; i++) { + if (hostA[i] != (hostB[i] + hostC[i])) { + errors++; + } + } + if (errors != 0) { + ret = false; + } else { + ret = true; + } + HIP_CHECK(hipFree(deviceA)); + HIP_CHECK(hipFree(deviceB)); + HIP_CHECK(hipFree(deviceC)); + + free(hostA); + free(hostB); + free(hostC); + + return ret; +} + +TEST_CASE("Unit_Test_makechar_functionality") { + bool errors; + + errors = dataTypesRunChar1() && dataTypesRunChar2() && + dataTypesRunChar3() && dataTypesRunChar4(); + + REQUIRE(errors == true); +} diff --git a/catch/unit/deviceLib/hip_trig.cc b/catch/unit/deviceLib/hip_trig.cc new file mode 100644 index 0000000000..a264d69783 --- /dev/null +++ b/catch/unit/deviceLib/hip_trig.cc @@ -0,0 +1,86 @@ +/* +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 (LEN << 2) +__global__ static void kernel_trig(float* In, float* sin_d, + float* cos_d, float* tan_d, + float* sin_pd, float* cos_pd) { + int tid = threadIdx.x + blockIdx.x * blockDim.x; + sin_d[tid] = sinf(In[tid]); + cos_d[tid] = cosf(In[tid]); + tan_d[tid] = tanf(In[tid]); + sincosf(In[tid], &sin_pd[tid], &cos_pd[tid]); +} +TEST_CASE("Unit_kernel_trigger") { + float *In, *sin_h, *cos_h, *tan_h, *sin_ph, *cos_ph; + float *In_d, *sin_d, *cos_d, *tan_d, *sin_pd, *cos_pd; + int errors = 0; + In = new float[LEN]; + sin_h = new float[LEN]; + cos_h = new float[LEN]; + tan_h = new float[LEN]; + sin_ph = new float[LEN]; + cos_ph = new float[LEN]; + for (int i = 0; i < LEN; i++) { + In[i] = 1.0f; + sin_h[i] = 0.0f; + cos_h[i] = 0.0f; + tan_h[i] = 0.0f; + sin_ph[i] = 0.0f; + cos_ph[i] = 0.0f; + } + HIP_CHECK(hipMalloc(reinterpret_cast(&In_d), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&sin_d), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&cos_d), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&tan_d), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&sin_pd), SIZE)); + HIP_CHECK(hipMalloc(reinterpret_cast(&cos_pd), SIZE)); + + HIP_CHECK(hipMemcpy(In_d, In, SIZE, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(kernel_trig, dim3(LEN, 1, 1), dim3(1, 1, 1), 0, 0, + In_d, sin_d, cos_d, tan_d, + sin_pd, cos_pd); + HIP_CHECK(hipMemcpy(sin_h, sin_d, SIZE, hipMemcpyDeviceToHost)); + HIP_CHECK(hipMemcpy(cos_h, cos_d, SIZE, hipMemcpyDeviceToHost)); + HIP_CHECK(hipMemcpy(tan_h, tan_d, SIZE, hipMemcpyDeviceToHost)); + HIP_CHECK(hipMemcpy(sin_ph, sin_pd, SIZE, hipMemcpyDeviceToHost)); + HIP_CHECK(hipMemcpy(cos_ph, cos_pd, SIZE, hipMemcpyDeviceToHost)); + // Validation + for (int i = 0; i < LEN; i++) { + if (sin_h[i] != sin_ph[i] || cos_h[i] != cos_ph[i] || tan_h[i] * + cos_h[i] != sin_h[i]) { + errors++; + } + } + REQUIRE(errors == 0); + delete[] In; + delete[] sin_h; + delete[] cos_h; + delete[] tan_h; + delete[] sin_ph; + delete[] cos_ph; + HIP_CHECK(hipFree(In_d)); + HIP_CHECK(hipFree(sin_d)); + HIP_CHECK(hipFree(cos_d)); + HIP_CHECK(hipFree(tan_d)); + HIP_CHECK(hipFree(sin_pd)); + HIP_CHECK(hipFree(cos_pd)); +} From 23b02df2a188f02fd104f4d585de5b1de0d350c8 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Mon, 14 Aug 2023 20:53:37 +0530 Subject: [PATCH 09/30] SWDEV-385489 - [catch2][dtest] Adding scenarios for hipEventCreateWithFlags() with hipEventDisableSystemFence and default flags (#282) Change-Id: Ied3dce437f34d793eb3715999125924ff74ff9b8 --- .../config/config_amd_windows_MI2xx.json | 7 + .../config/config_amd_windows_common.json | 6 + catch/include/hip_test_defgroups.hh | 7 + catch/unit/event/hipEventCreateWithFlags.cc | 314 +++++++++++++++++- 4 files changed, 323 insertions(+), 11 deletions(-) diff --git a/catch/hipTestMain/config/config_amd_windows_MI2xx.json b/catch/hipTestMain/config/config_amd_windows_MI2xx.json index 92ce9593a5..27ab1dd12b 100644 --- a/catch/hipTestMain/config/config_amd_windows_MI2xx.json +++ b/catch/hipTestMain/config/config_amd_windows_MI2xx.json @@ -98,6 +98,13 @@ "Unit_hipStreamValue_Wait64_Blocking_NoMask_Nor", "Unit_hipLaunchHostFunc_Graph", "Unit_hipLaunchHostFunc_KernelHost", + "Unit_hipEventCreateWithFlags_DisableSystemFence_HstVisMem", + "Unit_hipEventCreateWithFlags_DefaultFlg_HstVisMem", + "Unit_hipEventCreateWithFlags_DisableSystemFence_NonCohHstMem", + "Unit_hipEventCreateWithFlags_DefaultFlg_NonCohHstMem", + "Unit_hipEventCreateWithFlags_DisableSystemFence_CohHstMem", + "Unit_hipEventCreateWithFlags_DefaultFlg_CohHstMem", + "Unit_hipStreamCreateWithPriority_MulthreadNonblockingflag", "Unit_hipDeviceGetUuid_Positive", "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", "Unit_hiprtc_saxpy.Unit_hiprtc_saxpy", diff --git a/catch/hipTestMain/config/config_amd_windows_common.json b/catch/hipTestMain/config/config_amd_windows_common.json index 405556ecc1..4f76812ef6 100644 --- a/catch/hipTestMain/config/config_amd_windows_common.json +++ b/catch/hipTestMain/config/config_amd_windows_common.json @@ -104,6 +104,12 @@ "Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout", "Unit_hipFuncSetAttribute_Positive_Parameters", "Unit_hipFuncSetAttribute_Negative_Parameters", + "Unit_hipEventCreateWithFlags_DisableSystemFence_HstVisMem", + "Unit_hipEventCreateWithFlags_DefaultFlg_HstVisMem", + "Unit_hipEventCreateWithFlags_DisableSystemFence_NonCohHstMem", + "Unit_hipEventCreateWithFlags_DefaultFlg_NonCohHstMem", + "Unit_hipEventCreateWithFlags_DisableSystemFence_CohHstMem", + "Unit_hipEventCreateWithFlags_DefaultFlg_CohHstMem", "NOTE: The following 4 tests are disabled due to defect - EXSWHTEC-240", "Unit_hipFuncSetCacheConfig_Negative_Not_Supported", "Unit_hipFuncSetSharedMemConfig_Negative_Not_Supported", diff --git a/catch/include/hip_test_defgroups.hh b/catch/include/hip_test_defgroups.hh index 119b095dcc..7d6fd3f731 100644 --- a/catch/include/hip_test_defgroups.hh +++ b/catch/include/hip_test_defgroups.hh @@ -107,6 +107,13 @@ THE SOFTWARE. * @} */ +/** + * @defgroup EventTest Event Management + * @{ + * This section describes the event management types & functions of HIP runtime API. + * @} + */ + /** * @defgroup ContextTest Context Management * @{ diff --git a/catch/unit/event/hipEventCreateWithFlags.cc b/catch/unit/event/hipEventCreateWithFlags.cc index c758e12a55..875d7f4295 100644 --- a/catch/unit/event/hipEventCreateWithFlags.cc +++ b/catch/unit/event/hipEventCreateWithFlags.cc @@ -1,5 +1,5 @@ /* -Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -21,38 +21,330 @@ THE SOFTWARE. */ #include +#include +#include +#include + +constexpr size_t buffer_size = (1024*1024); +constexpr int test_iteration_hstvismem = 5; +constexpr int test_iteration_noncohmem = 10; +constexpr int block_size = 512; /** * @addtogroup hipEventCreateWithFlags hipEventCreateWithFlags * @{ * @ingroup EventTest - * `hipEventCreateWithFlags(hipEvent_t* event, unsigned flags)` - - * Create an event with the specified flags to control event behaviour. + * `hipEventCreateWithFlags (hipEvent_t *event, unsigned flags)` - + * begins graph capture on a stream */ /** * Test Description * ------------------------ - * - Successfully create an event with all defined device flags. + * - Test simple event creation with hipEventCreateWithFlags api for each flag * Test source * ------------------------ - * - unit/event/hipEventCreateWithFlags.cc + * - catch\unit\event\hipEventCreateWithFlags.cc * Test requirements * ------------------------ - * - HIP_VERSION >= 5.2 + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipEventCreateWithFlags_Positive") { - #if HT_AMD - const unsigned int flagUnderTest = GENERATE(hipEventDefault, hipEventBlockingSync, hipEventDisableTiming, hipEventInterprocess | hipEventDisableTiming, hipEventReleaseToDevice, hipEventReleaseToSystem); + const unsigned int flagUnderTest = GENERATE(hipEventDefault, + hipEventBlockingSync, hipEventDisableTiming, + hipEventInterprocess | hipEventDisableTiming, + hipEventReleaseToDevice, hipEventReleaseToSystem); #else - // On Non-AMD platforms hipEventReleaseToDevice / hipEventReleaseToSystem are not defined - const unsigned int flagUnderTest = GENERATE(hipEventDefault, hipEventBlockingSync, hipEventDisableTiming, hipEventInterprocess | hipEventDisableTiming); + // On Non-AMD platforms hipEventReleaseToDevice / hipEventReleaseToSystem + // are not defined. + const unsigned int flagUnderTest = GENERATE(hipEventDefault, + hipEventBlockingSync, + hipEventDisableTiming, + hipEventInterprocess | hipEventDisableTiming); #endif hipEvent_t event; HIP_CHECK(hipEventCreateWithFlags(&event, flagUnderTest)); REQUIRE(event != nullptr); - HIP_CHECK(hipEventDestroy(event)); } + +/** +Since flags hipEventReleaseToSystem, hipEventDisableSystemFence and hipEventReleaseToDevice +are AMD specific flags, hence the following tests enabled only for AMD. +*/ +#if HT_AMD +enum class eSyncToTest { + eStreamSynchronize, + eDeviceSynchronize, + eStreamWaitEvent, + eEventSynchronize +}; + +enum class eMemoryToTest { + eHostVisibleMemory, + eNonCoherentHostMemory, + eCoherentHostMemory +}; + +static void init_input(int* a, size_t size) { + unsigned int seed = time(nullptr); + for (size_t i = 0; i < size; i++) { + a[i] = (HipTest::RAND_R(&seed) & 0xFF); + } +} + +static void check_output(int* inp, int* out, size_t size) { + for (size_t i = 0; i < size; i++) { + REQUIRE(out[i] == (inp[i]*inp[i])); + } +} +// local function +static void testMemCoherency(eSyncToTest test, eMemoryToTest mem, + uint32_t flags) { + hipDeviceProp_t prop; + HIP_CHECK(hipGetDeviceProperties(&prop, 0)); + // If the GPU is not large bar then exit the test + if (prop.isLargeBar != 1) { + HipTest::HIP_SKIP_TEST("Skipping test as large bar is not supported"); + return; + } + constexpr auto blocksPerCU = 6; + unsigned grid_size = HipTest::setNumBlocks(blocksPerCU, + block_size, buffer_size); + hipEvent_t event; + HIP_CHECK(hipEventCreateWithFlags(&event, flags)); + hipStream_t stream; + HIP_CHECK(hipStreamCreateWithFlags(&stream, 0x0)); + int *ibuf_h, *buf_d; + ibuf_h = new int[buffer_size]; + REQUIRE(ibuf_h != nullptr); + int total_iter = 0; + if (mem == eMemoryToTest::eHostVisibleMemory) { + HIP_CHECK(hipMalloc(&buf_d, buffer_size*sizeof(int))); + total_iter = test_iteration_hstvismem; + } else if (mem == eMemoryToTest::eNonCoherentHostMemory) { + HIP_CHECK(hipHostMalloc(&buf_d, buffer_size*sizeof(int), + hipHostMallocNonCoherent)); + total_iter = test_iteration_noncohmem; + } else if (mem == eMemoryToTest::eCoherentHostMemory) { + HIP_CHECK(hipHostMalloc(&buf_d, buffer_size*sizeof(int), + hipHostMallocCoherent)); + total_iter = test_iteration_noncohmem; + } + for (int iter = 0; iter < total_iter; iter++) { + // Inititalize the buffer with random data + init_input(ibuf_h, buffer_size); + HIP_CHECK(hipMemcpy(buf_d, ibuf_h, sizeof(int)*buffer_size, + hipMemcpyDefault)); + HipTest::vector_square<<>>( + buf_d, buf_d, buffer_size); + HIP_CHECK(hipEventRecord(event, stream)); + // test different synchronization APIs + if (test == eSyncToTest::eStreamSynchronize) { + HIP_CHECK(hipStreamSynchronize(stream)); + } else if (test == eSyncToTest::eDeviceSynchronize) { + HIP_CHECK(hipDeviceSynchronize()); + } else if (test == eSyncToTest::eEventSynchronize) { + HIP_CHECK(hipEventSynchronize(event)); + } else if (test == eSyncToTest::eStreamWaitEvent) { + HIP_CHECK(hipStreamWaitEvent(stream, event, 0)); + } + check_output(ibuf_h, buf_d, buffer_size); + } + delete[] ibuf_h; + HIP_CHECK(hipStreamDestroy(stream)); + HIP_CHECK(hipEventDestroy(event)); + if (mem == eMemoryToTest::eHostVisibleMemory) { + HIP_CHECK(hipFree(buf_d)); + } else if ((mem == eMemoryToTest::eNonCoherentHostMemory) || + (mem == eMemoryToTest::eCoherentHostMemory)) { + HIP_CHECK(hipHostFree(buf_d)); + } +} + +/** + * Test Description + * ------------------------ + * - Check Synchronization effect on Host Visible Memory. + * Disable System fence when creating an event. Create a chunk of Host Visisble + * Memory using hipMalloc and initialize the memory with user data. Launch a + * kernel that writes to this memory location. Perform different synchronizations + * and validate that updated values are seen from host. + * Test source + * ------------------------ + * - catch\unit\event\hipEventCreateWithFlags.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipEventCreateWithFlags_DisableSystemFence_HstVisMem") { + SECTION("Check with hipStreamSynchronize") { + INFO("Check with hipStreamSynchronize"); + testMemCoherency(eSyncToTest::eStreamSynchronize, + eMemoryToTest::eHostVisibleMemory, hipEventDisableSystemFence); + } + SECTION("Check with hipDeviceSynchronize") { + INFO("Check with hipDeviceSynchronize"); + testMemCoherency(eSyncToTest::eDeviceSynchronize, + eMemoryToTest::eHostVisibleMemory, hipEventDisableSystemFence); + } +} + +/** + * Test Description + * ------------------------ + * - Check Synchronization effect on Host Visible Memory. + * Use Default Flag when creating an event. Create a chunk of Host Visisble + * Memory using hipMalloc and initialize the memory with user data. Launch + * a kernel that writes to this memory location. Perform different synchronizations + * and validate that updated values are seen from host. + * ------------------------ + * - catch\unit\event\hipEventCreateWithFlags.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipEventCreateWithFlags_DefaultFlg_HstVisMem") { + SECTION("Check with hipStreamSynchronize") { + INFO("Check with hipStreamSynchronize"); + testMemCoherency(eSyncToTest::eStreamSynchronize, + eMemoryToTest::eHostVisibleMemory, hipEventDefault); + } + SECTION("Check with hipDeviceSynchronize") { + INFO("Check with hipDeviceSynchronize"); + testMemCoherency(eSyncToTest::eDeviceSynchronize, + eMemoryToTest::eHostVisibleMemory, hipEventDefault); + } + SECTION("Check with hipEventSynchronize") { + INFO("Check with hipEventSynchronize"); + testMemCoherency(eSyncToTest::eEventSynchronize, + eMemoryToTest::eHostVisibleMemory, hipEventDefault); + } +} + +/** + * Test Description + * ------------------------ + * - Check Synchronization effect on Non Coherent Host Memory. + * Disable System fence when creating an event. Create a chunk of Host Visisble + * Memory using hipMalloc and initialize the memory with user data. Launch a + * kernel that writes to this memory location. Perform different synchronizations + * and validate that updated values are seen from host. + * ------------------------ + * - catch\unit\event\hipEventCreateWithFlags.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipEventCreateWithFlags_DisableSystemFence_NonCohHstMem") { + SECTION("Check with hipStreamSynchronize") { + INFO("Check with hipStreamSynchronize"); + testMemCoherency(eSyncToTest::eStreamSynchronize, + eMemoryToTest::eNonCoherentHostMemory, hipEventDisableSystemFence); + } + SECTION("Check with hipDeviceSynchronize") { + INFO("Check with hipDeviceSynchronize"); + testMemCoherency(eSyncToTest::eDeviceSynchronize, + eMemoryToTest::eNonCoherentHostMemory, hipEventDisableSystemFence); + } +} + + +/** + * Test Description + * ------------------------ + * - Check Synchronization effect on Non Coherent Host Memory. + * Use Default Flag when creating an event. Create a chunk of Host Visisble + * Memory using hipMalloc and initialize the memory with user data. Launch + * a kernel that writes to this memory location. Perform different + * synchronizations and validate that updated values are seen from host. + * ------------------------ + * - catch\unit\event\hipEventCreateWithFlags.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipEventCreateWithFlags_DefaultFlg_NonCohHstMem") { + SECTION("Check with hipStreamSynchronize") { + INFO("Check with hipStreamSynchronize"); + testMemCoherency(eSyncToTest::eStreamSynchronize, + eMemoryToTest::eNonCoherentHostMemory, hipEventDefault); + } + SECTION("Check with hipDeviceSynchronize") { + INFO("Check with hipDeviceSynchronize"); + testMemCoherency(eSyncToTest::eDeviceSynchronize, + eMemoryToTest::eNonCoherentHostMemory, hipEventDefault); + } + SECTION("Check with hipEventSynchronize") { + INFO("Check with hipEventSynchronize"); + testMemCoherency(eSyncToTest::eEventSynchronize, + eMemoryToTest::eNonCoherentHostMemory, hipEventDefault); + } +} + +/** + * Test Description + * ------------------------ + * - Check Synchronization effect on Coherent Host Memory. + * Disable System fence when creating an event. Create a chunk of Host Visisble + * Memory using hipMalloc and initialize the memory with user data. Launch a + * kernel that writes to this memory location. Perform different synchronizations + * and validate that updated values are seen from host. + * ------------------------ + * - catch\unit\event\hipEventCreateWithFlags.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipEventCreateWithFlags_DisableSystemFence_CohHstMem") { + SECTION("Check with hipStreamSynchronize") { + INFO("Check with hipStreamSynchronize"); + testMemCoherency(eSyncToTest::eStreamSynchronize, + eMemoryToTest::eCoherentHostMemory, hipEventDisableSystemFence); + } + SECTION("Check with hipDeviceSynchronize") { + INFO("Check with hipDeviceSynchronize"); + testMemCoherency(eSyncToTest::eDeviceSynchronize, + eMemoryToTest::eCoherentHostMemory, hipEventDisableSystemFence); + } + SECTION("Check with hipEventSynchronize") { + INFO("Check with hipEventSynchronize"); + testMemCoherency(eSyncToTest::eEventSynchronize, + eMemoryToTest::eCoherentHostMemory, hipEventDisableSystemFence); + } +} + +/** + * Test Description + * ------------------------ + * - Check Synchronization effect on Coherent Host Memory. + * Use Default Flag when creating an event. Create a chunk of Host Visisble + * Memory using hipMalloc and initialize the memory with user data. Launch a + * kernel that writes to this memory location. Perform different synchronizations + * and validate that updated values are seen from host. + * ------------------------ + * - catch\unit\event\hipEventCreateWithFlags.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipEventCreateWithFlags_DefaultFlg_CohHstMem") { + SECTION("Check with hipStreamSynchronize") { + INFO("Check with hipStreamSynchronize"); + testMemCoherency(eSyncToTest::eStreamSynchronize, + eMemoryToTest::eCoherentHostMemory, hipEventDefault); + } + SECTION("Check with hipDeviceSynchronize") { + INFO("Check with hipDeviceSynchronize"); + testMemCoherency(eSyncToTest::eDeviceSynchronize, + eMemoryToTest::eCoherentHostMemory, hipEventDefault); + } + SECTION("Check with hipEventSynchronize") { + INFO("Check with hipEventSynchronize"); + testMemCoherency(eSyncToTest::eEventSynchronize, + eMemoryToTest::eCoherentHostMemory, hipEventDefault); + } +} +#endif From f5b1bdb7e5b1e414cb9058c6663f25a985c6cc62 Mon Sep 17 00:00:00 2001 From: Sourabh U Betigeri Date: Mon, 14 Aug 2023 08:23:59 -0700 Subject: [PATCH 10/30] Disabling tests on windows to allow PR 849086 (#318) Change-Id: Id769c12448cac5f185083d89211a7f2683852ebb --- catch/hipTestMain/config/config_amd_windows_common.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/catch/hipTestMain/config/config_amd_windows_common.json b/catch/hipTestMain/config/config_amd_windows_common.json index 4f76812ef6..398630a2fa 100644 --- a/catch/hipTestMain/config/config_amd_windows_common.json +++ b/catch/hipTestMain/config/config_amd_windows_common.json @@ -194,6 +194,9 @@ "Unit_hipGraphInstantiateWithFlags_FlagAutoFreeOnLaunch_check", "SWDEV-398981 fails in stress test", "Unit_hipStreamCreateWithPriority_MulthreadDefaultflag", + "Disabling below tests temporarily due to change in API behavior", + "Unit_hipMemPrefetchAsync_NonPageSz", + "Unit_hipStreamCreateWithFlags_DefaultStreamInteraction", "SWDEV-402054 fails in external github build", "Unit_hipEventDestroy_WithWaitingStream", "Note: UUID returned empty on some windows nodes", From 5d8dda1c384591f15551ab3b920203ed13b77a28 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Mon, 14 Aug 2023 20:59:31 +0530 Subject: [PATCH 11/30] SWDEV-388833 - [catch2][dtest] Kernel tests migrated from dtests to catch2 (#320) Change-Id: Ibc0248300b8ce8b58d1025743ab5946721e9d7e5 --- catch/include/hip_test_defgroups.hh | 144 ++- catch/unit/kernel/CMakeLists.txt | 8 + catch/unit/kernel/hipDynamicShared.cc | 161 ++++ catch/unit/kernel/hipDynamicShared2.cc | 89 ++ catch/unit/kernel/hipEmptyKernel.cc | 52 + catch/unit/kernel/hipExtLaunchKernelGGL.cc | 133 +++ catch/unit/kernel/hipGridLaunch.cc | 117 +++ catch/unit/kernel/hipLanguageExtensions.cc | 104 ++ catch/unit/kernel/hipLaunchParm.cc | 1009 ++++++++++++++++++++ catch/unit/kernel/hipLaunchParmFunctor.cc | 459 +++++++++ 10 files changed, 2194 insertions(+), 82 deletions(-) create mode 100644 catch/unit/kernel/hipDynamicShared.cc create mode 100644 catch/unit/kernel/hipDynamicShared2.cc create mode 100644 catch/unit/kernel/hipEmptyKernel.cc create mode 100644 catch/unit/kernel/hipExtLaunchKernelGGL.cc create mode 100644 catch/unit/kernel/hipGridLaunch.cc create mode 100644 catch/unit/kernel/hipLanguageExtensions.cc create mode 100644 catch/unit/kernel/hipLaunchParm.cc create mode 100644 catch/unit/kernel/hipLaunchParmFunctor.cc diff --git a/catch/include/hip_test_defgroups.hh b/catch/include/hip_test_defgroups.hh index 7d6fd3f731..5d4a319187 100644 --- a/catch/include/hip_test_defgroups.hh +++ b/catch/include/hip_test_defgroups.hh @@ -30,16 +30,17 @@ THE SOFTWARE. */ /** - * @defgroup GraphTest Graph Management + * @defgroup ContextTest Context Management * @{ - * This section describes tests for the graph management types & functions of HIP runtime API. + * This section describes tests for the context management functions of HIP runtime API. + * @warning All Context Management APIs are **deprecated** and shall not be implemented. * @} */ /** - * @defgroup VectorTypeTest Vector types + * @defgroup DeviceLanguageTest Device Language * @{ - * This section describes tests for the Vector type functions and operators. + * This section describes tests for the Device Language API. * @} */ @@ -50,28 +51,6 @@ THE SOFTWARE. * @} */ -/** - * @defgroup EventTest Event Management - * @{ - * This section describes tests for the event management functions of HIP runtime API. - * @} - */ - -/** - * @defgroup ErrorTest Error Handling - * @{ - * This section describes tests for the error handling functions of HIP runtime API. - * @} - */ - -/** - * @defgroup PeerToPeerTest PeerToPeer Device Memory Access - * @{ - * This section describes tests for the PeerToPeer device memory access functions of HIP runtime API. - * @warning PeerToPeer support is experimental. - * @} - */ - /** * @defgroup DriverTest Initialization and Version * @{ @@ -79,56 +58,6 @@ THE SOFTWARE. * @} */ -/** - * @defgroup DeviceLanguageTest Device Language - * @{ - * This section describes tests for the Device Language API. - * @} - */ - -/** - * @defgroup ExecutionTest Execution Control - * @{ - * This section describes tests for the execution control functions of HIP runtime API. - * @} - */ - -/** - * @defgroup TextureTest Texture Management - * @{ - * This section describes tests for the texture management functions of HIP runtime API. - * @} - */ - - /** - * @defgroup ShflTest warp shuffle function Management - * @{ - * This section describes the warp shuffle types & functions of HIP runtime API. - * @} - */ - -/** - * @defgroup EventTest Event Management - * @{ - * This section describes the event management types & functions of HIP runtime API. - * @} - */ - -/** - * @defgroup ContextTest Context Management - * @{ - * This section describes tests for the context management functions of HIP runtime API. - * @warning All Context Management APIs are **deprecated** and shall not be implemented. - * @} - */ - -/** - * @defgroup StreamTest Stream Management - * @{ - * This section describes the stream management types & functions of HIP runtime API. - * @} - */ - /** * @defgroup DynamicLoadingTest Kernel Loading Management * @{ @@ -137,9 +66,30 @@ THE SOFTWARE. */ /** - * @defgroup MemoryTest memory Management APIs + * @defgroup ErrorTest Error Handling * @{ - * This section describes the memory management types & functions of HIP runtime API. + * This section describes tests for the error handling functions of HIP runtime API. + * @} + */ + +/** + * @defgroup EventTest Event Management + * @{ + * This section describes tests for the event management functions of HIP runtime API. + * @} + */ + +/** + * @defgroup ExecutionTest Execution Control + * @{ + * This section describes tests for the execution control functions of HIP runtime API. + * @} + */ + +/** + * @defgroup GraphTest Graph Management + * @{ + * This section describes tests for the graph management types & functions of HIP runtime API. * @} */ @@ -151,14 +101,44 @@ THE SOFTWARE. */ /** - * @defgroup DeviceLanguageTest Device Language + * @defgroup MemoryTest memory Management APIs * @{ - * This section describes tests for the Device Language API. + * This section describes the memory management types & functions of HIP runtime API. * @} */ /** - * @defgroup DeviceLanguageTest Device Language + * @defgroup PeerToPeerTest PeerToPeer Device Memory Access * @{ - * This section describes tests for the Device Language API. + * This section describes tests for the PeerToPeer device memory access functions of HIP runtime API. + * @warning PeerToPeer support is experimental. + * @} + */ + + /** + * @defgroup ShflTest warp shuffle function Management + * @{ + * This section describes the warp shuffle types & functions of HIP runtime API. + * @} + */ + +/** + * @defgroup StreamTest Stream Management + * @{ + * This section describes the stream management types & functions of HIP runtime API. + * @} + */ + +/** + * @defgroup TextureTest Texture Management + * @{ + * This section describes tests for the texture management functions of HIP runtime API. + * @} + */ + +/** + * @defgroup VectorTypeTest Vector types + * @{ + * This section describes tests for the Vector type functions and operators. + * @} */ diff --git a/catch/unit/kernel/CMakeLists.txt b/catch/unit/kernel/CMakeLists.txt index 77a48363ed..d8a07b8638 100644 --- a/catch/unit/kernel/CMakeLists.txt +++ b/catch/unit/kernel/CMakeLists.txt @@ -23,6 +23,13 @@ set(TEST_SRC hipMemFaultStackAllocation.cc hipLaunchBounds.cc hipShflTests.cc + hipDynamicShared.cc + hipDynamicShared2.cc + hipEmptyKernel.cc + hipGridLaunch.cc + hipLanguageExtensions.cc + hipLaunchParm.cc + hipLaunchParmFunctor.cc hipTestConstant.cc hipTestGlobalVariable.cc hipTestMemKernel.cc @@ -47,6 +54,7 @@ endif() if(HIP_PLATFORM MATCHES "amd") set(AMD_SRC hipShflUpDownTest.cc + hipExtLaunchKernelGGL.cc ) set(TEST_SRC ${TEST_SRC} ${AMD_SRC}) endif() diff --git a/catch/unit/kernel/hipDynamicShared.cc b/catch/unit/kernel/hipDynamicShared.cc new file mode 100644 index 0000000000..168d979d14 --- /dev/null +++ b/catch/unit/kernel/hipDynamicShared.cc @@ -0,0 +1,161 @@ +/* +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 +#include +#include +#include +unsigned threadsPerBlock = 256; + +template +__device__ void sum(T* sdata, unsigned groupElements, unsigned tid) { + T tmp; + if (groupElements < batch) + return; + // sdata[tid] += sdata[tid - batch/2] does not work when block size is + // greater than wave size because one wave may complete before another + // wave. + if (tid >= batch/2 && tid < groupElements) + tmp = sdata[tid - batch/2]; + __syncthreads(); + if (tid >= batch/2 && tid < groupElements) + sdata[tid] += tmp; + __syncthreads(); +} + +template +__global__ void testExternSharedKernel(const T* A_d, const T* B_d, T* C_d, + size_t numElements, size_t groupElements) { + // declare dynamic shared memory + extern __shared__ double sdata0[]; + T* sdata = reinterpret_cast(sdata0); + + size_t gid = (blockIdx.x * blockDim.x + threadIdx.x); + size_t tid = threadIdx.x; + + // initialize dynamic shared memory + if (tid < groupElements) { + sdata[tid] = static_cast(tid); + } + __syncthreads(); + + // prefix sum inside dynamic shared memory + sum<512>(sdata, groupElements, tid); + sum<256>(sdata, groupElements, tid); + sum<128>(sdata, groupElements, tid); + sum<64>(sdata, groupElements, tid); + sum<32>(sdata, groupElements, tid); + sum<16>(sdata, groupElements, tid); + sum<8>(sdata, groupElements, tid); + sum<4>(sdata, groupElements, tid); + sum<2>(sdata, groupElements, tid); + C_d[gid] = A_d[gid] + B_d[gid] + sdata[tid % groupElements]; +} + +template +void testExternShared(size_t N, unsigned groupElements) { + size_t Nbytes = N * sizeof(T); + + T *A_d, *B_d, *C_d; + T *A_h, *B_h, *C_h; + + HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, N, false); + unsigned blocks = N/threadsPerBlock; + assert(N == blocks * threadsPerBlock); + + HIP_CHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice)); + + // calculate the amount of dynamic shared memory required + size_t groupMemBytes = groupElements * sizeof(double); + + // launch kernel with dynamic shared memory + hipLaunchKernelGGL(HIP_KERNEL_NAME(testExternSharedKernel), dim3(blocks), + dim3(threadsPerBlock), groupMemBytes, 0, A_d, B_d, C_d, + N, groupElements); + + HIP_CHECK(hipDeviceSynchronize()); + HIP_CHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + + // verify + for (size_t i = 0; i < N; ++i) { + size_t tid = (i % min(threadsPerBlock, groupElements)); + T sumFromSharedMemory = static_cast(tid * (tid + 1) / 2); + T expected = A_h[i] + B_h[i] + sumFromSharedMemory; + REQUIRE(C_h[i] == expected); + } + HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false); +} + +/** +* @addtogroup hipLaunchKernelGGL 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 + * ------------------------ + * - launch kernel with dynamic shared memory for float and double + * datatypes and verify the results. + + * Test source + * ------------------------ + * - catch/unit/kernel/hipDynamicShared.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.5 + */ + +TEST_CASE("Unit_hipDynamicShared") { + SECTION("test case with float for least size") { + testExternShared(1024, 4); + testExternShared(1024, 8); + testExternShared(1024, 16); + testExternShared(1024, 32); + testExternShared(1024, 64); + } + + SECTION("test case with float for max size") { + testExternShared(65536, 4); + testExternShared(65536, 8); + testExternShared(65536, 16); + testExternShared(65536, 32); + testExternShared(65536, 64); + } + + SECTION("test case with double for least size") { + testExternShared(1024, 4); + testExternShared(1024, 8); + testExternShared(1024, 16); + testExternShared(1024, 32); + testExternShared(1024, 64); + } + + SECTION("test case with double for max size") { + testExternShared(65536, 4); + testExternShared(65536, 8); + testExternShared(65536, 16); + testExternShared(65536, 32); + testExternShared(65536, 64); + } +} diff --git a/catch/unit/kernel/hipDynamicShared2.cc b/catch/unit/kernel/hipDynamicShared2.cc new file mode 100644 index 0000000000..47a94c1357 --- /dev/null +++ b/catch/unit/kernel/hipDynamicShared2.cc @@ -0,0 +1,89 @@ +/* +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 +#include +#include +#include + +#define LEN (16 * 1024) +#define SIZE (LEN * sizeof(float)) + +__global__ void vectorAdd(float* Ad, float* Bd) { + extern __shared__ float sBd[]; + int tx = threadIdx.x; + for (int i = 0; i < LEN / 64; i++) { + sBd[tx + i * 64] = Ad[tx + i * 64] + 1.0f; + Bd[tx + i * 64] = sBd[tx + i * 64]; + } +} + +/** +* @addtogroup hipLaunchKernelGGL 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 + * ------------------------ + * - Assign max dynamic shared memory to kernel function and + * verify the results. + + * Test source + * ------------------------ + * - catch/unit/kernel/hipDynamicShared2.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.5 + */ + +TEST_CASE("Unit_hipDynamicShared2") { + float *A, *B, *Ad, *Bd; + A = new float[LEN]; + B = new float[LEN]; + for (int i = 0; i < LEN; i++) { + A[i] = 1.0f; + B[i] = 1.0f; + } + HIP_CHECK(hipMalloc(&Ad, SIZE)); + HIP_CHECK(hipMalloc(&Bd, SIZE)); + HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(Bd, B, SIZE, hipMemcpyHostToDevice)); + + hipError_t ret = hipFuncSetAttribute( + reinterpret_cast(&vectorAdd), + hipFuncAttributeMaxDynamicSharedMemorySize, SIZE); + + REQUIRE(ret == hipSuccess); + hipLaunchKernelGGL(vectorAdd, dim3(1, 1, 1), dim3(64, 1, 1), SIZE, 0, Ad, Bd); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipMemcpy(B, Bd, SIZE, hipMemcpyDeviceToHost)); + for (int i = 0; i < LEN; i++) { + assert(B[i] > 1.0f && B[i] < 3.0f); + } + HIP_CHECK(hipFree(Ad)); + HIP_CHECK(hipFree(Bd)); + + delete[] A; + delete[] B; +} diff --git a/catch/unit/kernel/hipEmptyKernel.cc b/catch/unit/kernel/hipEmptyKernel.cc new file mode 100644 index 0000000000..484a77e0a6 --- /dev/null +++ b/catch/unit/kernel/hipEmptyKernel.cc @@ -0,0 +1,52 @@ +/* +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 +#include +#include +#include + +__global__ void Empty(int param) {} + +/** +* @addtogroup hipLaunchKernelGGL 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 + * ------------------------ + * - pass empty Kernel function. + + * Test source + * ------------------------ + * - catch/unit/kernel/hipEmptyKernel.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.5 + */ + +TEST_CASE("Unit_hipEmptyKernel") { + hipLaunchKernelGGL(HIP_KERNEL_NAME(Empty), dim3(1), dim3(1), 0, 0, 0); + HIP_CHECK(hipDeviceSynchronize()); +} diff --git a/catch/unit/kernel/hipExtLaunchKernelGGL.cc b/catch/unit/kernel/hipExtLaunchKernelGGL.cc new file mode 100644 index 0000000000..c23ebb7f81 --- /dev/null +++ b/catch/unit/kernel/hipExtLaunchKernelGGL.cc @@ -0,0 +1,133 @@ +/* +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. +*/ +// Test the Grid_Launch syntax. + +#include +#include +#include +#include +#include "hip/hip_ext.h" + +static unsigned threadsPerBlock = 256; +static unsigned blocksPerCU = 6; + +struct _t { + double _a, _b, _c, _d, _e, _f, _g, _h, _i, _j; +}; + +typedef struct _t _T; + +__global__ void sKernel(_T s, double *a) { + *a = s._a + s._b + s._c + s._d + s._e + s._f + s._g + s._h + s._i + s._j; +} + +__global__ void mKernel(char f, int16_t a, int b, double c, + int16_t d, int e, double* res) { + *res = a + b + c + d + e + f; +} + +void testMixData() { + double m = 0; + double *d_m; + HIP_CHECK(hipMalloc(&d_m, sizeof(double))); + int a = 1, e = 10; + int16_t b = 2, d = 4; + double c = 3.0; + char ff = 10; + hipExtLaunchKernelGGL(mKernel, 1, 1, 0, 0, nullptr, nullptr, 0, ff, + b, a, c, d, e, d_m); + HIP_CHECK(hipMemcpy(&m, d_m, sizeof(double), hipMemcpyDeviceToHost)); + REQUIRE(m == 30.0); + HIP_CHECK(hipFree(d_m)); +} + +void testStruct() { + double m = 0; + double *d_m; + HIP_CHECK(hipMalloc(&d_m, sizeof(double))); + _T s{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + hipExtLaunchKernelGGL(sKernel, 1, 1, 0, 0, nullptr, nullptr, 0, s, d_m); + HIP_CHECK(hipMemcpy(&m, d_m, sizeof(double), hipMemcpyDeviceToHost)); + REQUIRE(m == 55.0); + HIP_CHECK(hipFree(d_m)); +} + +void test(size_t N) { + size_t Nbytes = N * sizeof(int); + 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, N); + + unsigned blocks = HipTest::setNumBlocks(blocksPerCU, threadsPerBlock, N); + + HIP_CHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice)); + + hipExtLaunchKernelGGL(HipTest::vectorADD, dim3(blocks), + dim3(threadsPerBlock), 0, 0, nullptr, nullptr, 0, + static_cast(A_d), + static_cast(B_d), C_d, N); + + HIP_CHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + HIP_CHECK(hipDeviceSynchronize()); + HipTest::checkVectorADD(A_h, B_h, C_h, N); +} + +/** +* @addtogroup hipExtLaunchKernelGGL hipExtLaunchKernelGGL +* @{ +* @ingroup KernelTest +* `void hipExtLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks, + std::uint32_t sharedMemBytes, hipStream_t stream, + hipEvent_t startEvent, hipEvent_t stopEvent, std::uint32_t flags, + Args... args)` - +* Launches kernel with dimention parameters and shared memory on stream with templated kernel and arguments +*/ + +/** + * Test Description + * ------------------------ + * - Test case to verify sample array with hipExtLaunchKernelGGL() + * and verify the results. + * - Test case to verify struct data with hipExtLaunchKernelGGL() + * and verify the results. + * - Test case to verify mix datatypes with hipExtLaunchKernelGGL() + * and verify the results. + + * Test source + * ------------------------ + * - catch/unit/kernel/hipExtLaunchKernelGGL.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.5 + */ + +TEST_CASE("Unit_hipExtLaunchKernelGGL") { + SECTION("test run") { + size_t N = 4 * 1024 * 1024; + test(N); + } + SECTION("testStruct run") { + testStruct(); + } + SECTION("testMixData run") { + testMixData(); + } +} diff --git a/catch/unit/kernel/hipGridLaunch.cc b/catch/unit/kernel/hipGridLaunch.cc new file mode 100644 index 0000000000..7716b0781a --- /dev/null +++ b/catch/unit/kernel/hipGridLaunch.cc @@ -0,0 +1,117 @@ +/* +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. +*/ +// Test the Grid_Launch syntax. + +#include +#include +#include +#include + +static unsigned threadsPerBlock = 256; +static unsigned blocksPerCU = 6; + +// __device__ maps to __attribute__((hc)) +__device__ int foo(int i) { return i + 1; } + + +template +__global__ void vectorADD2(T* A_d, T* B_d, T* C_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) { + double foo = __hiloint2double(A_d[i], B_d[i]); + C_d[i] = __double2loint(foo) + __double2hiint(foo); + } +} + +int test_gl2(size_t N) { + size_t Nbytes = N * sizeof(int); + 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, N); + + unsigned blocks = HipTest::setNumBlocks(blocksPerCU, threadsPerBlock, N); + + // Full vadd in one large chunk, to get things started: + HIP_CHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice)); + hipLaunchKernelGGL(vectorADD2, dim3(blocks), dim3(threadsPerBlock), + 0, 0, A_d, B_d, C_d, N); + HIP_CHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + HIP_CHECK(hipDeviceSynchronize()); + // verify + HipTest::checkVectorADD(A_h, B_h, C_h, N); + return 0; +} + +#if __HIP__ +int test_triple_chevron(size_t N) { + size_t Nbytes = N * sizeof(int); + 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, N); + + unsigned blocks = HipTest::setNumBlocks(blocksPerCU, threadsPerBlock, N); + // Full vadd in one large chunk, to get things started: + HIP_CHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice)); + vectorADD2<<>>(A_d, B_d, C_d, N); + HIP_CHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + HIP_CHECK(hipDeviceSynchronize()); + // verify + HipTest::checkVectorADD(A_h, B_h, C_h, N); + return 0; +} +#endif + +/** +* @addtogroup hipLaunchKernelGGL 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 verify the Grid_Launch syntax. + + * Test source + * ------------------------ + * - catch/unit/kernel/hipGridLaunch.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.5 + */ + +TEST_CASE("Unit_hipGridLaunch") { + size_t N = 4 * 1024 * 1024; + SECTION("Test test_gl2") { + test_gl2(N); + } + +#if __HIP__ + SECTION("Test triple_chevron") { + test_triple_chevron(N); + } +#endif +} diff --git a/catch/unit/kernel/hipLanguageExtensions.cc b/catch/unit/kernel/hipLanguageExtensions.cc new file mode 100644 index 0000000000..5e601d35cf --- /dev/null +++ b/catch/unit/kernel/hipLanguageExtensions.cc @@ -0,0 +1,104 @@ +/* +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 +#include +#include +#include +#include + +// Simple tests for variable type qualifiers: +__device__ int deviceVar; + +// TODO-HCC __constant__ not working yet. +__constant__ int constantVar1; + +__constant__ __device__ int constantVar2; + +// Test HOST space: +__host__ void foo() { printf("foo!\n"); } + +__device__ __noinline__ int sum1_noinline(int a) { return a + 1; } +__device__ __forceinline__ int sum1_forceinline(int a) { return a + 1; } + + +__device__ __host__ float PlusOne(float x) { return x + 1.0; } + +__global__ void MyKernel(const float* a, const float* b, float* c, + unsigned N) { + unsigned gid = threadIdx.x; + if (gid < N) { + c[gid] = a[gid] + PlusOne(b[gid]); + } +} + +void callMyKernel() { + float *a, *b, *c; + const unsigned blockSize = 256; + unsigned N = blockSize; + hipLaunchKernelGGL(MyKernel, dim3(N / blockSize), dim3(blockSize), + 0, 0, a, b, c, N); +} + +template +__global__ void vectorADD(T __restrict__* A_d, T* B_d, T* C_d, size_t N) { +#ifdef NOT_YET + int a = __shfl_up(x, 1); +#endif + float x = 1.0; + float z = sin(x); +#ifdef NOT_YET + float fastZ = __sin(x); +#endif + __syncthreads(); + + 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_d[i] = A_d[i] + B_d[i]; + } +} + +/** +* @addtogroup hipLaunchKernelGGL 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 + * ------------------------ + * - Collection of code to make sure that various features + * in the hip kernel language compile. + + * Test source + * ------------------------ + * - catch/unit/kernel/hipLanguageExtensions.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.5 + */ + +TEST_CASE("Unit_hipLanguageExtensions") { + REQUIRE(true); +} diff --git a/catch/unit/kernel/hipLaunchParm.cc b/catch/unit/kernel/hipLaunchParm.cc new file mode 100644 index 0000000000..f033829f6e --- /dev/null +++ b/catch/unit/kernel/hipLaunchParm.cc @@ -0,0 +1,1009 @@ +/* +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 +#include +#include +#include +#include + +// Memory alignment is broken +// Update: with latest changes the aligment is working fine, hence enabled +#define ENABLE_ALIGNMENT_TEST_SMALL_BAR 1 + +// Packed member atribute broken +#define ENABLE_PACKED_TEST 0 + +// Update: with latest changes struct class object +// from device is working fine, hence enabled +#define ENABLE_CLASS_OBJ_ACCESS 1 + +// accessing dynamic/heap memory from device is broken +#define ENABLE_HEAP_MEMORY_ACCESS 0 + +// Update: with latest changes it's working hence enabled +#define ENABLE_USER_STL 1 + +// Update: with latest changes it's working hence enabled +#define ENABLE_OUT_OF_ORDER_INITIALIZATION 1 + +// Direct initialization of struct broken, +// ip_d9 is a pointer, uint_t*, hipLaunchKernelStruct_h9 = {'c', ip_d9}; +#define ENABLE_DECLARE_INITIALIZATION_POINTER 0 + +// Bit fields are broken +#define ENABLE_BIT_FIELDS 0 + +static const int BLOCK_DIM_SIZE = 512; + +// allocate memory on device and host for result validation +static bool *result_d, *result_h; + +static hipError_t hipMallocError = hipErrorUnknown; +static hipError_t hipHostMallocError = hipErrorUnknown; +static hipError_t hipMemsetError = hipErrorUnknown; + +static void ResultValidation() { + HIP_CHECK(hipMemcpy(result_h, result_d, BLOCK_DIM_SIZE*sizeof(bool), + hipMemcpyDeviceToHost)); + + for (int k = 0; k < BLOCK_DIM_SIZE; ++k) { + REQUIRE(result_h[k] == true); + } + return; +} + +// Segregating the reset part as it was causing a problem when i put inside +// ResultValidation() function, the memory was not reset correctly for the +// tests which were disabled. +static void ResetValidationMem() { + // reset the memory to false to reuse it. + HIP_CHECK(hipMemset(result_d, false, BLOCK_DIM_SIZE)); + HIP_CHECK(hipMemset(result_h, false, BLOCK_DIM_SIZE)); + return; +} + +// This test is to verify Struct with variables +// support, read from device. +typedef struct hipLaunchKernelStruct1 { + int li; // local int + float lf; // local float + bool result; // local bool +} hipLaunchKernelStruct_t1; + +// This test is to verify struct with padding, read from device +typedef struct hipLaunchKernelStruct2 { + char c1; + int64_t l1; + char c2; + int64_t l2; + bool result; +} hipLaunchKernelStruct_t2; + +// This test is to verify struct with padding, read from device +typedef struct hipLaunchKernelStruct3 { + char bf1; + char bf2; + int64_t l1; + char bf3; + bool result; +} hipLaunchKernelStruct_t3; + +// This test is to verify empty struct +typedef struct hipLaunchKernelStruct4 { + // empty struct, size will be verified from device side,size 1Byte +} hipLaunchKernelStruct_t4; + +// This test is to verify struct with pointer member variable. +typedef struct hipLaunchKernelStruct5 { + char c1; + char* cp; // char pointer +} hipLaunchKernelStruct_t5; + + +// This test is to verify struct with aligned(8), +// right now it's broken on hcc & hip-clang +typedef struct hipLaunchKernelStruct6 { + char c1; + int16_t si; +} __attribute__((aligned(8))) hipLaunchKernelStruct_t6; + +// This test is to verify struct with aligned(16), +// right now it's brokenon hcc & hip-clang +typedef struct hipLaunchKernelStruct7 { + char c1; + int16_t si; +} __attribute__((aligned(16))) hipLaunchKernelStruct_t7; + +// This test is to verify struct with packed & aligned, +// size should be 4Bytes right now it's broken on hcc & hip-clang +typedef struct hipLaunchKernelStruct8 { + char c1; + int16_t si; + bool b; +}__attribute__((packed, aligned(4))) hipLaunchKernelStruct_t8; + +// This test is to verify struct with packed, no alignment as Sam suggested +// size should be 4Bytes, right now it's broken on hcc & hip-clang +typedef struct hipLaunchKernelStruct8A { + char c1; + int16_t si; + bool b; +}__attribute__((packed)) hipLaunchKernelStruct_t8A; + +// This test is to verify struct with alignment, no packing as Sam suggested +// size should be 8Bytes as no packing, right now it's broken on hcc & hip-clang +typedef struct hipLaunchKernelStruct8B { + char c1; + int16_t si; + bool b; +}__attribute__((aligned(8))) hipLaunchKernelStruct_t8B; + +// This test is to verify const struct object +typedef struct hipLaunchKernelStruct9 { + char c1; + uint32_t* ip; // uint pointer +} hipLaunchKernelStruct_t9; + +// This test is to verify struct with stdint types, uintN_t +typedef struct hipLaunchKernelStruct10 { + uint64_t u64; + uint32_t u32; + uint8_t u8; +} hipLaunchKernelStruct_t10; + +// This test is to verify struct with volatile member +typedef struct hipLaunchKernelStruct11 { + int i1; + volatile unsigned int vint; +} hipLaunchKernelStruct_t11; + +// This test is to verify struct with simple class object +class base { + public: + int i = 0; + base() {} +}; +typedef struct hipLaunchKernelStruct12 { + base b; + char c1; +} hipLaunchKernelStruct_t12; + +// This test is to verify struct with __device__ func() attribute +typedef struct hipLaunchKernelStruct13 { + int i1; + __device__ int getvalue() { return i1; } +} hipLaunchKernelStruct_t13; + +// This test is to verify struct with array variable, +// write to from device +typedef struct hipLaunchKernelStruct14 { + int readint; + int writeint[BLOCK_DIM_SIZE]; // will write to this from device +} hipLaunchKernelStruct_t14; + +// This test is to verify struct with dynamic memory, new int +// the heap memory will be accessed from device +typedef struct hipLaunchKernelStruct15 { + char c1; + int* heapmem; // allocated using hipMalloc() +} hipLaunchKernelStruct_t15; + +// This test is to verify simple template struct +template +struct hipLaunchKernelStruct_t16 { + T t1; +}; + +// This test is to verify simple explicity template struct +template struct hipLaunchKernelStruct_t17 {}; +template<> // explicit template +struct hipLaunchKernelStruct_t17 { + int t1; +}; + +// This test is to verity write to struct memory using __device__ func() +typedef struct hipLaunchKernelStruct18 { + char c1; + __device__ void setChar(char c) { c1 = c; } + __device__ int getChar() { return c1; } +} hipLaunchKernelStruct_t18; + +// This test is to verity user defined STL, simple stack implementation +typedef struct stackNode { + int data; + stackNode* nextNode = NULL; +} stackNode_t; +typedef struct hipLaunchKernelStruct19 { + stackNode_t* stack = NULL; + unsigned int size_ = 0; + void pushMe(int value) { // not a device function, setting from host + stackNode_t* newNode; + HIP_CHECK(hipMalloc(reinterpret_cast(&newNode), + sizeof(stackNode_t))); + HIP_CHECK(hipMemset(&newNode->data, value, sizeof(stackNode_t))); + // newNode->data = value; + ++size_; + if (stack == NULL) { + stack = newNode; + return; + } + stackNode_t* currentHead = stack; + stack = newNode; + stack->nextNode = currentHead; + return; + } + __device__ void popMe() { + stackNode_t* currentHead = stack; + stack = stack->nextNode; + --size_; + // delete currentHead; // no idea why delete not working + return; + } + int stackSize() { + return size_; + } +} hipLaunchKernelStruct_t19; + +// This test is to verify out of order initalizer of struct elements +// and access in-order, from device. +typedef struct hipLaunchKernelStruct20 { + char name; + int age; + int rank; +} hipLaunchKernelStruct_t20; + +// This test is to verify bit fields operations +// the size should be 1Bytes +typedef struct hipLaunchKernelStruct21 { + int i : 3; // limiting bits to 3 + int j : 2; // limiting bits to 2 +} hipLaunchKernelStruct_t21; + +// Passing struct to a hipLaunchKernelGGL(), +// read and write into the same struct +__global__ void hipLaunchKernelStructFunc1( + hipLaunchKernelStruct_t1 hipLaunchKernelStruct_, + bool* result_d1) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + + // set the result to true if the condition met + result_d1[x] = ((hipLaunchKernelStruct_.li == 1) + && (hipLaunchKernelStruct_.lf == 1.0) + && (hipLaunchKernelStruct_.result == false)); +} + +// Passing struct to a hipLaunchKernelGGL(), checks padding, +// read and write into the same struct +__global__ void hipLaunchKernelStructFunc2( + hipLaunchKernelStruct_t2 hipLaunchKernelStruct_, + bool* result_d2) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + + // set the result to true if the condition met + result_d2[x] = ((hipLaunchKernelStruct_.c1 == 'a') + && (hipLaunchKernelStruct_.l1 == 1.0) + && (hipLaunchKernelStruct_.c2 == 'b') + && (hipLaunchKernelStruct_.l2 == 2.0) ); +} + +// Passing struct to a hipLaunchKernelGGL(), checks padding, +// read and write into the same struct +__global__ void hipLaunchKernelStructFunc3( + hipLaunchKernelStruct_t3 hipLaunchKernelStruct_, + bool* result_d3) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + + // set the result to true if the condition met + result_d3[x] = ((hipLaunchKernelStruct_.bf1 == 1) + && (hipLaunchKernelStruct_.bf2 == 1) + && (hipLaunchKernelStruct_.l1 == 1.0) + && (hipLaunchKernelStruct_.bf3 == 1) ); +} + +// Passing empty struct to a hipLaunchKernelGGL(), +// check the size of 1Byte, set result_d4 to true if condition met +__global__ void hipLaunchKernelStructFunc4( + hipLaunchKernelStruct_t4 hipLaunchKernelStruct_, + bool* result_d4) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + + // set the result to true if the condition met + result_d4[x] = (sizeof(hipLaunchKernelStruct_) == 1); +} + +// Passing struct with pointer object to a hipLaunchKernelGGL() +__global__ void hipLaunchKernelStructFunc5( + hipLaunchKernelStruct_t5 hipLaunchKernelStruct_, + bool* result_d5) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + + // set the result to true if the condition met + result_d5[x] = ((hipLaunchKernelStruct_.c1 == 'c') + && (*hipLaunchKernelStruct_.cp == 'p')); +} + +// Passing struct which is aligned to 8Byte to a hipLaunchKernelGGL(), +// set the result_d6 to true if condition met +__global__ void hipLaunchKernelStructFunc6( + hipLaunchKernelStruct_t6 hipLaunchKernelStruct_, + bool* result_d6) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + + // set the result to true if the condition met + // get the address of the struct + // size_t(p)%8 will be 0 if aligned to 8Byte address space + int *p = reinterpret_cast(&hipLaunchKernelStruct_); + result_d6[x] = ((hipLaunchKernelStruct_.c1 == 'c') + && (hipLaunchKernelStruct_.si == 1) + && ((size_t(p))%8 ==0)); +} + +// Passing struct which is aligned to 16Byte, +// set the result_d7 to true if condition met +__global__ void hipLaunchKernelStructFunc7( + hipLaunchKernelStruct_t7 hipLaunchKernelStruct_, + bool* result_d7) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + + // set the result to true if the condition met + // get the address of the struct + // size_t(p)%16 will be 0 if aligned to 16Byte address space + int *p = reinterpret_cast(&hipLaunchKernelStruct_); + result_d7[x] = ((hipLaunchKernelStruct_.c1 == 'c') + && (hipLaunchKernelStruct_.si == 1) + && ((size_t(p))%16 ==0) ); +} + +// Passing struct which is packed & aligned to 4Byte, +// set the result_d8 to true if condition met +__global__ void hipLaunchKernelStructFunc8( + hipLaunchKernelStruct_t8 hipLaunchKernelStruct_, + bool* result_d8) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + // set the result to true if the condition met + // get the address of the xth element, struct[x], + // size_t(p)%4 will be 0 if aligned to 4Byte address space + int *p = reinterpret_cast(&hipLaunchKernelStruct_); + result_d8[x] = ((hipLaunchKernelStruct_.c1 == 'c') + && (hipLaunchKernelStruct_.si == 1) + && ((size_t(p))%4 ==0) + && (sizeof(hipLaunchKernelStruct_) == 4)); +} + +// Passing struct which is packed only, as Sam suggested, should be 4Bytes +// set the result_d8A to true if condition met +__global__ void hipLaunchKernelStructFunc8A( + hipLaunchKernelStruct_t8A hipLaunchKernelStruct_, + bool* result_d8A) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + // set the result to true if the condition met + // this is packed struct + // the address will not be aglined in this case hence condition removed + // only sizeof(hipLaunchKernelStruct_) will be valided + result_d8A[x] = ((hipLaunchKernelStruct_.c1 == 'c') + && (hipLaunchKernelStruct_.si == 1) + && (sizeof(hipLaunchKernelStruct_) == 4)); +} + +// Passing struct which is aligned(4) only, as Sam suggested +// , size should be 8Bytes, set the result_d8B to true if condition met +__global__ void hipLaunchKernelStructFunc8B( + hipLaunchKernelStruct_t8B hipLaunchKernelStruct_, + bool* result_d8B) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + // set the result to true if the condition met + // get the address of the xth element, struct[x], + // size_t(p)%4 will be 0 if aligned to 4Byte address space + int *p = reinterpret_cast(&hipLaunchKernelStruct_); + result_d8B[x] = ((hipLaunchKernelStruct_.c1 == 'c') + && (hipLaunchKernelStruct_.si == 1) + && ((size_t(p))%8 == 0) + && (sizeof(hipLaunchKernelStruct_) == 8)); +} + +// Passing struct with uint pointer object to a hipLaunchKernelGGL() +__global__ void hipLaunchKernelStructFunc9( + const hipLaunchKernelStruct_t9 hipLaunchKernelStruct_, + bool* result_d9) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + + // set the result to true if the condition met + result_d9[x] = ((hipLaunchKernelStruct_.c1 == 'c') + && (*hipLaunchKernelStruct_.ip == 1)); +} + +// Passing struct with stdint types object, uintN_t, to a hipLaunchKernelGGL() +__global__ void hipLaunchKernelStructFunc10( + hipLaunchKernelStruct_t10 hipLaunchKernelStruct_, + bool* result_d10) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + // set the result to true if the condition met + result_d10[x] = ((hipLaunchKernelStruct_.u64 == UINT64_MAX) + && (hipLaunchKernelStruct_.u32 == 1) + && (hipLaunchKernelStruct_.u8 == UINT8_MAX)); +} + +// Passing struct with volatile member, to a hipLaunchKernelGGL() +__global__ void hipLaunchKernelStructFunc11( + hipLaunchKernelStruct_t11 hipLaunchKernelStruct_, + bool* result_d11) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + // set the result to true if the condition met + result_d11[x] = ((hipLaunchKernelStruct_.i1 == 1) + && (hipLaunchKernelStruct_.vint == 0)); +} + +// Passing struct with simple class obj, to a hipLaunchKernelGGL() +__global__ void hipLaunchKernelStructFunc12( + hipLaunchKernelStruct_t12 hipLaunchKernelStruct_, + bool* result_d12) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + // set the result to true if the condition met + result_d12[x] = ((hipLaunchKernelStruct_.c1 == 'c') + && (hipLaunchKernelStruct_.b.i == 0)); +} + +// Passing struct with simple __device__ func(), to a hipLaunchKernelGGL() +__global__ void hipLaunchKernelStructFunc13( + hipLaunchKernelStruct_t13 hipLaunchKernelStruct_, + bool* result_d13) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + // set the result to true if the condition met + result_d13[x] = ((hipLaunchKernelStruct_.i1 == 1) + && (hipLaunchKernelStruct_.getvalue() == 1)); +} + +// Passing struct with array variable, write to from device +__global__ void hipLaunchKernelStructFunc14( + hipLaunchKernelStruct_t14 hipLaunchKernelStruct_, + bool* result_d14) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + hipLaunchKernelStruct_.writeint[x] = 1; + // set the result to true if the condition met + result_d14[x] = ((hipLaunchKernelStruct_.readint == 1) + && (hipLaunchKernelStruct_.writeint[x] == 1)); +} + +// Passing struct with struct with dynamic memory, new int +// the heap memory will be accessed from device +__global__ void hipLaunchKernelStructFunc15( + hipLaunchKernelStruct_t15 hipLaunchKernelStruct_, + bool* result_d15) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + // set the result to true if the condition met + result_d15[x] = ((hipLaunchKernelStruct_.c1 == 'c') + && (hipLaunchKernelStruct_.heapmem[x] == 1)); +} + +// Passing simple template struct +__global__ void hipLaunchKernelStructFunc16( + hipLaunchKernelStruct_t16 hipLaunchKernelStruct_, + bool* result_d16) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + // set the result to true if the condition met + result_d16[x] = (hipLaunchKernelStruct_.t1 == 'c'); +} + +// Passing simple explicit template struct +__global__ void hipLaunchKernelStructFunc17( + hipLaunchKernelStruct_t17 hipLaunchKernelStruct_, + bool* result_d17) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + // set the result to true if the condition met + result_d17[x] = (hipLaunchKernelStruct_.t1 == 1); +} + +// Passing struct and write to struct memory using __device__ func() +__global__ void hipLaunchKernelStructFunc18( + hipLaunchKernelStruct_t18 hipLaunchKernelStruct_, + bool* result_d18) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + hipLaunchKernelStruct_.setChar('c'); + // set the result to true if the condition met + result_d18[x] = (hipLaunchKernelStruct_.getChar() == 'c'); +} + +// Passing simple user defined stack implemenration, using __device__ func() +__global__ void hipLaunchKernelStructFunc19( + hipLaunchKernelStruct_t19 hipLaunchKernelStruct_) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + // stack should be empty after the kernel execustion, verify on host side + hipLaunchKernelStruct_.popMe(); +} + +// Passing out of order initalized struct, access in-order +__global__ void hipLaunchKernelStructFunc20( + hipLaunchKernelStruct_t20 hipLaunchKernelStruct_, + bool* result_d20) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + // accessing struct members in order + result_d20[x] = (hipLaunchKernelStruct_.name == 'A' + // strcmp(hipLaunchKernelStruct_.name, "AMD") -> strcmp is not broken + && hipLaunchKernelStruct_.age == 42 + && hipLaunchKernelStruct_.rank == 2); +} + +// Passing struct with bit fields +__global__ void hipLaunchKernelStructFunc21( + hipLaunchKernelStruct_t21 hipLaunchKernelStruct_, + bool* result_d21) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + // accessing struct members in order + result_d21[x] = (hipLaunchKernelStruct_.i == 2 + && hipLaunchKernelStruct_.j == 0 + && (sizeof(hipLaunchKernelStruct_) == 1)); +} + +__global__ void vAdd(float* a) {} + +template +__global__ void myKernel(T1 a, T2 b) {} + + +//--- +// Some wrapper macro for testing: +#define WRAP(...) __VA_ARGS__ + +#define MY_LAUNCH_MACRO(cmd, elapsed, quiet) \ + do { \ + HIP_CHECK(hipDeviceSynchronize()); \ + cmd; \ + HIP_CHECK(hipDeviceSynchronize()); \ + } while (0); + + +#define MY_LAUNCH(command, doTrace, msg) \ + { \ + if (doTrace) printf("TRACE: %s %s\n", msg, #command); \ + command; \ + } + + +#define MY_LAUNCH_WITH_PAREN(command, doTrace, msg) \ + { \ + if (doTrace) printf("TRACE: %s %s\n", msg, #command); \ + (command); \ + } + +/** +* @addtogroup hipLaunchKernelGGL 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 + * ------------------------ + * - Passing struct to a hipLaunchKernelGGL(), + * read and write into the same struct + * - Test to verify by Passing Struct type, checks padding + * - Test to verify by Passing Struct type, checks padding, assigning integer to a char + * - Test to verify by Passing empty struct + * - Test to verify by Passing struct with pointer object to a hipLaunchKernelGGL() + * - Test to verify by Passing struct with aligned(8) + * - Test to verify by Passing struct with aligned(16) + * - Test to verify by Passing struct with packed aligned to 4Bytes + * - Test to verify by Passing struct with packed to 4Bytes + * - Test to verify by Passing struct with aligned(4) to 4Bytes, size is 8Bytes + * - Test to verify by Passing const struct object to a hipLaunchKernelGGL() + * - Test to verify by Passing struct with uintN_t as member variables + * - Test to verify by Passing struct with uintN_t as member variables + * - Test to verify by Passing struct with simple class object + * - Test to verify by Passing struct with simple __device__ func() + * - Test to verify by Passing struct with array variable, write to from device + * - Test to verify by Passing simple template struct + * - Test to verify by Passing simple explicit template struct + * - Test to verify by Passing struct with simple __device__ func() to struct memory + * - Test to verify by Passing struct which is initiazed out of order + * accessing same elements in order from device + * - Test to verify by Passing struct with bit fields operation + * accessing same elements in order from device + * - Test to verify by Passing the different hipLaunchParm options + + * Test source + * ------------------------ + * - catch/unit/kernel/hipLaunchParm.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.5 + */ + +TEST_CASE("Unit_hipLaunchParm") { + hipMallocError = hipMalloc(reinterpret_cast(&result_d), + BLOCK_DIM_SIZE*sizeof(bool)); + hipHostMallocError = hipHostMalloc(reinterpret_cast(&result_h), + BLOCK_DIM_SIZE*sizeof(bool)); + hipMemsetError = hipMemset(result_d, false, BLOCK_DIM_SIZE); + + // Validating memory & initial value, for result_d, result_h + REQUIRE(hipMallocError == hipSuccess); + REQUIRE(hipHostMallocError == hipSuccess); + REQUIRE(hipMemsetError == hipSuccess); + + SECTION("check access from device") { + ResetValidationMem(); + hipLaunchKernelStruct_t1 hipLaunchKernelStruct_h1; + hipLaunchKernelStruct_h1.li = 1; + hipLaunchKernelStruct_h1.lf = 1.0; + hipLaunchKernelStruct_h1.result = false; + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc1), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h1, + result_d); + ResultValidation(); + } + + SECTION("check padding") { + ResetValidationMem(); + hipLaunchKernelStruct_t2 hipLaunchKernelStruct_h2; + hipLaunchKernelStruct_h2.c1 = 'a'; + hipLaunchKernelStruct_h2.l1 = 1.0; + hipLaunchKernelStruct_h2.c2 = 'b'; + hipLaunchKernelStruct_h2.l2 = 2.0; + hipLaunchKernelStruct_h2.result = false; + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc2), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h2, + result_d); + ResultValidation(); + } + + SECTION("check padding assigning int to char") { + ResetValidationMem(); + hipLaunchKernelStruct_t3 hipLaunchKernelStruct_h3; + hipLaunchKernelStruct_h3.bf1 = 1; + hipLaunchKernelStruct_h3.bf2 = 1; + hipLaunchKernelStruct_h3.l1 = 1.0; + hipLaunchKernelStruct_h3.bf3 = 1; + hipLaunchKernelStruct_h3.result = false; + // initialize to false, will be set to + // true if the struct size is 1Byte, from device size + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc3), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h3, + result_d); + ResultValidation(); + } + + SECTION("Empty struct") { + ResetValidationMem(); + hipLaunchKernelStruct_t4 hipLaunchKernelStruct_h4; + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc4), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h4, + result_d); + ResultValidation(); + } + + SECTION("Passing struct with pointer object") { + ResetValidationMem(); + hipLaunchKernelStruct_t5 hipLaunchKernelStruct_h5; + char* cp_d5; // This is passed as pointer to struct member + // allocating memory for char pointer on device + HIP_CHECK(hipMalloc(reinterpret_cast(&cp_d5), sizeof(char))); + HIP_CHECK(hipMemset(cp_d5, 'p', sizeof(char))); + hipLaunchKernelStruct_h5.c1 = 'c'; + hipLaunchKernelStruct_h5.cp = cp_d5; + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc5), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h5, + result_d); + ResultValidation(); + } + + SECTION("Passing struct with aligned(8)") { + ResetValidationMem(); + hipLaunchKernelStruct_t6 hipLaunchKernelStruct_h6; + hipLaunchKernelStruct_h6.c1 = 'c'; + hipLaunchKernelStruct_h6.si = 1; + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc6), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h6, + result_d); + // alignment is broken hence disabled the validation part + #if ENABLE_ALIGNMENT_TEST_SMALL_BAR + ResultValidation(); + #endif + } + + SECTION("Passing struct with aligned(16)") { + ResetValidationMem(); + hipLaunchKernelStruct_t7 hipLaunchKernelStruct_h7; + hipLaunchKernelStruct_h7.c1 = 'c'; + hipLaunchKernelStruct_h7.si = 1; + #if ENABLE_ALIGNMENT_TEST_SMALL_BAR // This is broken on small bar + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc7), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h7, + result_d); + ResultValidation(); + #endif + } + + SECTION("Passing struct with packed aligned to 4bytes") { + ResetValidationMem(); + hipLaunchKernelStruct_t8 hipLaunchKernelStruct_h8; + hipLaunchKernelStruct_h8.c1 = 'c'; + hipLaunchKernelStruct_h8.si = 1; + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc8), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h8, + result_d); + // packed member broken on large and small bar setup. + #if ENABLE_PACKED_TEST + ResultValidation(); + #endif + } + + SECTION("Passing struct with packed to 4Bytes") { + ResetValidationMem(); + hipLaunchKernelStruct_t8A hipLaunchKernelStruct_h8A; + hipLaunchKernelStruct_h8A.c1 = 'c'; + hipLaunchKernelStruct_h8A.si = 1; + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc8A), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h8A, + result_d); + // packed member broken on large and small bar setup. + #if ENABLE_PACKED_TEST + ResultValidation(); + #endif + } + + SECTION("Passing struct with aligned(4) to 4Bytes") { + ResetValidationMem(); + hipLaunchKernelStruct_t8B hipLaunchKernelStruct_h8B; + hipLaunchKernelStruct_h8B.c1 = 'c'; + hipLaunchKernelStruct_h8B.si = 1; + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc8B), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h8B, + result_d); + // alignment is broken hence disabled the validation part + #if ENABLE_ALIGNMENT_TEST_SMALL_BAR + ResultValidation(); + #endif + } + + SECTION("Passing const struct object") { + ResetValidationMem(); + uint32_t* ip_d9; + // allocating memory for char pointer on device + HIP_CHECK(hipMalloc(reinterpret_cast(&ip_d9), sizeof(uint32_t))); + HIP_CHECK(hipMemset(ip_d9, 1, sizeof(uint32_t))); + // ip_d9 passed as pointer to struct member, struct.ip = &ip_d9 + const hipLaunchKernelStruct_t9 hipLaunchKernelStruct_h9 = {'c', ip_d9}; + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc9), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h9, + result_d); + #if ENABLE_DECLARE_INITIALIZATION_POINTER + ResultValidation(); + #endif + } + + SECTION("Passing struct with uintN_t") { + ResetValidationMem(); + hipLaunchKernelStruct_t10 hipLaunchKernelStruct_h10; + hipLaunchKernelStruct_h10.u64 = UINT64_MAX; + hipLaunchKernelStruct_h10.u32 = 1; + hipLaunchKernelStruct_h10.u8 = UINT8_MAX; + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc10), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h10, + result_d); + ResultValidation(); + } + + SECTION("hipLaunchKernelStructFunc11") { + ResetValidationMem(); + hipLaunchKernelStruct_t11 hipLaunchKernelStruct_h11; + hipLaunchKernelStruct_h11.i1 = 1; + hipLaunchKernelStruct_h11.vint = 0; + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc11), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h11, + result_d); + ResultValidation(); + } + + SECTION("Passing struct with simple class object") { + ResetValidationMem(); + hipLaunchKernelStruct_t12 hipLaunchKernelStruct_h12; + hipLaunchKernelStruct_h12.c1 = 'c'; + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc12), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h12, + result_d); + #if ENABLE_CLASS_OBJ_ACCESS // access class obj from device broken + // Validation part of the struct, hipLaunchKernelStructFunc12 + ResultValidation(); + #endif + } + + SECTION("Passing struct with simple __device__ func()") { + ResetValidationMem(); + hipLaunchKernelStruct_t13 hipLaunchKernelStruct_h13; + hipLaunchKernelStruct_h13.i1 = 1; + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc13), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h13, + result_d); + ResultValidation(); + } + + SECTION("Passing struct with array variable") { + ResetValidationMem(); + hipLaunchKernelStruct_t14 hipLaunchKernelStruct_h14; + hipLaunchKernelStruct_h14.readint = 1; + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc14), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h14, + result_d); + ResultValidation(); + } + + SECTION("Passing struct with heap memory") { + ResetValidationMem(); + hipLaunchKernelStruct_t15 hipLaunchKernelStruct_h15; + hipLaunchKernelStruct_h15.c1 = 'c'; + + #if ENABLE_HEAP_MEMORY_ACCESS // causing page fault here, + // on small bar set + HIP_CHECK(hipMalloc(&hipLaunchKernelStruct_h15.heapmem, + BLOCK_DIM_SIZE*sizeof(int))); + HIP_CHECK(hipMemset(&hipLaunchKernelStruct_h15.heapmem, + 0, BLOCK_DIM_SIZE)); + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc15), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h15, + result_d); + ResultValidation(); + #endif + } + + SECTION("Passing simple template struct") { + ResetValidationMem(); + hipLaunchKernelStruct_t16 hipLaunchKernelStruct_h16; + hipLaunchKernelStruct_h16.t1 = 'c'; + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc16), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h16, + result_d); + ResultValidation(); + } + + SECTION("Passing simple explicit template struct") { + ResetValidationMem(); + hipLaunchKernelStruct_t17 hipLaunchKernelStruct_h17; + hipLaunchKernelStruct_h17.t1 = 1; + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc17), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h17, + result_d); + ResultValidation(); + } + + SECTION("Passing struct with simple __device__ func()") { + ResetValidationMem(); + hipLaunchKernelStruct_t18 hipLaunchKernelStruct_h18; + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc18), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h18, + result_d); + ResultValidation(); + } + + SECTION("Passing user defined stack") { + ResetValidationMem(); + hipLaunchKernelStruct_t19 hipLaunchKernelStruct_h19; + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc19), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h19); + #if ENABLE_USER_STL + // Validation part of the struct, hipLaunchKernelStructFunc19 + HIPASSERT(hipLaunchKernelStruct_h19.stackSize() == 0); + #endif + } + + // Test: Passing struct which is initiazed out of order + // accessing same elements in order from device + SECTION("Passing struct which is initiazed out of order") { + ResetValidationMem(); + hipLaunchKernelStruct_t20 hipLaunchKernelStruct_h20; + hipLaunchKernelStruct_h20.name = 'A'; + hipLaunchKernelStruct_h20.rank = 2; + hipLaunchKernelStruct_h20.age = 42; + bool *result_d20, *result_h20; + #if ENABLE_OUT_OF_ORDER_INITIALIZATION + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc20), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h20, result_d); + ResultValidation(); + #endif + } + + SECTION("Passing struct with bit fields operation") { + ResetValidationMem(); + hipLaunchKernelStruct_t21 hipLaunchKernelStruct_h21 = + // out of order initalization + {2, 0}; + bool *result_d21, *result_h21; + hipLaunchKernelGGL(HIP_KERNEL_NAME(hipLaunchKernelStructFunc21), + dim3(BLOCK_DIM_SIZE), + dim3(1), 0, 0, hipLaunchKernelStruct_h21, result_d); + #if ENABLE_BIT_FIELDS + ResultValidation(); + #endif + } + + SECTION("Passing the different hipLaunchParm options") { + float* Ad; + HIP_CHECK(hipMalloc(reinterpret_cast(&Ad), 1024)); + hipLaunchKernelGGL(HIP_KERNEL_NAME(vAdd), size_t(1024), 1, 0, 0, Ad); + hipLaunchKernelGGL(HIP_KERNEL_NAME(vAdd), 1024, dim3(1), 0, 0, Ad); + hipLaunchKernelGGL(HIP_KERNEL_NAME(vAdd), dim3(1024), 1, 0, 0, Ad); + hipLaunchKernelGGL(HIP_KERNEL_NAME(vAdd), dim3(1024), dim3(1), 0, 0, Ad); + + // Test: Passing macro to hipLaunchKernelGGL +#define KERNEL_CONFIG dim3(1024), dim3(1), 0, 0 + hipLaunchKernelGGL(HIP_KERNEL_NAME(vAdd), KERNEL_CONFIG, Ad); + + // Test: Same thing with templates: + int a; + float b; + hipLaunchKernelGGL(HIP_KERNEL_NAME(myKernel), + KERNEL_CONFIG, a, b); + +#define TYPE_PARAM_CONFIG int, float + hipLaunchKernelGGL(HIP_KERNEL_NAME(myKernel), + KERNEL_CONFIG, a, b); + + // Test: Passing hipLaunchKernelGGL inside another macro: + float e0; + MY_LAUNCH_MACRO(hipLaunchKernelGGL(vAdd, dim3(1024), + dim3(1), 0, 0, Ad), e0, j); + MY_LAUNCH_MACRO(WRAP(hipLaunchKernelGGL(vAdd, dim3(1024), + dim3(1), 0, 0, Ad)), e0, j); + +#ifdef EXTRA_PARENS_1 + // Don't wrap hipLaunchKernelGGL in extra set of parens: + MY_LAUNCH_MACRO((hipLaunchKernelGGL(vAdd, dim3(1024), + dim3(1), 0, 0, Ad)), e0, j); +#endif + + MY_LAUNCH(hipLaunchKernelGGL(vAdd, dim3(1024), dim3(1), + 0, 0, Ad), true, "firstCall"); + float* A; + float e1; + MY_LAUNCH_WITH_PAREN(hipMalloc(&A, 100), true, "launch2"); + +#ifdef EXTRA_PARENS_2 + // MY_LAUNCH_WITH_PAREN wraps cmd in () which can cause issues. + MY_LAUNCH_WITH_PAREN(hipLaunchKernelGGL(vAdd, dim3(1024), + dim3(1), 0, 0, Ad), true, "firstCall"); +#endif + } + HIP_CHECK(hipHostFree(result_h)); + HIP_CHECK(hipFree(result_d)); +} diff --git a/catch/unit/kernel/hipLaunchParmFunctor.cc b/catch/unit/kernel/hipLaunchParmFunctor.cc new file mode 100644 index 0000000000..5b12ff52ae --- /dev/null +++ b/catch/unit/kernel/hipLaunchParmFunctor.cc @@ -0,0 +1,459 @@ +/* +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 +#include +#include +#include + +class HipFunctorTests { + public: + // Test that a class functor can be passed to hiplaunchparam + // and can be used in kernel + void TestForSimpleClassFunctor(void); + // Test that a templated class functor can be passed to hiplaunchparam + // and can be used in kernel + void TestForClassTemplateFunctor(void); + // Test that a class functor object ptr can be passed to hiplaunchparam + // and can be used in kernel + void TestForClassObjPtrFunctor(void); + // Test that a class object containing functor can be passed + // to hiplaunchparam and can be used in kernel + void TestForFunctorContainInClassObj(void); + // Test that a stuct functor can be passed to hiplaunchparam + // and can be used in kernel + void TestForSimpleStructFunctor(void); + // Test that a stuct functor object ptr can be passed to hiplaunchparam + // and can be used in kernel + void TestForStructObjPtrFunctor(void); + // Test that a templated struct functor can be passed to hiplaunchparam + // and can be used in kernel + void TestForStructTemplateFunctor(void); + // Test that a struct object containing functor can be + // passed to hiplaunchparam and can be used in kernel + void TestForFunctorContainInStructObj(void); +}; + +static const int BLOCK_DIM_SIZE = 1024; +static const int THREADS_PER_BLOCK = 1; + +// class functor tests + +// Simple doubler Functor +class DoublerFunctor{ + public: + __device__ int operator()(int x) { return x * 2;} +}; + +// simple doubler functor passed to kernel +__global__ void DoublerFunctorKernel( + DoublerFunctor doubler_, + bool* deviceResult) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + int result = doubler_(5); + deviceResult[x] = (result == 10); +} + +void HipFunctorTests::TestForSimpleClassFunctor(void) { + DoublerFunctor doubler; + bool *deviceResults, *hostResults; + HIP_CHECK(hipMalloc(&deviceResults, BLOCK_DIM_SIZE*sizeof(bool))); + HIP_CHECK(hipHostMalloc(&hostResults, BLOCK_DIM_SIZE*sizeof(bool))); + for (int k = 0; k < BLOCK_DIM_SIZE; ++k) { + // initialize to false, will be set to + // true if the functor is called in device code + hostResults[k] = false; + } + + HIP_CHECK(hipMemcpy(deviceResults, hostResults, BLOCK_DIM_SIZE*sizeof(bool), + hipMemcpyHostToDevice)); + hipLaunchKernelGGL(DoublerFunctorKernel, dim3(BLOCK_DIM_SIZE), + dim3(THREADS_PER_BLOCK), 0, 0, doubler, deviceResults); + + // Validation part of TestForSimpleClassFunctor + HIP_CHECK(hipMemcpy(hostResults, deviceResults, BLOCK_DIM_SIZE*sizeof(bool), + hipMemcpyDeviceToHost)); + for (int k = 0; k < BLOCK_DIM_SIZE; ++k) + REQUIRE(hostResults[k] == true); + HIP_CHECK(hipHostFree(hostResults)); + HIP_CHECK(hipFree(deviceResults)); +} + +// pointer functor passed to kernel +__global__ void PtrDoublerFunctorKernel( + DoublerFunctor *doubler_, + bool* deviceResult) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + int result = (*doubler_)(5); + deviceResult[x] = (result == 10); +} + +void HipFunctorTests::TestForClassObjPtrFunctor(void) { + DoublerFunctor* ptrdoubler = new DoublerFunctor[sizeof(int)]; + bool *deviceResults, *hostResults; + HIP_CHECK(hipMalloc(&deviceResults, BLOCK_DIM_SIZE*sizeof(bool))); + HIP_CHECK(hipHostMalloc(&hostResults, BLOCK_DIM_SIZE*sizeof(bool))); + for (int k = 0; k < BLOCK_DIM_SIZE; ++k) { + // initialize to false, will be set to + // true if the functor is called in device code + hostResults[k] = false; + } + + HIP_CHECK(hipMemcpy(deviceResults, hostResults, BLOCK_DIM_SIZE*sizeof(bool), + hipMemcpyHostToDevice)); + hipLaunchKernelGGL(PtrDoublerFunctorKernel, dim3(BLOCK_DIM_SIZE), + dim3(THREADS_PER_BLOCK), 0, 0, ptrdoubler, deviceResults); + + // Validation part of TestForClassObjPtrFunctor + HIP_CHECK(hipMemcpy(hostResults, deviceResults, BLOCK_DIM_SIZE*sizeof(bool), + hipMemcpyDeviceToHost)); + for (int k = 0; k < BLOCK_DIM_SIZE; ++k) + REQUIRE(hostResults[k] == true); + HIP_CHECK(hipHostFree(hostResults)); + HIP_CHECK(hipFree(deviceResults)); + delete[] ptrdoubler; +} + +class compare { + public: + template + __device__ bool operator()(const T1& v1, const T2& v2) { + return v1 > v2; + } +}; + +// template functor passed to kernel +__global__ void TemplateFunctorKernel( + compare compare_, + bool* deviceResult) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + deviceResult[x] = compare_(2.2, 2.1); + deviceResult[x] = compare_(2, 1); + deviceResult[x] = compare_('b', 'a'); +} + +void HipFunctorTests::TestForClassTemplateFunctor(void) { + compare comparefunctor; + bool *deviceResults, *hostResults; + HIP_CHECK(hipMalloc(&deviceResults, BLOCK_DIM_SIZE*sizeof(bool))); + HIP_CHECK(hipHostMalloc(&hostResults, BLOCK_DIM_SIZE*sizeof(bool))); + for (int k = 0; k < BLOCK_DIM_SIZE; ++k) { + // initialize to false, will be set to + // true if the functor is called in device code + hostResults[k] = false; + } + + HIP_CHECK(hipMemcpy(deviceResults, hostResults, BLOCK_DIM_SIZE*sizeof(bool), + hipMemcpyHostToDevice)); + hipLaunchKernelGGL(TemplateFunctorKernel, dim3(BLOCK_DIM_SIZE), + dim3(THREADS_PER_BLOCK), 0, 0, comparefunctor, deviceResults); + + // Validation part of TestForClassTemplateFunctor + HIP_CHECK(hipMemcpy(hostResults, deviceResults, BLOCK_DIM_SIZE*sizeof(bool), + hipMemcpyDeviceToHost)); + for (int k = 0; k < BLOCK_DIM_SIZE; ++k) + REQUIRE(hostResults[k] == true); + HIP_CHECK(hipHostFree(hostResults)); + HIP_CHECK(hipFree(deviceResults)); +} + + +// Doubler calculator +class DoublerCalculator { + public: + int a, result; + // fucntor contained in class object + DoublerFunctor doubler; +}; + +// doubler functor conatined in class obj passed to kernel +__global__ void DoublerCalculatorFunctorKernel( + DoublerCalculator doubler_, + bool* deviceResult) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + int result = doubler_.doubler(doubler_.a); + deviceResult[x] = (doubler_.result == result); +} + +void HipFunctorTests::TestForFunctorContainInClassObj(void) { + DoublerCalculator Doubler; + bool *deviceResults, *hostResults; + HIP_CHECK(hipMalloc(&deviceResults, BLOCK_DIM_SIZE*sizeof(bool))); + HIP_CHECK(hipHostMalloc(&hostResults, BLOCK_DIM_SIZE*sizeof(bool))); + for (int k = 0; k < BLOCK_DIM_SIZE; ++k) { + // initialize to false, will be set to + // true if the functor is called in device code + hostResults[k] = false; + } + + Doubler.a = 5; + Doubler.result = 10; + // pass comparefunctor to hipLaunchParm + + HIP_CHECK(hipMemcpy(deviceResults, hostResults, BLOCK_DIM_SIZE*sizeof(bool), + hipMemcpyHostToDevice)); + hipLaunchKernelGGL(DoublerCalculatorFunctorKernel, dim3(BLOCK_DIM_SIZE), + dim3(THREADS_PER_BLOCK), 0, 0, Doubler, deviceResults); + + // Validation part of TestForStructTemplateFunctor + HIP_CHECK(hipMemcpy(hostResults, deviceResults, BLOCK_DIM_SIZE*sizeof(bool), + hipMemcpyDeviceToHost)); + for (int k = 0; k < BLOCK_DIM_SIZE; ++k) + REQUIRE(hostResults[k] == true); + HIP_CHECK(hipHostFree(hostResults)); + HIP_CHECK(hipFree(deviceResults)); +} + +// Struct functor tests + +// Simple doubler Functor +struct sDoublerFunctor { + public: + __device__ int operator()(int x) { return x * 2;} +}; + + +// simple sturct doubler functor passed to kernel +__global__ void structDoublerFunctorKernel( + sDoublerFunctor doubler_, + bool* deviceResult) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + int result = doubler_(5); + deviceResult[x] = (result == 10); +} + +void HipFunctorTests::TestForSimpleStructFunctor(void) { + sDoublerFunctor doubler; + bool *deviceResults, *hostResults; + HIP_CHECK(hipMalloc(&deviceResults, BLOCK_DIM_SIZE*sizeof(bool))); + HIP_CHECK(hipHostMalloc(&hostResults, BLOCK_DIM_SIZE*sizeof(bool))); + for (int k = 0; k < BLOCK_DIM_SIZE; ++k) { + // initialize to false, will be set to + // true if the functor is called in device code + hostResults[k] = false; + } + + HIP_CHECK(hipMemcpy(deviceResults, hostResults, BLOCK_DIM_SIZE*sizeof(bool), + hipMemcpyHostToDevice)); + hipLaunchKernelGGL(structDoublerFunctorKernel, dim3(BLOCK_DIM_SIZE), + dim3(THREADS_PER_BLOCK), 0, 0, doubler, deviceResults); + + // Validation part of TestForSimpleStructFunctor + HIP_CHECK(hipMemcpy(hostResults, deviceResults, BLOCK_DIM_SIZE*sizeof(bool), + hipMemcpyDeviceToHost)); + for (int k = 0; k < BLOCK_DIM_SIZE; ++k) + REQUIRE(hostResults[k] == true); + HIP_CHECK(hipHostFree(hostResults)); + HIP_CHECK(hipFree(deviceResults)); +} + +// ptr functor passed to kernel +__global__ void structPtrDoublerFunctorKernel( + sDoublerFunctor *doubler_, + bool* deviceResult) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + int result = (*doubler_)(5); + deviceResult[x] = (result == 10); +} + +void HipFunctorTests::TestForStructObjPtrFunctor(void) { + sDoublerFunctor* ptrdoubler = new sDoublerFunctor[sizeof(int)]; + bool *deviceResults, *hostResults; + HIP_CHECK(hipMalloc(&deviceResults, BLOCK_DIM_SIZE*sizeof(bool))); + HIP_CHECK(hipHostMalloc(&hostResults, BLOCK_DIM_SIZE*sizeof(bool))); + for (int k = 0; k < BLOCK_DIM_SIZE; ++k) { + // initialize to false, will be set to + // true if the functor is called in device code + hostResults[k] = false; + } + + HIP_CHECK(hipMemcpy(deviceResults, hostResults, BLOCK_DIM_SIZE*sizeof(bool), + hipMemcpyHostToDevice)); + hipLaunchKernelGGL(structPtrDoublerFunctorKernel, dim3(BLOCK_DIM_SIZE), + dim3(THREADS_PER_BLOCK), 0, 0, ptrdoubler, deviceResults); + + // Validation part of TestForStructObjPtrFunctor + HIP_CHECK(hipMemcpy(hostResults, deviceResults, BLOCK_DIM_SIZE*sizeof(bool), + hipMemcpyDeviceToHost)); + for (int k = 0; k < BLOCK_DIM_SIZE; ++k) + REQUIRE(hostResults[k] == true); + HIP_CHECK(hipHostFree(hostResults)); + HIP_CHECK(hipFree(deviceResults)); + delete[] ptrdoubler; +} + +struct sCompare { + public: + template< typename T1, typename T2 > + __device__ bool operator()(const T1& v1, const T2& v2) { + return v1 > v2; + } +}; + +// template functor passed to kernel +__global__ void structTemplateFunctorKernel( + sCompare compare_, + bool* deviceResult) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + deviceResult[x] = compare_(2.2, 2.1); + deviceResult[x] = compare_(2, 1); + deviceResult[x] = compare_('b', 'a'); +} + +void HipFunctorTests::TestForStructTemplateFunctor(void) { + sCompare comparefunctor; + bool *deviceResults, *hostResults; + HIP_CHECK(hipMalloc(&deviceResults, BLOCK_DIM_SIZE*sizeof(bool))); + HIP_CHECK(hipHostMalloc(&hostResults, BLOCK_DIM_SIZE*sizeof(bool))); + for (int k = 0; k < BLOCK_DIM_SIZE; ++k) { + // initialize to false, will be set to + // true if the functor is called in device code + hostResults[k] = false; + } + + HIP_CHECK(hipMemcpy(deviceResults, hostResults, BLOCK_DIM_SIZE*sizeof(bool), + hipMemcpyHostToDevice)); + + // pass comparefunctor to hipLaunchKernelGGL + hipLaunchKernelGGL(structTemplateFunctorKernel, dim3(BLOCK_DIM_SIZE), + dim3(THREADS_PER_BLOCK), 0, 0, comparefunctor, deviceResults); + + // Validation part of TestForStructTemplateFunctor + HIP_CHECK(hipMemcpy(hostResults, deviceResults, BLOCK_DIM_SIZE*sizeof(bool), + hipMemcpyDeviceToHost)); + for (int k = 0; k < BLOCK_DIM_SIZE; ++k) + REQUIRE(hostResults[k] == true); + HIP_CHECK(hipHostFree(hostResults)); + HIP_CHECK(hipFree(deviceResults)); +} + +// Doubler calculator struct +struct sDoublerCalculator { + public: + int a, result; + // fucntor contained in class object + DoublerFunctor doubler; +}; + + + +// doubler functor contained in struct passed to kernel +__global__ void DoublerCalculatorFunctorKernel( + sDoublerCalculator doubler_, + bool* deviceResult) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + int result = doubler_.doubler(doubler_.a); + deviceResult[x] = (doubler_.result == result); +} + +void HipFunctorTests::TestForFunctorContainInStructObj(void) { + sDoublerCalculator Doubler; + bool *deviceResults, *hostResults; + HIP_CHECK(hipMalloc(&deviceResults, BLOCK_DIM_SIZE*sizeof(bool))); + HIP_CHECK(hipHostMalloc(&hostResults, BLOCK_DIM_SIZE*sizeof(bool))); + for (int k = 0; k < BLOCK_DIM_SIZE; ++k) { + // initialize to false, will be set to + // true if the functor is called in device code + hostResults[k] = false; + } + + Doubler.a = 5; + Doubler.result = 10; + HIP_CHECK(hipMemcpy(deviceResults, hostResults, BLOCK_DIM_SIZE*sizeof(bool), + hipMemcpyHostToDevice)); + + + // pass comparefunctor to hipLaunchKernelGGL + hipLaunchKernelGGL(DoublerCalculatorFunctorKernel, dim3(BLOCK_DIM_SIZE), + dim3(THREADS_PER_BLOCK), 0, 0, Doubler, deviceResults); + + // Validation part of TestForStructTemplateFunctor + HIP_CHECK(hipMemcpy(hostResults, deviceResults, BLOCK_DIM_SIZE*sizeof(bool), + hipMemcpyDeviceToHost)); + for (int k = 0; k < BLOCK_DIM_SIZE; ++k) + REQUIRE(hostResults[k] == true); + HIP_CHECK(hipHostFree(hostResults)); + HIP_CHECK(hipFree(deviceResults)); +} + +/** +* @addtogroup hipLaunchKernelGGL 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 that a class functor can be passed to hiplaunchparam + * and can be used in kernel. + * - Test that a templated class functor can be passed to hiplaunchparam + * and can be used in kernel. + * - Test that a class functor object ptr can be passed to hiplaunchparam + * and can be used in kernel. + * - Test that a class object containing functor can be passed to hiplaunchparam + * and can be used in kernel + * - Test that a stuct functor can be passed to hiplaunchparam + * and can be used in kernel + * - Test that a stuct functor object ptr can be passed to hiplaunchparam + * and can be used in kernel + * - Test that a templated struct functor can be passed to hiplaunchparam + * and can be used in kernel + * - Test that a struct object containing functor can be passed to hiplaunchparam + * and can be used in kernel + + * Test source + * ------------------------ + * - catch/unit/kernel/hipLaunchParmFunctor.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.5 + */ + +TEST_CASE("Unit_hipLaunchParmFunctor") { + HipFunctorTests FunctorTests; + + SECTION("test for simple class functor") { + FunctorTests.TestForSimpleClassFunctor(); + } + SECTION("test for class objptr functor") { + FunctorTests.TestForClassObjPtrFunctor(); + } + SECTION("test for class templete functor") { + FunctorTests.TestForClassTemplateFunctor(); + } + SECTION("test for simple struct functor") { + FunctorTests.TestForSimpleStructFunctor(); + } + SECTION("test for struct objptr functor") { + FunctorTests.TestForStructObjPtrFunctor(); + } + SECTION("test for struct templete functor") { + FunctorTests.TestForStructTemplateFunctor(); + } + SECTION("test for functor contain in classobj") { + FunctorTests.TestForFunctorContainInClassObj(); + } + SECTION("test for functor contain in structobj") { + FunctorTests.TestForFunctorContainInStructObj(); + } +} From 528764ec78cb99b888e8f891826b57fa879150c0 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Mon, 14 Aug 2023 20:59:45 +0530 Subject: [PATCH 12/30] SWDEV-396085 - [catch2][dtest] Adding test cases for hipHostRegister() to test SVM feature (#324) Change-Id: I72bb3d1cf3410180c98f4629fdad7497698849a2 --- catch/unit/memory/CMakeLists.txt | 7 +- catch/unit/memory/hipHostRegister.cc | 831 ++++++++++++++++++++++- catch/unit/memory/hipHostRegister_exe.cc | 155 +++++ 3 files changed, 958 insertions(+), 35 deletions(-) create mode 100644 catch/unit/memory/hipHostRegister_exe.cc diff --git a/catch/unit/memory/CMakeLists.txt b/catch/unit/memory/CMakeLists.txt index 6f236ac229..fa340863a6 100644 --- a/catch/unit/memory/CMakeLists.txt +++ b/catch/unit/memory/CMakeLists.txt @@ -1,4 +1,4 @@ -# 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 @@ -88,6 +88,11 @@ hip_add_exe_to_target(NAME MemoryTest1 TEST_SRC ${TEST_SRC} TEST_TARGET_NAME build_tests COMMON_SHARED_SRC ${COMMON_SHARED_SRC}) +if(HIP_PLATFORM MATCHES "amd") + set_source_files_properties(hipHostRegister.cc PROPERTIES COMPILE_FLAGS -std=c++17) + add_executable(hipHostRegisterPerf EXCLUDE_FROM_ALL hipHostRegister_exe.cc) +endif() + set(TEST_SRC hipMemcpyFromSymbol.cc hipPtrGetAttribute.cc diff --git a/catch/unit/memory/hipHostRegister.cc b/catch/unit/memory/hipHostRegister.cc index 5e1b10d234..cb62532ae7 100644 --- a/catch/unit/memory/hipHostRegister.cc +++ b/catch/unit/memory/hipHostRegister.cc @@ -1,5 +1,5 @@ /* -Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -20,20 +20,40 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* -This testfile verifies the following scenarios of hipHostRegister API -1. Referencing the hipHostRegister variable from kernel and performing - memset on that variable.This is verified for different datatypes. -2. hipHostRegister and perform hipMemcpy on it. -*/ +/** + * @addtogroup hipHostRegister hipHostRegister + * @{ + * @ingroup MemoryTest + * `hipError_t hipHostRegister (void *hostPtr, size_t sizeBytes, unsigned int flags)` - + * register host memory so it can be accessed from the current device. + */ #include "hip/hip_runtime_api.h" #include #include +#include +#include #include #define OFFSET 128 +#define INITIAL_VAL 1 +#define EXPECTED_VAL 2 +#define ITERATION 100 +#define ADDITIONAL_MEMORY_PERCENT 10 + static constexpr auto LEN{1024 * 1024}; +static constexpr auto LARGE_CHUNK_LEN{100 * LEN}; +static constexpr auto SMALL_CHUNK_LEN{10 * LEN}; + +#if HT_AMD +#define TEST_SKIP(arch, msg) \ + if (std::string::npos == arch.find("xnack+")) {\ + HipTest::HIP_SKIP_TEST(msg);\ + return;\ + } +#else +#define TEST_SKIP(arch, msg) +#endif template __global__ void Inc(T* Ad) { int tx = threadIdx.x + blockIdx.x * blockDim.x; @@ -41,7 +61,8 @@ template __global__ void Inc(T* Ad) { } template -void doMemCopy(size_t numElements, int offset, T* A, T* Bh, T* Bd, bool internalRegister) { +void doMemCopy(size_t numElements, int offset, T* A, T* Bh, T* Bd, + bool internalRegister) { constexpr auto memsetval = 13.0f; A = A + offset; numElements -= offset; @@ -71,18 +92,27 @@ void doMemCopy(size_t numElements, int offset, T* A, T* Bh, T* Bd, bool internal } } -/* -This testcase verifies the hipHostRegister API by -1. Allocating the memory using malloc -2. hipHostRegister that variable -3. Getting the corresponding device pointer of the registered varible -4. Launching kernel and access the device pointer variable -5. performing hipMemset on the device pointer variable -*/ -TEMPLATE_TEST_CASE("Unit_hipHostRegister_ReferenceFromKernelandhipMemset", "", int, float, double) { +/** + * Test Description + * ------------------------ + * - This testcase verifies the hipHostRegister API by + * 1. Allocating the memory using malloc + * 2. hipHostRegister that variable + * 3. Getting the corresponding device pointer of the registered varible + * 4. Launching kernel and access the device pointer variable + * 5. performing hipMemset on the device pointer variable + * Test source + * ------------------------ + * - catch\unit\memory\hipHostRegister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEMPLATE_TEST_CASE("Unit_hipHostRegister_ReferenceFromKernelandhipMemset", "", \ + int, float, double) { size_t sizeBytes{LEN * sizeof(TestType)}; TestType *A, **Ad; - int num_devices; + int num_devices = 0; HIP_CHECK(hipGetDeviceCount(&num_devices)); Ad = new TestType*[num_devices]; A = reinterpret_cast(malloc(sizeBytes)); @@ -118,17 +148,722 @@ TEMPLATE_TEST_CASE("Unit_hipHostRegister_ReferenceFromKernelandhipMemset", "", i delete[] Ad; } -/* -This testcase verifies hipHostRegister API by -performing memcpy on the hipHostRegistered variable. -*/ +/** + * Test Description + * ------------------------ + * - This testcase verifies that the host pointer registered by hipHostRegister API + * is accessible from current device when xnack is on. + * Test source + * ------------------------ + * - catch\unit\memory\hipHostRegister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEMPLATE_TEST_CASE("Unit_hipHostRegister_DirectReferenceFromKernel", "", \ + int, float, double) { + auto flags = GENERATE(hipHostRegisterDefault, hipHostRegisterPortable, + hipHostRegisterMapped); + // Execute the test only if xnack is supported + hipDeviceProp_t prop; + HIP_CHECK(hipGetDeviceProperties(&prop, 0)); + std::string arch = prop.gcnArchName; + TEST_SKIP(arch, "Xnack+ is not supported. Skipping the test ...") + size_t sizeBytes{LEN * sizeof(TestType)}; + TestType *A; + A = reinterpret_cast(malloc(sizeBytes)); + REQUIRE(A != nullptr); + // Initialize buffer with data + TestType val = static_cast(1); + for (int i = 0; i < LEN; i++) { + A[i] = val; + } + HIP_CHECK(hipHostRegister(A, sizeBytes, flags)); + + // Reference the registered device pointer A from inside the kernel: + hipLaunchKernelGGL(Inc, dim3(LEN / 32), dim3(32), 0, 0, A); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipDeviceSynchronize()); + for (int i = 0; i < LEN; i++) { + REQUIRE(A[i] == (val + static_cast(1))); + } + HIP_CHECK(hipHostUnregister(A)); + free(A); +} + +/** + * Test Description + * ------------------------ + * - This testcase verifies that the host pointer registered by hipHostRegister API + is usable from multiple device when xnack is on. + * Test source + * ------------------------ + * - catch\unit\memory\hipHostRegister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEMPLATE_TEST_CASE("Unit_hipHostRegister_DirectReferenceMultGpu", "", \ + int, float, double) { + // 1 refers to doing hipHostRegister once for all devices + // 0 refers to doing hipHostRegister for each device + auto register_once = GENERATE(0, 1); + hipDeviceProp_t prop; + int numDevices = HipTest::getDeviceCount(); + size_t sizeBytes{LEN * sizeof(TestType)}; + TestType *A; + A = reinterpret_cast(malloc(sizeBytes)); + REQUIRE(A != nullptr); + // Register host memory only once for all device + if (register_once == 1) { + HIP_CHECK(hipHostRegister(A, sizeBytes, 0)); + } + // Reference the registered device pointer A from inside all devices: + for (int dev = 0; dev < numDevices; dev++) { + // Initialize buffer with data + TestType val = static_cast(1); + for (int i = 0; i < LEN; i++) { + A[i] = val; + } + HIP_CHECK(hipSetDevice(dev)); + HIP_CHECK(hipGetDeviceProperties(&prop, dev)); + std::string arch = prop.gcnArchName; + TEST_SKIP(arch, "Xnack+ is not supported. Skipping the test ...") + // Register host memory for each device + if (register_once == 0) { + HIP_CHECK(hipHostRegister(A, sizeBytes, 0)); + } + hipLaunchKernelGGL(Inc, dim3(LEN / 32), dim3(32), 0, 0, A); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipDeviceSynchronize()); + for (int i = 0; i < LEN; i++) { + REQUIRE(A[i] == (val + static_cast(1))); + } + if (register_once == 0) { + HIP_CHECK(hipHostUnregister(A)); + } + } + if (register_once == 1) { + HIP_CHECK(hipHostUnregister(A)); + } + free(A); +} + +/** + * Test Description + * ------------------------ + * - This testcase verifies functionality when same host pointer is repeatedly + * registered and unregistered. + * Test source + * ------------------------ + * - catch\unit\memory\hipHostRegister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipHostRegister_SameChunkRepeat") { + // Execute the test only if xnack is supported + hipDeviceProp_t prop; + HIP_CHECK(hipGetDeviceProperties(&prop, 0)); + std::string arch = prop.gcnArchName; + TEST_SKIP(arch, "Xnack+ is not supported. Skipping the test ...") + size_t sizeBytes{LEN * sizeof(uint8_t)}; + uint8_t *A; + A = reinterpret_cast(malloc(sizeBytes)); + REQUIRE(A != nullptr); + for (int iter = 0; iter < ITERATION; iter++) { + // Initialize buffer with data + memset(A, INITIAL_VAL, sizeBytes); + HIP_CHECK(hipHostRegister(A, sizeBytes, 0)); + + // Reference the registered device pointer A from inside the kernel: + hipLaunchKernelGGL(Inc, dim3(LEN / 32), dim3(32), 0, 0, A); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipDeviceSynchronize()); + for (int i = 0; i < LEN; i++) { + REQUIRE(A[i] == EXPECTED_VAL); + } + HIP_CHECK(hipHostUnregister(A)); + } + free(A); +} + +/** + * Test Description + * ------------------------ + * - Allocate a large chunk of host memory. Divide the memory into smaller chunks. + * Register each smaller chunk in one attempt. Access all the chunks in Kernel. Verify + * results. + * Test source + * ------------------------ + * - catch\unit\memory\hipHostRegister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipHostRegister_Chunks_SingleAttempt") { + // Execute the test only if xnack is supported + hipDeviceProp_t prop; + HIP_CHECK(hipGetDeviceProperties(&prop, 0)); + std::string arch = prop.gcnArchName; + TEST_SKIP(arch, "Xnack+ is not supported. Skipping the test ...") + size_t sizeBytes{LARGE_CHUNK_LEN * sizeof(uint8_t)}; + size_t sizeBytesChunk{SMALL_CHUNK_LEN * sizeof(uint8_t)}; + uint8_t *A; + A = reinterpret_cast(malloc(sizeBytes)); + REQUIRE(A != nullptr); + // Initialize buffer with data + memset(A, INITIAL_VAL, sizeBytes); + uint8_t *arrPtr[LARGE_CHUNK_LEN / SMALL_CHUNK_LEN]; + for (int cnt = 0; cnt < (LARGE_CHUNK_LEN / SMALL_CHUNK_LEN); cnt++) { + arrPtr[cnt] = A + (cnt*sizeBytesChunk); + HIP_CHECK(hipHostRegister(arrPtr[cnt], sizeBytesChunk, 0)); + } + // Reference each registered chunk inside the kernel: + for (int cnt = 0; cnt < (LARGE_CHUNK_LEN / SMALL_CHUNK_LEN); cnt++) { + uint8_t *ptrA = arrPtr[cnt]; + hipLaunchKernelGGL(Inc, dim3(SMALL_CHUNK_LEN / 32), dim3(32), 0, 0, ptrA); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipDeviceSynchronize()); + for (int i = 0; i < SMALL_CHUNK_LEN; i++) { + REQUIRE(ptrA[i] == EXPECTED_VAL); + } + } + for (int cnt = 0; cnt < (LARGE_CHUNK_LEN / SMALL_CHUNK_LEN); cnt++) { + HIP_CHECK(hipHostUnregister(arrPtr[cnt])); + } + free(A); +} + +/** + * Test Description + * ------------------------ + * - Allocate a large chunk of host memory. Divide the memory into smaller chunks. + * Register each smaller chunk, access the chunk in Kernel and unregister the chunk. + * Verify results. Perform this series of operation in a round robin manner for + * all chunks. + * Test source + * ------------------------ + * - catch\unit\memory\hipHostRegister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipHostRegister_Chunks_RoundRobin") { + // Execute the test only if xnack is supported + hipDeviceProp_t prop; + HIP_CHECK(hipGetDeviceProperties(&prop, 0)); + std::string arch = prop.gcnArchName; + TEST_SKIP(arch, "Xnack+ is not supported. Skipping the test ...") + size_t sizeBytes{LARGE_CHUNK_LEN * sizeof(uint8_t)}; + size_t sizeBytesChunk{SMALL_CHUNK_LEN * sizeof(uint8_t)}; + uint8_t *A; + A = reinterpret_cast(malloc(sizeBytes)); + REQUIRE(A != nullptr); + // Initialize buffer with data + memset(A, INITIAL_VAL, sizeBytes); + for (int cnt = 0; cnt < (LARGE_CHUNK_LEN / SMALL_CHUNK_LEN); cnt++) { + uint8_t *ptrA = A + (cnt*sizeBytesChunk); + HIP_CHECK(hipHostRegister(ptrA, sizeBytesChunk, 0)); + hipLaunchKernelGGL(Inc, dim3(SMALL_CHUNK_LEN / 32), dim3(32), 0, 0, ptrA); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipDeviceSynchronize()); + for (int i = 0; i < SMALL_CHUNK_LEN; i++) { + REQUIRE(ptrA[i] == EXPECTED_VAL); + } + HIP_CHECK(hipHostUnregister(ptrA)); + } + free(A); +} + +/** + * Test Description + * ------------------------ + * - This testcase verifies that the host pointer registered by hipHostRegister API + * can be memset using hipMemset. + * Test source + * ------------------------ + * - catch\unit\memory\hipHostRegister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipHostRegister_Perform_hipMemset") { + // Execute the test only if xnack is supported + hipDeviceProp_t prop; + HIP_CHECK(hipGetDeviceProperties(&prop, 0)); + std::string arch = prop.gcnArchName; + TEST_SKIP(arch, "Xnack+ is not supported. Skipping the test ...") + size_t sizeBytes{LEN * sizeof(uint8_t)}; + uint8_t *A; + A = reinterpret_cast(malloc(sizeBytes)); + REQUIRE(A != nullptr); + // Register the host pointer + HIP_CHECK(hipHostRegister(A, sizeBytes, 0)); + // Memset the registered pointer + HIP_CHECK(hipMemset(A, INITIAL_VAL, sizeBytes)); + // Reference the registered device pointer A from inside the kernel: + hipLaunchKernelGGL(Inc, dim3(LEN / 32), dim3(32), 0, 0, A); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipDeviceSynchronize()); + for (int i = 0; i < LEN; i++) { + REQUIRE(A[i] == EXPECTED_VAL); + } + HIP_CHECK(hipHostUnregister(A)); + free(A); +} + +/** + * Test Description + * ------------------------ + * - This testcase verifies that the host pointer registered by hipHostRegister API + * can be used with hipMemcpy. + * Test source + * ------------------------ + * - catch\unit\memory\hipHostRegister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipHostRegister_Perform_hipMemcpy") { + // Execute the test only if xnack is supported + hipDeviceProp_t prop; + HIP_CHECK(hipGetDeviceProperties(&prop, 0)); + std::string arch = prop.gcnArchName; + TEST_SKIP(arch, "Xnack+ is not supported. Skipping the test ...") + size_t sizeBytes{LEN * sizeof(uint8_t)}; + uint8_t *A, *B; + A = reinterpret_cast(malloc(sizeBytes)); + REQUIRE(A != nullptr); + B = reinterpret_cast(malloc(sizeBytes)); + REQUIRE(B != nullptr); + memset(B, INITIAL_VAL, sizeBytes); + // Register the host pointer + HIP_CHECK(hipHostRegister(A, sizeBytes, 0)); + // Memcpy from B to A + HIP_CHECK(hipMemcpy(A, B, sizeBytes, hipMemcpyDefault)); + // Reference the registered device pointer A from inside the kernel: + hipLaunchKernelGGL(Inc, dim3(LEN / 32), dim3(32), 0, 0, A); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipDeviceSynchronize()); + // Verify if we can Memcpy from A to B + HIP_CHECK(hipMemcpy(B, A, sizeBytes, hipMemcpyDefault)); + for (int i = 0; i < LEN; i++) { + REQUIRE(B[i] == EXPECTED_VAL); + } + HIP_CHECK(hipHostUnregister(A)); + free(A); + free(B); +} + +/** + * Test Description + * ------------------------ + * - Oversubscription: This testcase allocates host memory of size > total + * GPU memory. Register the memory and try accessing it from kernel. Verify + * the behaviour. + * Test source + * ------------------------ + * - catch\unit\memory\hipHostRegister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipHostRegister_Oversubscription") { + // Execute the test only if xnack is supported + hipDeviceProp_t prop; + HIP_CHECK(hipGetDeviceProperties(&prop, 0)); + std::string arch = prop.gcnArchName; + TEST_SKIP(arch, "Xnack+ is not supported. Skipping the test ...") + size_t maxGpuMem = 0, availableMem = 0; + // Get available GPU memory and total GPU memory + HIP_CHECK(hipMemGetInfo(&availableMem, &maxGpuMem)); + size_t allocsize = maxGpuMem + + ((maxGpuMem*ADDITIONAL_MEMORY_PERCENT)/100); + // Get free host In bytes + size_t hostMemFree = HipTest::getMemoryAmount() * 1024 * 1024; + // Ensure that allocsize < hostMemFree + if (allocsize >= hostMemFree) { + HipTest::HIP_SKIP_TEST("Available Host Memory is not sufficient ..."); + return; + } + uint8_t* A = reinterpret_cast(malloc(allocsize)); + REQUIRE(A != nullptr); + size_t used_size = LEN; + // Inititalize only the first used_size bytes chunk + memset(A, INITIAL_VAL, used_size); + // Inititalize only the last used_size bytes chunk + memset((A + allocsize - used_size), INITIAL_VAL, used_size); + // Register the entire host memory chunk + HIP_CHECK(hipHostRegister(A, allocsize, 0)); + // Reference only the first used_size bytes + hipLaunchKernelGGL(Inc, dim3(used_size / 32), dim3(32), 0, 0, A); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipDeviceSynchronize()); + for (int i = 0; i < used_size; i++) { + REQUIRE(A[i] == EXPECTED_VAL); + } + // Reference only the last used_size bytes chunk + uint8_t* B = (A + allocsize - used_size); + hipLaunchKernelGGL(Inc, dim3(used_size / 32), dim3(32), 0, 0, B); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipDeviceSynchronize()); + for (int i = 0; i < used_size; i++) { + REQUIRE(B[i] == EXPECTED_VAL); + } + HIP_CHECK(hipHostUnregister(A)); + free(A); +} + +/** + * Test Description + * ------------------------ + * - This testcase verifies that the host pointer registered by hipHostRegister API + * can be used with Async APIs (hipMemsetAsync, hipMemcpyAsync and kernel) on a user + * defined stream. + * Test source + * ------------------------ + * - catch\unit\memory\hipHostRegister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipHostRegister_AsyncApis") { + // Execute the test only if xnack is supported + hipDeviceProp_t prop; + HIP_CHECK(hipGetDeviceProperties(&prop, 0)); + std::string arch = prop.gcnArchName; + bool useRegPtrInDev = false; +#if HT_AMD + if (std::string::npos == arch.find("xnack+")) { + useRegPtrInDev = false; + } else { + useRegPtrInDev = true; + } +#else + useRegPtrInDev = GENERATE(true, false); +#endif + size_t sizeBytes{LEN * sizeof(uint32_t)}; + uint32_t *A, *B, *dPtr; + A = reinterpret_cast(malloc(sizeBytes)); + REQUIRE(A != nullptr); + B = reinterpret_cast(malloc(sizeBytes)); + REQUIRE(B != nullptr); + for (int i = 0; i < LEN; i++) { + B[i] = i; + } + // Register the host pointer + HIP_CHECK(hipHostRegister(A, sizeBytes, 0)); + if (useRegPtrInDev) { + dPtr = A; + } else { + HIP_CHECK(hipHostGetDevicePointer(reinterpret_cast(&dPtr), A, 0)); + } + hipStream_t strm{nullptr}; + HIP_CHECK(hipStreamCreate(&strm)); + // Memcpy from B to A + HIP_CHECK(hipMemcpyAsync(dPtr, B, sizeBytes, hipMemcpyHostToDevice, strm)); + // Reference the registered device pointer A from inside the kernel: + hipLaunchKernelGGL(Inc, dim3(LEN / 32), dim3(32), 0, strm, dPtr); + HIP_CHECK(hipMemcpyAsync(B, dPtr, sizeBytes, hipMemcpyDeviceToHost, strm)); + HIP_CHECK(hipStreamSynchronize(strm)); + for (int i = 0; i < LEN; i++) { + REQUIRE(B[i] == (i + 1)); + } + HIP_CHECK(hipStreamDestroy(strm)); + HIP_CHECK(hipHostUnregister(A)); + free(A); + free(B); +} + +/** + * Test Description + * ------------------------ + * - This testcase verifies the behaviour of host registered memory when + * used with hipGraph. + * Test source + * ------------------------ + * - catch\unit\memory\hipHostRegister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipHostRegister_Graphs") { + // Execute the test only if xnack is supported + hipDeviceProp_t prop; + HIP_CHECK(hipGetDeviceProperties(&prop, 0)); + std::string arch = prop.gcnArchName; + bool useRegPtrInDev = false; +#if HT_AMD + if (std::string::npos == arch.find("xnack+")) { + useRegPtrInDev = false; + } else { + useRegPtrInDev = true; + } +#else + useRegPtrInDev = GENERATE(true, false); +#endif + size_t sizeBytes{LEN * sizeof(uint32_t)}; + uint32_t *A, *B, *dPtr; + A = reinterpret_cast(malloc(sizeBytes)); + REQUIRE(A != nullptr); + B = reinterpret_cast(malloc(sizeBytes)); + REQUIRE(B != nullptr); + for (int i = 0; i < LEN; i++) { + B[i] = i; + } + // Register the host pointer + HIP_CHECK(hipHostRegister(A, sizeBytes, 0)); + if (useRegPtrInDev) { + dPtr = A; + } else { + HIP_CHECK(hipHostGetDevicePointer(reinterpret_cast(&dPtr), A, 0)); + } + // Use dPtr in graphs + hipStream_t streamForGraph; + HIP_CHECK(hipStreamCreate(&streamForGraph)); + hipGraph_t graph; + HIP_CHECK(hipGraphCreate(&graph, 0)); + hipGraphNode_t memcpyH2D, memcpyD2H; + hipGraphNode_t kernel_vecInc; + void* kernelArgs1[] = {&dPtr}; + hipKernelNodeParams kernelNodeParams{}; + kernelNodeParams.func = reinterpret_cast(Inc); + kernelNodeParams.gridDim = dim3(LEN / 32); + kernelNodeParams.blockDim = dim3(32); + kernelNodeParams.sharedMemBytes = 0; + kernelNodeParams.kernelParams = reinterpret_cast(kernelArgs1); + kernelNodeParams.extra = nullptr; + HIP_CHECK(hipGraphAddKernelNode(&kernel_vecInc, graph, nullptr, 0, + &kernelNodeParams)); + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D, graph, nullptr, 0, dPtr, B, + sizeBytes, hipMemcpyHostToDevice)); + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H, graph, nullptr, 0, B, dPtr, + sizeBytes, hipMemcpyDeviceToHost)); + // Create dependencies + HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D, &kernel_vecInc, 1)); + HIP_CHECK(hipGraphAddDependencies(graph, &kernel_vecInc, &memcpyD2H, 1)); + // Instantiate and execute Graph + hipGraphExec_t graphExec; + HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph)); + HIP_CHECK(hipStreamSynchronize(streamForGraph)); + // Verify Result + for (int i = 0; i < LEN; i++) { + REQUIRE(B[i] == (i + 1)); + } + HIP_CHECK(hipGraphExecDestroy(graphExec)); + HIP_CHECK(hipGraphDestroy(graph)); + HIP_CHECK(hipStreamDestroy(streamForGraph)); + HIP_CHECK(hipHostUnregister(A)); + free(A); + free(B); +} + +#if HT_AMD +/** + * Test Description + * ------------------------ + * - This testcase measures performance when same memory chunk is repeatedly + * registered and unregistered. + * Test source + * ------------------------ + * - catch\unit\memory\hipHostRegister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipHostRegister_RegUnreg_Perf_SameChunk") { + // Execute the test only if xnack is supported + hipDeviceProp_t prop; + hipDevice_t device; + HIP_CHECK(hipDeviceGet(&device, 0)); + HIP_CHECK(hipGetDeviceProperties(&prop, device)); + std::string arch = prop.gcnArchName; + if (std::string::npos == arch.find("xnack+")) { + HipTest::HIP_SKIP_TEST("Xnack+ is not supported. Skipping the test ..."); + return; + } + hip::SpawnProc proc("hipHostRegisterPerf", true); + REQUIRE(proc.run("svm_enable 1") == 0); + float perf_svm_enable = std::stof(proc.getOutput()); + INFO("perf_svm_enable: " << perf_svm_enable); + REQUIRE(proc.run("svm_disable 1") == 0); + float perf_svm_disable = std::stof(proc.getOutput()); + INFO("perf_svm_disable: " << perf_svm_disable); + REQUIRE(perf_svm_enable <= perf_svm_disable); +} + +/** + * Test Description + * ------------------------ + * - This testcase measures performance when different memory chunks + * are repeatedly registered and unregistered. + * Test source + * ------------------------ + * - catch\unit\memory\hipHostRegister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipHostRegister_RegUnreg_Perf_DiffChunk") { + // Execute the test only if xnack is supported + hipDeviceProp_t prop; + hipDevice_t device; + HIP_CHECK(hipDeviceGet(&device, 0)); + HIP_CHECK(hipGetDeviceProperties(&prop, device)); + std::string arch = prop.gcnArchName; + if (std::string::npos == arch.find("xnack+")) { + HipTest::HIP_SKIP_TEST("Xnack+ is not supported. Skipping the test ..."); + return; + } + hip::SpawnProc proc("hipHostRegisterPerf", true); + REQUIRE(proc.run("svm_enable 0") == 0); + float perf_svm_enable = std::stof(proc.getOutput()); + INFO("perf_svm_enable: " << perf_svm_enable); + REQUIRE(proc.run("svm_disable 0") == 0); + float perf_svm_disable = std::stof(proc.getOutput()); + INFO("perf_svm_disable: " << perf_svm_disable); + REQUIRE(perf_svm_enable <= perf_svm_disable); +} + +/** + * Test Description + * ------------------------ + * - This testcase measures performance when same memory chunk is repeatedly + * registered and unregistered on multiple GPUs. + * Test source + * ------------------------ + * - catch\unit\memory\hipHostRegister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipHostRegister_RegUnreg_Perf_SameChunk_MGPU") { + // Execute the test only if xnack is supported + hipDeviceProp_t prop; + hipDevice_t device; + HIP_CHECK(hipDeviceGet(&device, 0)); + HIP_CHECK(hipGetDeviceProperties(&prop, device)); + std::string arch = prop.gcnArchName; + if (std::string::npos == arch.find("xnack+")) { + HipTest::HIP_SKIP_TEST("Xnack+ is not supported. Skipping the test ..."); + return; + } + int dev_count = HipTest::getDeviceCount(); + if (dev_count < 2) { + HipTest::HIP_SKIP_TEST("Only 1 GPU available. Skipping this test ..."); + return; + } + hip::SpawnProc proc("hipHostRegisterPerf", true); + REQUIRE(proc.run("svm_enable 2") == 0); + float perf_svm_enable = std::stof(proc.getOutput()); + INFO("perf_svm_enable: " << perf_svm_enable); + REQUIRE(proc.run("svm_disable 2") == 0); + float perf_svm_disable = std::stof(proc.getOutput()); + INFO("perf_svm_disable: " << perf_svm_disable); + REQUIRE(perf_svm_enable <= perf_svm_disable); +} + +/** + * Test Description + * ------------------------ + * - This testcase verifies whether hipMemAdvise can be used with + * host memory registered with hipHostRegister. + * registered and unregistered. + * Test source + * ------------------------ + * - catch\unit\memory\hipHostRegister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.6 + */ +TEST_CASE("Unit_hipHostRegister_MemAdvise_SetGet") { + // Execute the test only if xnack is supported + hipDeviceProp_t prop; + HIP_CHECK(hipGetDeviceProperties(&prop, 0)); + std::string arch = prop.gcnArchName; + if ((std::string::npos == arch.find("xnack+")) || + (prop.concurrentManagedAccess == 0)) { + const char *msg = "Xnack/ConcurrentAccess not supported. Skipping test"; + HipTest::HIP_SKIP_TEST(msg); + return; + } + int numDevices = HipTest::getDeviceCount(); + size_t sizeBytes{LEN * sizeof(uint8_t)}; + uint8_t *A; + A = reinterpret_cast(malloc(sizeBytes)); + REQUIRE(A != nullptr); + memset(A, INITIAL_VAL, sizeBytes); + HIP_CHECK(hipHostRegister(A, sizeBytes, 0)); + int out = 0; + SECTION("Attribute = hipMemAdviseSetReadMostly") { + HIP_CHECK(hipMemAdvise(A, sizeBytes, hipMemAdviseSetReadMostly, 0)); + HIP_CHECK(hipMemRangeGetAttribute(&out, 4, hipMemRangeAttributeReadMostly, + A, sizeBytes)); + REQUIRE(out == 1); + HIP_CHECK(hipMemAdvise(A, sizeBytes, hipMemAdviseUnsetReadMostly, 0)); + HIP_CHECK(hipMemRangeGetAttribute(&out, 4, hipMemRangeAttributeReadMostly, + A, sizeBytes)); + REQUIRE(out == 0); + } + SECTION("Attribute = hipMemAdviseSetPreferredLocation") { + HIP_CHECK(hipMemAdvise(A, sizeBytes, + hipMemAdviseSetPreferredLocation, hipCpuDeviceId)); + HIP_CHECK(hipMemRangeGetAttribute(&out, sizeof(int), + hipMemRangeAttributePreferredLocation, A, sizeBytes)); + REQUIRE(out == hipCpuDeviceId); + for (int dev = 0; dev < numDevices; dev++) { + HIP_CHECK(hipMemAdvise(A, sizeBytes, + hipMemAdviseSetPreferredLocation, dev)); + HIP_CHECK(hipMemRangeGetAttribute(&out, sizeof(int), + hipMemRangeAttributePreferredLocation, A, sizeBytes)); + REQUIRE(out == dev); + } + HIP_CHECK(hipMemAdvise(A, sizeBytes, + hipMemAdviseUnsetPreferredLocation, 0)); + HIP_CHECK(hipMemRangeGetAttribute(&out, sizeof(int), + hipMemRangeAttributePreferredLocation, A, sizeBytes)); + REQUIRE(out == hipInvalidDeviceId); + } + SECTION("Attribute = hipMemAdviseSetAccessedBy") { + size_t size = numDevices*sizeof(int); + int *chkOut = reinterpret_cast(malloc(size)); + HIP_CHECK(hipMemAdvise(A, sizeBytes, + hipMemAdviseSetAccessedBy, hipCpuDeviceId)); + for (int dev = 0; dev < numDevices; dev++) { + HIP_CHECK(hipMemAdvise(A, sizeBytes, + hipMemAdviseSetAccessedBy, dev)); + } + HIP_CHECK(hipMemRangeGetAttribute(chkOut, size, + hipMemRangeAttributeAccessedBy, A, sizeBytes)); + for (int dev = 0; dev < numDevices; dev++) { + REQUIRE(chkOut[dev] == dev); + } + free(chkOut); + } + HIP_CHECK(hipHostUnregister(A)); + free(A); +} +#endif +/** + * Test Description + * ------------------------ + * - This testcase verifies hipHostRegister API by performing memcpy + * on the hipHostRegistered variable. + * Test source + * ------------------------ + * - catch\unit\memory\hipHostRegister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipHostRegister_Memcpy", "", int, float, double) { // 1 refers to hipHostRegister // 0 refers to malloc auto mem_type = GENERATE(0, 1); HIP_CHECK(hipSetDevice(0)); - size_t sizeBytes = LEN * sizeof(TestType); TestType* A = reinterpret_cast(malloc(sizeBytes)); @@ -161,6 +896,17 @@ template __global__ void fill_kernel(T* dataPtr, T value) { dataPtr[tid] = value; } +/** + * Test Description + * ------------------------ + * - This testcase verifies all the supported flags of hipHostRegister. + * Test source + * ------------------------ + * - catch\unit\memory\hipHostRegister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipHostRegister_Flags", "", int, float, double) { size_t sizeBytes = 1 * sizeof(TestType); TestType* hostPtr = reinterpret_cast(malloc(sizeBytes)); @@ -171,25 +917,40 @@ TEMPLATE_TEST_CASE("Unit_hipHostRegister_Flags", "", int, float, double) { bool valid; }; - /* EXSWCPHIPT-29 - 0x08 is hipHostRegisterReadOnly which currently doesn't have a definition in the headers */ - /* hipHostRegisterIoMemory is a valid flag but requires access to I/O mapped memory to be tested */ - FlagType flags = GENERATE( - FlagType{hipHostRegisterDefault, true}, FlagType{hipHostRegisterPortable, true}, - FlagType{0x08, true}, FlagType{hipHostRegisterPortable | hipHostRegisterMapped, true}, - FlagType{hipHostRegisterPortable | hipHostRegisterMapped | 0x08, true}, FlagType{0xF0, false}, - FlagType{0xFFF2, false}, FlagType{0xFFFFFFFF, false}); + /* EXSWCPHIPT-29 - 0x08 is hipHostRegisterReadOnly which currently doesn't + have a definition in the headers */ + /* hipHostRegisterIoMemory is a valid flag but requires access to I/O mapped + memory to be tested */ + FlagType flags = GENERATE(FlagType{hipHostRegisterDefault, true}, + FlagType{hipHostRegisterPortable, true}, + FlagType{0x08, true}, + FlagType{hipHostRegisterPortable | hipHostRegisterMapped, true}, + FlagType{hipHostRegisterPortable | hipHostRegisterMapped | 0x08, true}, + FlagType{0xF0, false}, + FlagType{0xFFF2, false}, FlagType{0xFFFFFFFF, false}); INFO("Testing hipHostRegister flag: " << flags.value); if (flags.valid) { HIP_CHECK(hipHostRegister(hostPtr, sizeBytes, flags.value)); HIP_CHECK(hipHostUnregister(hostPtr)); } else { - HIP_CHECK_ERROR(hipHostRegister(hostPtr, sizeBytes, flags.value), hipErrorInvalidValue); + HIP_CHECK_ERROR(hipHostRegister(hostPtr, sizeBytes, flags.value), + hipErrorInvalidValue); } - free(hostPtr); } +/** + * Test Description + * ------------------------ + * - These negative tests checks invalid parameter values. + * Test source + * ------------------------ + * - catch\unit\memory\hipHostRegister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipHostRegister_Negative", "", int, float, double) { TestType* hostPtr = nullptr; @@ -205,12 +966,14 @@ TEMPLATE_TEST_CASE("Unit_hipHostRegister_Negative", "", int, float, double) { size_t devMemAvail{0}, devMemFree{0}; HIP_CHECK(hipMemGetInfo(&devMemFree, &devMemAvail)); - auto hostMemFree = HipTest::getMemoryAmount() /* In MB */ * 1024 * 1024; // In bytes + auto hostMemFree = + HipTest::getMemoryAmount() /* In MB */ * 1024 * 1024; // In bytes REQUIRE(devMemFree > 0); REQUIRE(devMemAvail > 0); REQUIRE(hostMemFree > 0); - size_t memFree = (std::max)(devMemFree, hostMemFree); // which is the limiter cpu or gpu + // which is the limiter cpu or gpu + size_t memFree = (std::max)(devMemFree, hostMemFree); SECTION("hipHostRegister Negative Test - invalid memory size") { HIP_CHECK_ERROR(hipHostRegister(hostPtr, memFree, 0), hipErrorInvalidValue); diff --git a/catch/unit/memory/hipHostRegister_exe.cc b/catch/unit/memory/hipHostRegister_exe.cc new file mode 100644 index 0000000000..40c42a82bb --- /dev/null +++ b/catch/unit/memory/hipHostRegister_exe.cc @@ -0,0 +1,155 @@ +/* +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 +#include +#include // NOLINT +#include "hip/hip_runtime_api.h" + +#define ITERATION 1000 +#define SIZE (64*1024*1024) +#define ARRAY_SIZE 20 + +static bool UNSETENV(std::string var) { + int result = -1; +#ifdef __unix__ + result = unsetenv(var.c_str()); +#else + result = _putenv((var + '=').c_str()); +#endif + return (result == 0) ? true: false; +} + +static bool SETENV(std::string var, std::string value, int overwrite) { + int result = -1; +#ifdef __unix__ + result = setenv(var.c_str(), value.c_str(), overwrite); +#else + result = _putenv((var + '=' + value).c_str()); +#endif + return (result == 0) ? true: false; +} + +/** + Expects 2 command line arg, first command is flag svm_enable = 1/0 + and second command is test number: 0 = Register/Unregister different + chunks of host memory, 1 = Register/Unregister the same chunk of host + memory repeatedly, 2 = Register/Unregister the same chunk of host + memory repeatedly on multiple GPUs. +*/ +int main(int argc, char** argv) { + if (argc != 3) { + std::cerr << "Invalid number of args passed.\n" + << "argc : " << argc << std::endl; + return -1; + } + std::string env_flag = argv[1]; + int test = std::stoi(argv[2]); + // disable SVM feature using HSA_USE_SVM=0 env from shell + UNSETENV("HSA_USE_SVM"); + if (env_flag == "svm_enable") { + SETENV("HSA_USE_SVM", "1", 1); + } else { + SETENV("HSA_USE_SVM", "0", 1); + } + if (test == 0) { + uint8_t *A[ARRAY_SIZE]; + for (int i = 0; i < ARRAY_SIZE; i++) { + A[i] = reinterpret_cast(malloc(SIZE)); + if (A[i] == nullptr) { + return -1; + } + } + auto t1 = std::chrono::high_resolution_clock::now(); + for (int count = 0; count < ITERATION; count++) { + // Register the host pointer + if (hipSuccess != hipHostRegister(A[count%ARRAY_SIZE], SIZE, 0)) { + return -1; + } + // Unregister the host pointer + if (hipSuccess != hipHostUnregister(A[count%ARRAY_SIZE])) { + return -1; + } + } + auto t2 = std::chrono::high_resolution_clock::now(); + for (int i = 0; i < ARRAY_SIZE; i++) { + free(A[i]); + } + std::chrono::duration fp_ms = t2 - t1; + std::cout << fp_ms.count() << std::endl; + } else if (test == 1) { + uint8_t *A; + A = reinterpret_cast(malloc(SIZE)); + if (A == nullptr) { + return -1; + } + auto t1 = std::chrono::high_resolution_clock::now(); + for (int count = 0; count < ITERATION; count++) { + // Register the host pointer + if (hipSuccess != hipHostRegister(A, SIZE, 0)) { + return -1; + } + // Unregister the host pointer + if (hipSuccess != hipHostUnregister(A)) { + return -1; + } + } + auto t2 = std::chrono::high_resolution_clock::now(); + free(A); + std::chrono::duration fp_ms = t2 - t1; + std::cout << fp_ms.count() << std::endl; + } else if (test == 2) { + uint8_t *A; + A = reinterpret_cast(malloc(SIZE)); + if (A == nullptr) { + return -1; + } + int dev_count = 0; + if (hipSuccess != hipGetDeviceCount(&dev_count)) { + return -1; + } + auto t1 = std::chrono::high_resolution_clock::now(); + for (int dev = 0; dev < dev_count; dev++) { + if (hipSuccess != hipSetDevice(dev)) { + return -1; + } + for (int count = 0; count < ITERATION; count++) { + // Register the host pointer + if (hipSuccess != hipHostRegister(A, SIZE, 0)) { + return -1; + } + // Unregister the host pointer + if (hipSuccess != hipHostUnregister(A)) { + return -1; + } + } + } + auto t2 = std::chrono::high_resolution_clock::now(); + free(A); + std::chrono::duration fp_ms = t2 - t1; + std::cout << fp_ms.count() << std::endl; + } else { + // Undefined test + } + UNSETENV("HSA_USE_SVM"); + return 0; +} From b2041d42d89b5466d84ccc1b2a59eae067cf884a Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Mon, 14 Aug 2023 20:59:59 +0530 Subject: [PATCH 13/30] SWDEV-396687 - [catch2][dtest] mixing manual node adding in combination with Begin/End capture based on hipGraph apis (#326) Change-Id: Ife7de38956274895d2370b7c9032cf17eef287bc --- catch/unit/graph/CMakeLists.txt | 1 + .../unit/graph/hipGraphAddNodeBeginCapture.cc | 950 ++++++++++++++++++ 2 files changed, 951 insertions(+) create mode 100644 catch/unit/graph/hipGraphAddNodeBeginCapture.cc diff --git a/catch/unit/graph/CMakeLists.txt b/catch/unit/graph/CMakeLists.txt index 6d8e5e45d1..a47bb00387 100644 --- a/catch/unit/graph/CMakeLists.txt +++ b/catch/unit/graph/CMakeLists.txt @@ -126,6 +126,7 @@ set(TEST_SRC hipGraphExecDestroy.cc hipGraphUpload.cc hipGraphKernelNodeCopyAttributes.cc + hipGraphAddNodeBeginCapture.cc hipGraphCycle.cc hipGraphKernelNodeGetAttribute.cc hipGraphKernelNodeSetAttribute.cc) diff --git a/catch/unit/graph/hipGraphAddNodeBeginCapture.cc b/catch/unit/graph/hipGraphAddNodeBeginCapture.cc new file mode 100644 index 0000000000..80bf52371a --- /dev/null +++ b/catch/unit/graph/hipGraphAddNodeBeginCapture.cc @@ -0,0 +1,950 @@ +/* +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 +#include +#include + +#define SIZE (1024 * 1024) +static size_t Nbytes = SIZE * sizeof(int); + +__device__ int globalOut[SIZE]; + +/** +* @addtogroup hipStreamBeginCapture hipStreamBeginCapture +* @{ +* @ingroup GraphTest +* `hipStreamBeginCapture(hipStream_t stream, hipStreamCaptureMode mode)` - +* Returns the last error from a runtime call. +*/ + +static void verifyArrayMemset(int *A_h, int val) { + int expected_val = val | (val << 8) | (val << 16) | (val << 24); + for (size_t i = 0; i < SIZE; i++) { + if (A_h[i] != expected_val) { + INFO("Memset Validation failed at i " << i << " A_h[i] "<< A_h[i]); + REQUIRE(false); + } + } +} + +__device__ __host__ static void callbackFunc(void *A_h) { + int *A = reinterpret_cast(A_h); + for (int i = 0; i < SIZE; i++) { + A[i] = i + i%2; + } +} + +__global__ static void kCallbackFunc(void *A_h) { + callbackFunc(A_h); +} + +static void verifyCallbackFunc(int *A_h) { + for (size_t i = 0; i < SIZE; i++) { + if (A_h[i] != static_cast(i + i%2)) { + INFO("CallBack Validation failed i " << i << " A_h[i] "<< A_h[i]); + REQUIRE(false); + } + } +} + +__global__ static void addGpuKernel(int *i_d) { + *i_d = *i_d + 1; +} + +static void CpuCallback(void *args) { + // do nothing function +} + +/** +* Test Description +* ------------------------ +*  - Verify hipStreamBeginCapture, hipStreamEndCapture status with +* hipGraphAddHostNode api call. +* Test source +* ------------------------ +*  - unit/graph/hipGraphAddNodeBeginCapture.cc +* Test requirements +* ------------------------ +*  - HIP_VERSION >= 5.6 +*/ + +TEST_CASE("Unit_hipStreamBeginCapture_with_hipGraphAddHostNode") { + hipGraph_t graph; + hipGraphExec_t graphExec; + hipGraphNode_t cpuGraphNode; + int *i_d; + HIP_CHECK(hipMalloc(&i_d, sizeof(int))); + REQUIRE(i_d != nullptr); + + hipStream_t stream; + HIP_CHECK(hipStreamCreateWithFlags(&stream, hipStreamNonBlocking)); + HIP_CHECK(hipStreamBeginCapture(stream, hipStreamCaptureModeThreadLocal)); + HIP_CHECK(hipGraphCreate(&graph, 0)); + + hipHostNodeParams p = {0, 0}; + p.fn = CpuCallback; + p.userData = nullptr; + HIP_CHECK(hipGraphAddHostNode(&cpuGraphNode, graph, nullptr, 0, &p)); + + addGpuKernel<<<1, 1, 0, stream>>>(i_d); + + HIP_CHECK(hipStreamEndCapture(stream, &graph)); + + HIP_CHECK(hipGraphInstantiate(&graphExec, graph, NULL, NULL, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + HIP_CHECK(hipFree(i_d)); + HIP_CHECK(hipGraphExecDestroy(graphExec)); + HIP_CHECK(hipGraphDestroy(graph)); + HIP_CHECK(hipStreamDestroy(stream)); +} + +/** +* Test Description +* ------------------------ +*  - Capture graph sequence using hipStreamBeginCapture and try to add a new +* node to the capture stream using hipStreamUpdateCaptureDependencies api +* which will copy back the result from the existing graph and verify +* 1) Add a hipGraphAddMemcpyNode1D node before hipStreamEndCapture +* 2) Add a hipGraphAddMemsetNode node before hipStreamEndCapture +* 3) Add a hipGraphAddMemcpyNode node before hipStreamEndCapture +* 4) Add a hipGraphAddKernelNode node before hipStreamEndCapture +* 5) Add a hipGraphAddMemcpyNodeToSymbol and hipGraphAddMemcpyNodeFromSymbol +* node before hipStreamEndCapture +* 6) Add a hipGraphAddHostNode node before hipStreamEndCapture +* 7) Add a hipGraphAddChildGraphNode node before hipStreamEndCapture +* 8) Add a hipGraphAddEmptyNode node before hipStreamEndCapture +* 9) Add a hipGraphAddEventRecordNode node before hipStreamEndCapture +* 10) Add a hipGraphAddEventWaitNode node before hipStreamEndCapture +* Test source +* ------------------------ +*  - unit/graph/hipGraphAddNodeBeginCapture.cc +* Test requirements +* ------------------------ +*  - HIP_VERSION >= 5.6 +*/ + +TEST_CASE("Unit_hipStreamEndCapture_later_and_add_a_node_inbetween") { + hipGraphExec_t graphExec; + hipGraphNode_t memcpyD2H_C; + hipStream_t stream; + int *A_d, *B_d, *C_d, *A_h, *B_h, *C_h; + HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, SIZE, false); + + HIP_CHECK(hipStreamCreate(&stream)); + HIP_CHECK(hipStreamBeginCapture(stream, hipStreamCaptureModeGlobal)); + HIP_CHECK(hipMemcpyAsync(A_d, A_h, Nbytes, hipMemcpyHostToDevice, stream)); + HIP_CHECK(hipMemcpyAsync(B_d, B_h, Nbytes, hipMemcpyHostToDevice, stream)); + HipTest::vectorADD<<<1, 1, 0, stream>>>(A_d, B_d, C_d, SIZE); + + hipStreamCaptureStatus captureStatus{hipStreamCaptureStatusNone}; + hipGraph_t capGraph{nullptr}; + const hipGraphNode_t* nodelist{}; + size_t numDependencies; + + HIP_CHECK(hipStreamGetCaptureInfo_v2(stream, &captureStatus, nullptr, + &capGraph, &nodelist, &numDependencies)); + REQUIRE(captureStatus == hipStreamCaptureStatusActive); + REQUIRE(capGraph != nullptr); + + SECTION("Add a hipGraphAddMemcpyNode1D node before hipStreamEndCapture") { + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_C, capGraph, nodelist, + numDependencies, C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &memcpyD2H_C, 1, + hipStreamSetCaptureDependencies)); + + HIP_CHECK(hipStreamEndCapture(stream, &capGraph)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, capGraph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + // Verify execution result + HipTest::checkVectorADD(A_h, B_h, C_h, SIZE); + } + SECTION("Add a hipGraphAddMemsetNode node before hipStreamEndCapture") { + hipGraphNode_t memsetNode; + int memSetVal = 7; + hipMemsetParams memsetParams{}; + memset(&memsetParams, 0, sizeof(memsetParams)); + memsetParams.dst = reinterpret_cast(C_d); + memsetParams.value = memSetVal; + memsetParams.pitch = 0; + memsetParams.elementSize = sizeof(char); + memsetParams.width = Nbytes; + memsetParams.height = 1; + HIP_CHECK(hipGraphAddMemsetNode(&memsetNode, capGraph, nodelist, + numDependencies, &memsetParams)); + + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &memsetNode, 1, + hipStreamSetCaptureDependencies)); + HIP_CHECK(hipMemcpyAsync(C_h, C_d, Nbytes, hipMemcpyDeviceToHost, stream)); + HIP_CHECK(hipStreamEndCapture(stream, &capGraph)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, capGraph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + // Verify execution result + verifyArrayMemset(C_h, memSetVal); + } + SECTION("Add a hipGraphAddMemcpyNode node before hipStreamEndCapture") { + hipMemcpy3DParms myparams; + hipGraphNode_t memcpyNode; + + memset(&myparams, 0x0, sizeof(hipMemcpy3DParms)); + myparams.srcPos = make_hipPos(0, 0, 0); + myparams.dstPos = make_hipPos(0, 0, 0); + myparams.srcPtr = make_hipPitchedPtr(C_d, Nbytes, 1, 1); + myparams.dstPtr = make_hipPitchedPtr(C_h, Nbytes, 1, 1); + myparams.extent = make_hipExtent(Nbytes, 1, 1); + myparams.kind = hipMemcpyDeviceToHost; + + HIP_CHECK(hipGraphAddMemcpyNode(&memcpyNode, capGraph, nodelist, + numDependencies, &myparams)); + + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &memcpyNode, 1, + hipStreamSetCaptureDependencies)); + + HIP_CHECK(hipStreamEndCapture(stream, &capGraph)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, capGraph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + // Verify execution result + HipTest::checkVectorADD(A_h, B_h, C_h, SIZE); + } + SECTION("Add a hipGraphAddKernelNode node before hipStreamEndCapture") { + hipGraphNode_t kNode; + hipKernelNodeParams kNodeParams{}; + memset(&kNodeParams, 0x00, sizeof(kNodeParams)); + void* kernelArgs[] = {&C_d}; + kNodeParams.func = reinterpret_cast(kCallbackFunc); + kNodeParams.gridDim = dim3(1); + kNodeParams.blockDim = dim3(256); + kNodeParams.sharedMemBytes = 0; + kNodeParams.kernelParams = reinterpret_cast(kernelArgs); + kNodeParams.extra = nullptr; + HIP_CHECK(hipGraphAddKernelNode(&kNode, capGraph, nodelist, + numDependencies, &kNodeParams)); + + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &kNode, 1, + hipStreamSetCaptureDependencies)); + HIP_CHECK(hipMemcpyAsync(C_h, C_d, Nbytes, hipMemcpyDeviceToHost, stream)); + HIP_CHECK(hipStreamEndCapture(stream, &capGraph)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, capGraph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + // Verify execution result + verifyCallbackFunc(C_h); + } + SECTION("Add hipGraphAddMemcpyNodeToSymbol node before hipStreamEndCapture") { + hipGraphNode_t memcpyToSymNode, memcpyFromSymNode; + + HIP_CHECK(hipGraphAddMemcpyNodeToSymbol(&memcpyToSymNode, capGraph, + nodelist, numDependencies, HIP_SYMBOL(globalOut), + C_d, Nbytes, 0, hipMemcpyDeviceToDevice)); + + HIP_CHECK(hipGraphAddMemcpyNodeFromSymbol(&memcpyFromSymNode, capGraph, + nullptr, 0, C_h, HIP_SYMBOL(globalOut), + Nbytes, 0, hipMemcpyDeviceToHost)); + + HIP_CHECK(hipGraphAddDependencies(capGraph, &memcpyToSymNode, + &memcpyFromSymNode, 1)); + + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &memcpyToSymNode, 1, + hipStreamSetCaptureDependencies)); + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &memcpyFromSymNode, 1, + hipStreamSetCaptureDependencies)); + + HIP_CHECK(hipStreamEndCapture(stream, &capGraph)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, capGraph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + // Verify execution result + HipTest::checkVectorADD(A_h, B_h, C_h, SIZE); + } + SECTION("Add a hipGraphAddHostNode node before hipStreamEndCapture") { + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_C, capGraph, nodelist, + numDependencies, C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + + hipGraphNode_t hostNode; + hipHostNodeParams hostParams = {0, 0}; + hostParams.fn = callbackFunc; + hostParams.userData = C_h; + HIP_CHECK(hipGraphAddHostNode(&hostNode, capGraph, + nullptr, 0, &hostParams)); + + HIP_CHECK(hipGraphAddDependencies(capGraph, &memcpyD2H_C, &hostNode, 1)); + + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &memcpyD2H_C, 1, + hipStreamSetCaptureDependencies)); + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &hostNode, 1, + hipStreamSetCaptureDependencies)); + + HIP_CHECK(hipStreamEndCapture(stream, &capGraph)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, capGraph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + // Verify execution result + verifyCallbackFunc(C_h); + } + SECTION("Add a hipGraphAddChildGraphNode node before hipStreamEndCapture") { + hipGraph_t childGraph; + hipGraphNode_t memsetNode, childGraphNode; + int memSetVal = 7; + + hipMemsetParams memsetParams{}; + memset(&memsetParams, 0, sizeof(memsetParams)); + memsetParams.dst = reinterpret_cast(C_d); + memsetParams.value = memSetVal; + memsetParams.pitch = 0; + memsetParams.elementSize = sizeof(char); + memsetParams.width = Nbytes; + memsetParams.height = 1; + + HIP_CHECK(hipGraphCreate(&childGraph, 0)); + HIP_CHECK(hipGraphAddMemsetNode(&memsetNode, childGraph, nullptr, 0, + &memsetParams)); + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_C, childGraph, nullptr, 0, + C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + HIP_CHECK(hipGraphAddDependencies(childGraph, &memsetNode, + &memcpyD2H_C, 1)); + + HIP_CHECK(hipGraphAddChildGraphNode(&childGraphNode, capGraph, nodelist, + numDependencies, childGraph)); + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &childGraphNode, 1, + hipStreamSetCaptureDependencies)); + HIP_CHECK(hipStreamEndCapture(stream, &capGraph)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, capGraph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + // Verify execution result + verifyArrayMemset(C_h, memSetVal); + HIP_CHECK(hipGraphDestroy(childGraph)); + } + SECTION("Add a hipGraphAddEmptyNode node before hipStreamEndCapture") { + hipGraphNode_t emptyNode; + HIP_CHECK(hipGraphAddEmptyNode(&emptyNode, capGraph, + nodelist, numDependencies)); + + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_C, capGraph, nullptr, 0, + C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + + HIP_CHECK(hipGraphAddDependencies(capGraph, &emptyNode, &memcpyD2H_C, 1)); + + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &emptyNode, 1, + hipStreamSetCaptureDependencies)); + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &memcpyD2H_C, 1, + hipStreamSetCaptureDependencies)); + + HIP_CHECK(hipStreamEndCapture(stream, &capGraph)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, capGraph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + // Verify execution result + HipTest::checkVectorADD(A_h, B_h, C_h, SIZE); + } + SECTION("Add hipGraphAddEventRecordNode node before hipStreamEndCapture") { + hipGraphNode_t event_start, event_end; + hipEvent_t eventstart, eventend; + + HIP_CHECK(hipEventCreate(&eventstart)); + HIP_CHECK(hipEventCreate(&eventend)); + + HIP_CHECK(hipGraphAddEventRecordNode(&event_start, capGraph, + nodelist, numDependencies, eventstart)); + + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_C, capGraph, nullptr, 0, + C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + + HIP_CHECK(hipGraphAddEventRecordNode(&event_end, capGraph, + nullptr, 0, eventend)); + + HIP_CHECK(hipGraphAddDependencies(capGraph, &event_start, &memcpyD2H_C, 1)); + HIP_CHECK(hipGraphAddDependencies(capGraph, &memcpyD2H_C, &event_end, 1)); + + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &event_start, 1, + hipStreamSetCaptureDependencies)); + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &memcpyD2H_C, 1, + hipStreamSetCaptureDependencies)); + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &event_end, 1, + hipStreamSetCaptureDependencies)); + + HIP_CHECK(hipStreamEndCapture(stream, &capGraph)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, capGraph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + HIP_CHECK(hipEventSynchronize(eventend)); + + // Verify execution result + HipTest::checkVectorADD(A_h, B_h, C_h, SIZE); + + float t = 0.0f; + HIP_CHECK(hipEventElapsedTime(&t, eventstart, eventend)); + REQUIRE(t > 0.0f); + + HIP_CHECK(hipEventDestroy(eventstart)); + HIP_CHECK(hipEventDestroy(eventend)); + } + SECTION("Add hipGraphAddEventWaitNode node before hipStreamEndCapture") { + hipGraphNode_t eventRecNode, eventWaitNode; + hipEvent_t event; + + HIP_CHECK(hipEventCreate(&event)); + + HIP_CHECK(hipGraphAddEventRecordNode(&eventRecNode, capGraph, + nodelist, numDependencies, event)); + + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_C, capGraph, nullptr, 0, + C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + + HIP_CHECK(hipGraphAddEventWaitNode(&eventWaitNode, capGraph, + nullptr, 0, event)); + + HIP_CHECK(hipGraphAddDependencies(capGraph, &eventRecNode, + &memcpyD2H_C, 1)); + HIP_CHECK(hipGraphAddDependencies(capGraph, &memcpyD2H_C, + &eventWaitNode, 1)); + + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &eventRecNode, 1, + hipStreamSetCaptureDependencies)); + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &memcpyD2H_C, 1, + hipStreamSetCaptureDependencies)); + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &eventWaitNode, 1, + hipStreamSetCaptureDependencies)); + + HIP_CHECK(hipStreamEndCapture(stream, &capGraph)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, capGraph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + HIP_CHECK(hipEventSynchronize(event)); + + // Verify execution result + HipTest::checkVectorADD(A_h, B_h, C_h, SIZE); + + HIP_CHECK(hipEventDestroy(event)); + } + + HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false); + HIP_CHECK(hipGraphExecDestroy(graphExec)); + HIP_CHECK(hipGraphDestroy(capGraph)); + HIP_CHECK(hipStreamDestroy(stream)); +} + +/** +* Test Description +* ------------------------ +*  - Capture graph sequence using hipStreamBeginCapture and hipStreamEndCapture +* Try to add a new node and link this new node to the existing graph +* which will copy back the result from the existing graph and verify +* 1) Add a hipGraphAddMemcpyNode1D node after hipStreamEndCapture +* 2) Add a hipGraphAddMemsetNode node after hipStreamEndCapture +* 3) Add a hipGraphAddMemcpyNode node after hipStreamEndCapture +* 4) Add a hipGraphAddKernelNode node after hipStreamEndCapture +* 5) Add a hipGraphAddMemcpyNodeToSymbol and hipGraphAddMemcpyNodeFromSymbol +* node after hipStreamEndCapture +* 6) Add a hipGraphAddHostNode node after hipStreamEndCapture +* 7) Add a hipGraphAddChildGraphNode node after hipStreamEndCapture +* 8) Add a hipGraphAddEmptyNode node after hipStreamEndCapture +* 9) Add a hipGraphAddEventRecordNode node after hipStreamEndCapture +* 10) Add a hipGraphAddEventWaitNode node after hipStreamEndCapture +* Test source +* ------------------------ +*  - unit/graph/hipGraphAddNodeBeginCapture.cc +* Test requirements +* ------------------------ +*  - HIP_VERSION >= 5.6 +*/ + +TEST_CASE("Unit_hipStreamEndCapture_first_and_add_a_node_later") { + hipGraph_t graph; + hipGraphExec_t graphExec; + hipGraphNode_t memcpyD2H_C; + hipStream_t stream; + int *A_d, *B_d, *C_d, *A_h, *B_h, *C_h; + HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, SIZE, false); + + HIP_CHECK(hipStreamCreate(&stream)); + HIP_CHECK(hipStreamBeginCapture(stream, hipStreamCaptureModeGlobal)); + HIP_CHECK(hipMemcpyAsync(A_d, A_h, Nbytes, hipMemcpyHostToDevice, stream)); + HIP_CHECK(hipMemcpyAsync(B_d, B_h, Nbytes, hipMemcpyHostToDevice, stream)); + HipTest::vectorSUB<<<1, 1, 0, stream>>>(A_d, B_d, C_d, SIZE); + HIP_CHECK(hipStreamEndCapture(stream, &graph)); + + size_t numN{}; + int foundAt = -1; + HIP_CHECK(hipGraphGetNodes(graph, nullptr, &numN)); + + hipGraphNode_t* nodes = + reinterpret_cast(malloc(numN * sizeof(hipGraphNode_t))); + REQUIRE(nodes != nullptr); + + HIP_CHECK(hipGraphGetNodes(graph, nodes, &numN)); + hipGraphNodeType nodeType; + for (int i = 0; i < numN; i++) { + HIP_CHECK(hipGraphNodeGetType(nodes[i], &nodeType)); + if (nodeType == hipGraphNodeTypeKernel) { + foundAt = i; + break; + } + } + + SECTION("Add a hipGraphAddMemcpyNode1D node after hipStreamEndCapture") { + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_C, graph, nullptr, 0, + C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + HIP_CHECK(hipGraphAddDependencies(graph, &nodes[foundAt], &memcpyD2H_C, 1)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + // Verify execution result + HipTest::checkVectorSUB(A_h, B_h, C_h, SIZE); + } + SECTION("Add a hipGraphAddMemsetNode node after hipStreamEndCapture") { + hipGraphNode_t memsetNode; + int memSetVal = 7; + hipMemsetParams memsetParams{}; + memset(&memsetParams, 0, sizeof(memsetParams)); + memsetParams.dst = reinterpret_cast(C_d); + memsetParams.value = memSetVal; + memsetParams.pitch = 0; + memsetParams.elementSize = sizeof(char); + memsetParams.width = Nbytes; + memsetParams.height = 1; + HIP_CHECK(hipGraphAddMemsetNode(&memsetNode, graph, nullptr, 0, + &memsetParams)); + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_C, graph, nullptr, 0, + C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + + HIP_CHECK(hipGraphAddDependencies(graph, &nodes[foundAt], &memsetNode, 1)); + HIP_CHECK(hipGraphAddDependencies(graph, &memsetNode, &memcpyD2H_C, 1)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + // Verify execution result + verifyArrayMemset(C_h, memSetVal); + } + SECTION("Add a hipGraphAddMemcpyNode node after hipStreamEndCapture") { + hipMemcpy3DParms myparams; + hipGraphNode_t memcpyNode; + + memset(&myparams, 0x0, sizeof(hipMemcpy3DParms)); + myparams.srcPos = make_hipPos(0, 0, 0); + myparams.dstPos = make_hipPos(0, 0, 0); + myparams.srcPtr = make_hipPitchedPtr(C_d, Nbytes, 1, 1); + myparams.dstPtr = make_hipPitchedPtr(C_h, Nbytes, 1, 1); + myparams.extent = make_hipExtent(Nbytes, 1, 1); + myparams.kind = hipMemcpyDeviceToHost; + + HIP_CHECK(hipGraphAddMemcpyNode(&memcpyNode, graph, nullptr, 0, &myparams)); + + HIP_CHECK(hipGraphAddDependencies(graph, &nodes[foundAt], &memcpyNode, 1)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + // Verify execution result + HipTest::checkVectorSUB(A_h, B_h, C_h, SIZE); + } + SECTION("Add a hipGraphAddKernelNode node after hipStreamEndCapture") { + hipGraphNode_t kNode; + hipKernelNodeParams kNodeParams{}; + memset(&kNodeParams, 0x00, sizeof(kNodeParams)); + void* kernelArgs[] = {&C_d}; + kNodeParams.func = reinterpret_cast(kCallbackFunc); + kNodeParams.gridDim = dim3(1); + kNodeParams.blockDim = dim3(256); + kNodeParams.sharedMemBytes = 0; + kNodeParams.kernelParams = reinterpret_cast(kernelArgs); + kNodeParams.extra = nullptr; + HIP_CHECK(hipGraphAddKernelNode(&kNode, graph, nullptr, 0, &kNodeParams)); + + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_C, graph, nullptr, 0, + C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + + HIP_CHECK(hipGraphAddDependencies(graph, &nodes[foundAt], &kNode, 1)); + HIP_CHECK(hipGraphAddDependencies(graph, &kNode, &memcpyD2H_C, 1)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + // Verify execution result + verifyCallbackFunc(C_h); + } + SECTION("Add hipGraphAddMemcpyNodeToSymbol node after hipStreamEndCapture") { + hipGraphNode_t memcpyToSymNode, memcpyFromSymNode; + HIP_CHECK(hipGraphAddMemcpyNodeToSymbol(&memcpyToSymNode, graph, nullptr, + 0, HIP_SYMBOL(globalOut), C_d, Nbytes, 0, + hipMemcpyDeviceToDevice)); + + HIP_CHECK(hipGraphAddMemcpyNodeFromSymbol(&memcpyFromSymNode, graph, + nullptr, 0, C_h, HIP_SYMBOL(globalOut), + Nbytes, 0, hipMemcpyDeviceToHost)); + + HIP_CHECK(hipGraphAddDependencies(graph, &nodes[foundAt], + &memcpyToSymNode, 1)); + HIP_CHECK(hipGraphAddDependencies(graph, &memcpyToSymNode, + &memcpyFromSymNode, 1)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + // Verify execution result + HipTest::checkVectorSUB(A_h, B_h, C_h, SIZE); + } + SECTION("Add hipGraphAddHostNode node after hipStreamEndCapture") { + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_C, graph, nullptr, 0, + C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + + hipGraphNode_t hostNode; + hipHostNodeParams hostParams = {0, 0}; + hostParams.fn = callbackFunc; + hostParams.userData = C_h; + HIP_CHECK(hipGraphAddHostNode(&hostNode, graph, nullptr, 0, &hostParams)); + + HIP_CHECK(hipGraphAddDependencies(graph, &nodes[foundAt], &memcpyD2H_C, 1)); + HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2H_C, &hostNode, 1)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + // Verify execution result + verifyCallbackFunc(C_h); + } + SECTION("Add hipGraphAddChildGraphNode node after hipStreamEndCapture") { + hipGraph_t childGraph; + hipGraphNode_t memsetNode, childGraphNode; + int memSetVal = 7; + + hipMemsetParams memsetParams{}; + memset(&memsetParams, 0, sizeof(memsetParams)); + memsetParams.dst = reinterpret_cast(C_d); + memsetParams.value = memSetVal; + memsetParams.pitch = 0; + memsetParams.elementSize = sizeof(char); + memsetParams.width = Nbytes; + memsetParams.height = 1; + + HIP_CHECK(hipGraphCreate(&childGraph, 0)); + HIP_CHECK(hipGraphAddMemsetNode(&memsetNode, childGraph, nullptr, 0, + &memsetParams)); + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_C, childGraph, nullptr, 0, + C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + HIP_CHECK(hipGraphAddDependencies(childGraph, &memsetNode, + &memcpyD2H_C, 1)); + + HIP_CHECK(hipGraphAddChildGraphNode(&childGraphNode, graph, nullptr, 0, + childGraph)); + + HIP_CHECK(hipGraphAddDependencies(graph, &nodes[foundAt], + &childGraphNode, 1)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + // Verify execution result + verifyArrayMemset(C_h, memSetVal); + HIP_CHECK(hipGraphDestroy(childGraph)); + } + SECTION("Add hipGraphAddEmptyNode node after hipStreamEndCapture") { + hipGraphNode_t emptyNode; + HIP_CHECK(hipGraphAddEmptyNode(&emptyNode, graph, nullptr, 0)); + + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_C, graph, nullptr, 0, + C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + + HIP_CHECK(hipGraphAddDependencies(graph, &nodes[foundAt], &emptyNode, 1)); + HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode, &memcpyD2H_C, 1)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + // Verify execution result + HipTest::checkVectorSUB(A_h, B_h, C_h, SIZE); + } + SECTION("Add hipGraphAddEventRecordNode node after hipStreamEndCapture") { + hipGraphNode_t event_start, event_end; + hipEvent_t eventstart, eventend; + + HIP_CHECK(hipEventCreate(&eventstart)); + HIP_CHECK(hipEventCreate(&eventend)); + + HIP_CHECK(hipGraphAddEventRecordNode(&event_start, graph, + nullptr, 0, eventstart)); + + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_C, graph, nullptr, 0, + C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + + HIP_CHECK(hipGraphAddEventRecordNode(&event_end, graph, + nullptr, 0, eventend)); + + HIP_CHECK(hipGraphAddDependencies(graph, &nodes[foundAt], &event_start, 1)); + HIP_CHECK(hipGraphAddDependencies(graph, &event_start, &memcpyD2H_C, 1)); + HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2H_C, &event_end, 1)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + HIP_CHECK(hipEventSynchronize(eventend)); + + // Verify execution result + HipTest::checkVectorSUB(A_h, B_h, C_h, SIZE); + + float t = 0.0f; + HIP_CHECK(hipEventElapsedTime(&t, eventstart, eventend)); + REQUIRE(t > 0.0f); + + HIP_CHECK(hipEventDestroy(eventstart)); + HIP_CHECK(hipEventDestroy(eventend)); + } + SECTION("Add hipGraphAddEventWaitNode node after hipStreamEndCapture") { + hipGraphNode_t eventRecNode, eventWaitNode; + hipEvent_t event; + + HIP_CHECK(hipEventCreate(&event)); + + HIP_CHECK(hipGraphAddEventRecordNode(&eventRecNode, graph, + nullptr, 0, event)); + + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_C, graph, nullptr, 0, + C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + + HIP_CHECK(hipGraphAddEventWaitNode(&eventWaitNode, graph, + nullptr, 0, event)); + + HIP_CHECK(hipGraphAddDependencies(graph, &nodes[foundAt], + &eventRecNode, 1)); + HIP_CHECK(hipGraphAddDependencies(graph, &eventRecNode, &memcpyD2H_C, 1)); + HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2H_C, &eventWaitNode, 1)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + HIP_CHECK(hipEventSynchronize(event)); + + // Verify execution result + HipTest::checkVectorSUB(A_h, B_h, C_h, SIZE); + + HIP_CHECK(hipEventDestroy(event)); + } + + free(nodes); + HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false); + HIP_CHECK(hipGraphExecDestroy(graphExec)); + HIP_CHECK(hipGraphDestroy(graph)); + HIP_CHECK(hipStreamDestroy(stream)); +} + +/** +* Test Description +* ------------------------ +*  - Capture graph sequence using hipStreamBeginCapture and hipStreamEndCapture +* Add some new node to the same graph and execute it and verify +* Test source +* ------------------------ +*  - unit/graph/hipGraphAddNodeBeginCapture.cc +* Test requirements +* ------------------------ +*  - HIP_VERSION >= 5.6 +*/ + +TEST_CASE("Unit_hipStreamEndCapture_first_and_add_other_graph_node_later") { + hipGraph_t graph; + hipGraphExec_t graphExec; + hipGraphNode_t memcpyH2D_A, memcpyH2D_B, memcpyD2H_AC, memcpyH2D_C; + hipStream_t stream; + int *A_d, *B_d, *C_d, *A_h, *B_h, *C_h; + HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, SIZE, false); + + int *A_d1, *B_d1, *C_d1, *A_h1, *B_h1, *C_h1; + HipTest::initArrays(&A_d1, &B_d1, &C_d1, &A_h1, &B_h1, &C_h1, SIZE, false); + + HIP_CHECK(hipStreamCreate(&stream)); + HIP_CHECK(hipGraphCreate(&graph, 0)); + + HIP_CHECK(hipStreamBeginCapture(stream, hipStreamCaptureModeGlobal)); + HIP_CHECK(hipMemcpyAsync(A_d1, A_h1, Nbytes, hipMemcpyHostToDevice, stream)); + HIP_CHECK(hipMemcpyAsync(B_d1, B_h1, Nbytes, hipMemcpyHostToDevice, stream)); + HipTest::vectorADD<<<1, 1, 0, stream>>>(A_d1, B_d1, C_d1, SIZE); + HIP_CHECK(hipMemcpyAsync(C_h1, C_d1, Nbytes, hipMemcpyDeviceToHost, stream)); + HIP_CHECK(hipStreamEndCapture(stream, &graph)); + + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_A, graph, nullptr, 0, A_d, A_h, + Nbytes, hipMemcpyHostToDevice)); + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_B, graph, nullptr, 0, B_d, B_h, + Nbytes, hipMemcpyHostToDevice)); + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr, 0, C_d, C_h, + Nbytes, hipMemcpyHostToDevice)); + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_AC, graph, nullptr, 0, A_h, C_d, + Nbytes, hipMemcpyDeviceToHost)); + hipGraphNode_t hostNode; + hipHostNodeParams hostParams = {0, 0}; + hostParams.fn = callbackFunc; + hostParams.userData = A_h; + HIP_CHECK(hipGraphAddHostNode(&hostNode, graph, nullptr, 0, &hostParams)); + + HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_A, &memcpyH2D_B, 1)); + HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_B, &memcpyD2H_AC, 1)); + HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_C, &memcpyD2H_AC, 1)); + HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2H_AC, &hostNode, 1)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + // Verify execution result fir above two graph operations + verifyCallbackFunc(A_h); + HipTest::checkVectorADD(A_h1, B_h1, C_h1, SIZE); + + HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false); + HipTest::freeArrays(A_d1, B_d1, C_d1, A_h1, B_h1, C_h1, false); + HIP_CHECK(hipGraphExecDestroy(graphExec)); + HIP_CHECK(hipGraphDestroy(graph)); + HIP_CHECK(hipStreamDestroy(stream)); +} + +/** +* Test Description +* ------------------------ +*  - Capture graph sequence using hipStreamBeginCapture and +* add some new node before hipStreamEndCapture to the same graph +* and hipGraphAddEmptyNode to use as last node to grah to complete. +* Test source +* ------------------------ +*  - unit/graph/hipGraphAddNodeBeginCapture.cc +* Test requirements +* ------------------------ +*  - HIP_VERSION >= 5.6 +*/ + +TEST_CASE("Unit_hipStreamEndCapture_later_and_addEmptyNode") { + hipGraphExec_t graphExec; + hipGraphNode_t memcpyD2H_C; + hipStream_t stream; + int *A_d, *B_d, *C_d, *A_h, *B_h, *C_h; + HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, SIZE, false); + + HIP_CHECK(hipStreamCreate(&stream)); + HIP_CHECK(hipStreamBeginCapture(stream, hipStreamCaptureModeGlobal)); + HIP_CHECK(hipMemcpyAsync(A_d, A_h, Nbytes, hipMemcpyHostToDevice, stream)); + HIP_CHECK(hipMemcpyAsync(B_d, B_h, Nbytes, hipMemcpyHostToDevice, stream)); + HipTest::vectorSUB<<<1, 1, 0, stream>>>(A_d, B_d, C_d, SIZE); + + hipStreamCaptureStatus captureStatus{hipStreamCaptureStatusNone}; + hipGraph_t capGraph{nullptr}; + const hipGraphNode_t* nodelist{}; + size_t numDependencies; + + HIP_CHECK(hipStreamGetCaptureInfo_v2(stream, &captureStatus, nullptr, + &capGraph, &nodelist, &numDependencies)); + REQUIRE(captureStatus == hipStreamCaptureStatusActive); + REQUIRE(capGraph != nullptr); + + hipGraphNode_t memsetNode; + int memSetVal = 7; + hipMemsetParams memsetParams{}; + memset(&memsetParams, 0, sizeof(memsetParams)); + memsetParams.dst = reinterpret_cast(C_d); + memsetParams.value = memSetVal; + memsetParams.pitch = 0; + memsetParams.elementSize = sizeof(char); + memsetParams.width = Nbytes; + memsetParams.height = 1; + HIP_CHECK(hipGraphAddMemsetNode(&memsetNode, capGraph, nodelist, + numDependencies, &memsetParams)); + + HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_C, capGraph, nullptr, 0, + C_h, C_d, Nbytes, hipMemcpyDeviceToHost)); + + hipGraphNode_t emptyNode; + HIP_CHECK(hipGraphAddEmptyNode(&emptyNode, capGraph, nullptr, 0)); + + HIP_CHECK(hipGraphAddDependencies(capGraph, &memsetNode, &memcpyD2H_C, 1)); + HIP_CHECK(hipGraphAddDependencies(capGraph, &memcpyD2H_C, &emptyNode, 1)); + + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &memsetNode, 1, + hipStreamSetCaptureDependencies)); + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &memcpyD2H_C, 1, + hipStreamSetCaptureDependencies)); + HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, &emptyNode, 1, + hipStreamSetCaptureDependencies)); + + HIP_CHECK(hipStreamEndCapture(stream, &capGraph)); + + // Instantiate and launch the graph + HIP_CHECK(hipGraphInstantiate(&graphExec, capGraph, nullptr, nullptr, 0)); + HIP_CHECK(hipGraphLaunch(graphExec, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + + // Verify execution result + verifyArrayMemset(C_h, memSetVal); + + HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false); + HIP_CHECK(hipGraphExecDestroy(graphExec)); + HIP_CHECK(hipGraphDestroy(capGraph)); + HIP_CHECK(hipStreamDestroy(stream)); +} + From 58b55f9544b36db05066cb68fcd19fc5dccd4da1 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Mon, 14 Aug 2023 21:17:40 +0530 Subject: [PATCH 14/30] SWDEV-394940 - [catch2][dtest] Adding basic testcases with HIPRTC apis for supported compiler options & also with combination of compiler options (#327) Change-Id: Ie393e91afe195387152b588780e3109f21d1ad94 --- .../config/config_amd_linux_common.json | 26 +- catch/unit/rtc/CMakeLists.txt | 7 + catch/unit/rtc/RtcConfig.json | 175 + catch/unit/rtc/RtcFunctions.cpp | 3301 +++++++++++++++++ catch/unit/rtc/RtcUtility.cpp | 507 +++ catch/unit/rtc/headers/RtcFact.h | 38 + catch/unit/rtc/headers/RtcFunctions.h | 178 + catch/unit/rtc/headers/RtcKernels.h | 163 + catch/unit/rtc/headers/RtcUtility.h | 53 + catch/unit/rtc/headers/printf_common.h | 181 + catch/unit/rtc/hiprtcComplrOptnTesting.cc | 244 ++ 11 files changed, 4862 insertions(+), 11 deletions(-) create mode 100644 catch/unit/rtc/RtcConfig.json create mode 100644 catch/unit/rtc/RtcFunctions.cpp create mode 100644 catch/unit/rtc/RtcUtility.cpp create mode 100644 catch/unit/rtc/headers/RtcFact.h create mode 100644 catch/unit/rtc/headers/RtcFunctions.h create mode 100644 catch/unit/rtc/headers/RtcKernels.h create mode 100644 catch/unit/rtc/headers/RtcUtility.h create mode 100644 catch/unit/rtc/headers/printf_common.h create mode 100644 catch/unit/rtc/hiprtcComplrOptnTesting.cc diff --git a/catch/hipTestMain/config/config_amd_linux_common.json b/catch/hipTestMain/config/config_amd_linux_common.json index 2e7d092244..39c403ef89 100644 --- a/catch/hipTestMain/config/config_amd_linux_common.json +++ b/catch/hipTestMain/config/config_amd_linux_common.json @@ -111,22 +111,26 @@ "Unit_deviceAllocation_Malloc_ComplexDataType", "Unit_deviceAllocation_New_ComplexDataType", "Unit_hipStreamValue_Wait32_Blocking_Mask_Eq_1", + "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/327 ===", + "Unit_hiprtcGpuRdcComplrOptnTst", + "Unit_hiprtcDisabledSlpVectorizeComplrOptnTst", + "Unit_hiprtcRpassInlineComplrOptnTst", + "Unit_hiprtcCombiComplrOptnTst", "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/92 ===", "Unit_hipGetChannelDesc_Negative_Parameters", "Unit_hipGraphAddChildGraphNode_CmplxNstGrph_UpdKerFun_Clone", "=== Below tests fail in stress test on 24/07/23 ===", "Unit_hipStreamCreateWithPriority_ValidateWithEvents", "Unit_hipEventIpc", - "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", - "Unit_hiprtc_saxpy.Unit_hiprtc_saxpy", - "Unit_hiprtc_warpsize.Unit_hiprtc_warpsize", - "Unit_hiprtc_functional.Unit_hiprtc_functional", - "Unit_hipStreamCaptureRtc.Unit_hipStreamCaptureRtc", - "Unit_hiprtc_cpp17.Unit_hiprtc_cpp17", - "Unit_hiprtc_namehandling.Unit_hiprtc_namehandling", - "Unit_hiprtc_getloweredname.Unit_hiprtc_getloweredname", - "Unit_hiprtc_test_hip_bfloat16.Unit_hiprtc_test_hip_bfloat16", - "Unit_RTC_LinkerAPI.Unit_RTC_LinkerAPI" - + "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", + "Unit_hiprtc_saxpy.Unit_hiprtc_saxpy", + "Unit_hiprtc_warpsize.Unit_hiprtc_warpsize", + "Unit_hiprtc_functional.Unit_hiprtc_functional", + "Unit_hipStreamCaptureRtc.Unit_hipStreamCaptureRtc", + "Unit_hiprtc_cpp17.Unit_hiprtc_cpp17", + "Unit_hiprtc_namehandling.Unit_hiprtc_namehandling", + "Unit_hiprtc_getloweredname.Unit_hiprtc_getloweredname", + "Unit_hiprtc_test_hip_bfloat16.Unit_hiprtc_test_hip_bfloat16", + "Unit_RTC_LinkerAPI.Unit_RTC_LinkerAPI" ] } diff --git a/catch/unit/rtc/CMakeLists.txt b/catch/unit/rtc/CMakeLists.txt index 57b17b7807..62fd20bf7e 100644 --- a/catch/unit/rtc/CMakeLists.txt +++ b/catch/unit/rtc/CMakeLists.txt @@ -14,6 +14,13 @@ set(AMD_TEST_SRC shfl.cc ) +if(UNIX) + set(AMD_TEST_SRC ${TEST_SRC} + RtcFunctions.cpp + RtcUtility.cpp + hiprtcComplrOptnTesting.cc) +endif() + if(HIP_PLATFORM MATCHES "nvidia") hip_add_exe_to_target(NAME RTC TEST_SRC ${TEST_SRC} diff --git a/catch/unit/rtc/RtcConfig.json b/catch/unit/rtc/RtcConfig.json new file mode 100644 index 0000000000..f0d00f704f --- /dev/null +++ b/catch/unit/rtc/RtcConfig.json @@ -0,0 +1,175 @@ +[ { + "block_name" : "all_compier_options", + "single_CO" : ["architecture", "rdc", "no_denormals", + "denormals", "off_ffp_contract", + "on_ffp_contract", "fast_ffp_contract", + "no_fast_math", "fast_math", + "no_slp_vectorize", "slp_vectorize", + "macro", "undef_macro", + "header_dir", "warning", "Rpass_inline", + "conversion_error", "conversion_no_error", + "conversion_no_warning", "conversion_warning", + "max_thread", "no_unsafe_atomic", "unsafe_atomic", + "no_infinite_num", "infinite_num", + "no_NAN_num", "NAN_num", + "no_finite_math", "finite_math", + "no_associative_math", "associative_math", + "no_signed_zeros","signed_zeros", + "no_trapping_math", "trapping_math" + ], + "Combi_CO" : ["header_dir:no_denormals:undef_macro:slp_vectorize:warning:conversion_no_warning:no_associative_math", + "max_thread:warning:architecture:macro:conversion_no_error:associative_math", + "denormals:macro:warning:header_dir:conversion_no_warning:unsafe_atomic:no_slp_vectorize", + "macro:warning:header_dir:undef_macro:architecture:on_ffp_contract:max_thread", + "no_NAN_num:max_thread:undef_macro:header_dir:warning", + "no_unsafe_atomic:fast_ffp_contract:undef_macro:fast_math", + "warning:max_thread:denormals:header_dir:no_infinite_num", + "no_denormals:header_dir:conversion_warning:off_ffp_contract", + "max_thread:fast_math:macro:no_denormals:no_unsafe_atomic", + "Rpass_inline:no_finite_math:NAN_num:warning:no_fast_math", + "no_infinite_num:no_trapping_math:conversion_no_error", + "infinite_num:no_trapping_math:undef_macro:header_dir", + "infinite_num:NAN_num:no_finite_math:max_thread:NAN_num", + "undef_macro:warning:header_dir:no_denormals:finite_math:associative_math", + "header_dir:Rpass_inline:no_fast_math:infinite_num:NAN_num:no_finite_math", + "denormals:no_unsafe_atomic:fast_ffp_contract", + "fast_math:no_infinite_num:no_NAN_num:finite_math:associative_math:no_signed_zeros:no_trapping_math:fast_ffp_contract", + "no_fast_math:infinite_num:NAN_num:no_finite_math:no_associative_math:signed_zeros:trapping_math:on_ffp_contract" + ] + }, + { + "block_name" : "architecture", + "compiler_option" : "--gpu-architecture=", + "kernel_name" : "max_thread" + }, + { + "block_name" : "rdc", + "compiler_option" : "-fgpu-rdc", + "kernel_name" : "rdc" + }, + { + "block_name" : "denormals", + "compiler_option" : "-fgpu-flush-denormals-to-zero", + "reverse_compiler_option" : "-fno-gpu-flush-denormals-to-zero", + "Input_Vals" : [2, -125, 2, -126, 2, -149, 2, -150, 2, -1000, 2, -2000, 2, -128], + "Expected_Results" : [1, 0, 0, 0, 0, 0, 0 ], + "Expected_Results_for_no" : [1, 1, 1, 0, 0, 0, 1 ], + "kernel_name" : "denormals" + }, + { + "block_name" : "max_thread", + "compiler_option" : "--gpu-max-threads-per-block=", + "Target_Vals" : [10, 100], + "Input_Vals" : [ 1, 2, 3, 50, 30, 50, 100, 110], + "Expected_Results" : [1, 1, 1, 0, 1, 1, 1, 0 ], + "ready_compiler_option" : "--gpu-max-threads-per-block=1000", + "kernel_name" : "max_thread" + }, + { + "block_name" : "fp32_div_sqrt", + "compiler_option" : "-fhip-fp32-correctly-rounded-divide-sqrt", + "reverse_compiler_option" : "-fno-hip-fp32-correctly-rounded-divide-sqrt", + "kernel_name" : "fp32_div_sqrt" + }, + { + "block_name" : "ffp_contract", + "compiler_option" : ["-ffp-contract=off", "-ffp-contract=on", "-ffp-contract=fast", "-ffp-contract=fast-honor-pragmas"], + "kernel_name" : "ffp_contract" + }, + { + "block_name" : "fast_math", + "compiler_option" : "-ffast-math", + "reverse_compiler_option" : "-fno-fast-math", + "kernel_name" : "ffp_contract" + }, + { + "block_name" : "warning", + "compiler_option" : "-w", + "kernel_name" : "warning" + }, + { + "block_name" : "error", + "compiler_option" : ["-Werror=conversion", "-Wno-error=conversion", "-Wconversion", "-Wno-conversion"], + "kernel_name" : "error" + }, + { + "block_name" : "Rpass_inline", + "compiler_option" : "-Rpass=inline", + "kernel_name" : "max_thread" + }, + { + "block_name" : "macro", + "compiler_option" : "-DPI=50", + "Expected_Results" : [50], + "kernel_name" : "macro" + }, + { + "block_name" : "undef_macro", + "compiler_option" : ["-DZ=10", "-UZ"], + "kernel_name" : "undef_macro" + }, + { + "block_name" : "header_dir", + "compiler_option" : "-I", + "depending_comp_optn" : ["-includefact.h"], + "Headers" : ["RtcFact.h"], + "Src_headers" : ["__device__ int fact(int num) {int fact =1; for (int i=1 ; i<= num ; i++){fact*=i;}return fact;}"], + "Input_Vals" : [5, 10], + "Expected_Results" : [120, 3628800], + "kernel_name" : "header_dir" + }, + { + "block_name" : "amdgpu_ieee", + "compiler_option" : ["-mamdgpu-ieee"], + "reverse_compiler_option" : ["-mno-amdgpu-ieee", "-fno-honor-nans"], + "kernel_name" : "amdgpu_ieee" + }, + { + "block_name" : "slp_vectorize", + "compiler_option" : "-fslp-vectorize", + "reverse_compiler_option" : "-fno-slp-vectorize", + "kernel_name" : "slp_vectorize" + }, + { + "block_name" : "unsafe_atomic", + "compiler_option" : "-munsafe-fp-atomics", + "reverse_compiler_option" : "-mno-unsafe-fp-atomics", + "kernel_name" : "unsafe_atomic" + }, + { + "block_name" : "infinite_num", + "compiler_option" : "-fhonor-infinities", + "reverse_compiler_option" : "-fno-honor-infinities", + "kernel_name" : "ffp_contract" + }, + { + "block_name" : "NAN_num", + "compiler_option" : "-fhonor-nans", + "reverse_compiler_option" : "-fno-honor-nans", + "kernel_name" : "ffp_contract" + }, + { + "block_name" : "finite_math", + "compiler_option" : "-ffinite-math-only", + "reverse_compiler_option" : "-fno-finite-math-only", + "kernel_name" : "ffp_contract" + }, + { + "block_name" : "associative_math", + "compiler_option" : "-fassociative-math", + "reverse_compiler_option" : "-fno-associative-math", + "kernel_name" : "ffp_contract" + }, + { + "block_name" : "signed_zeros", + "compiler_option" : "-fsigned-zeros", + "reverse_compiler_option" : "-fno-signed-zeros", + "kernel_name" : "ffp_contract" + }, + { + "block_name" : "trapping_math", + "compiler_option" : "-ftrapping-math", + "reverse_compiler_option" : "-fno-trapping-math", + "kernel_name" : "ffp_contract" + } +] diff --git a/catch/unit/rtc/RtcFunctions.cpp b/catch/unit/rtc/RtcFunctions.cpp new file mode 100644 index 0000000000..e73e195c07 --- /dev/null +++ b/catch/unit/rtc/RtcFunctions.cpp @@ -0,0 +1,3301 @@ +/* +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. +*/ + +/* +This file contains functions for idividual HIPRTC supported compiler options +validation. For PASS senario the function returns 1 or 0 otherwise. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "headers/RtcUtility.h" +#include "headers/RtcFunctions.h" +#include "headers/RtcKernels.h" +#include +#include "headers/printf_common.h" + +bool check_architecture(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "architecture"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::string retrieved_CO = get_string_parameters("compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME " << block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + hipDeviceProp_t prop; + HIP_CHECK(hipGetDeviceProperties(&prop, 0)); + std::string actual_architecture = prop.gcnArchName; + std::string complete_CO = retrieved_CO + actual_architecture; + const char* compiler_option = complete_CO.c_str(); + hiprtcProgram prog; + HIPRTC_CHECK(hiprtcCreateProgram(&prog, max_thread_string, + kername, 0, NULL, NULL)); + if (Combination_CO_size != -1) { + hiprtcResult compileResult{hiprtcCompileProgram(prog, + Combination_CO_size, + Combination_CO)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << compiler_option); + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } else { + hiprtcResult compileResult{hiprtcCompileProgram(prog, 1, + &compiler_option)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << compiler_option); + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } + return 1; +} + +bool check_rdc(const char** Combination_CO, int Combination_CO_size, + int max_thread_pos, int fast_math_present) { + std::string block_name = "rdc"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::string CO = get_string_parameters("compiler_option", + block_name); + if (CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + const char* compiler_opt = CO.c_str(); + float *A_d, *B_d, *C_d; + float *A_h, *B_h, *C_h, *result; + float Nbytes = sizeof(float); + A_h = new float[1]; + B_h = new float[1]; + C_h = new float[1]; + result = new float[1]; + for (int i = 0; i < 1; i++) { + A_h[i] = 4; + B_h[i] = 4; + result[i] = 16; + } + HIP_CHECK(hipMalloc(&A_d, Nbytes)); + HIP_CHECK(hipMalloc(&B_d, Nbytes)); + HIP_CHECK(hipMalloc(&C_d, Nbytes)); + HIP_CHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice)); + hiprtcProgram prog; + HIPRTC_CHECK(hiprtcCreateProgram(&prog, rdc_string, kername, 0, NULL, NULL)); + if (Combination_CO_size != -1) { + hiprtcResult compileResult{hiprtcCompileProgram(prog, Combination_CO_size, + Combination_CO)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << compiler_opt); + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } else { + hiprtcResult compileResult{hiprtcCompileProgram(prog, 1, &compiler_opt)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << compiler_opt); + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } + void* kernelParam[] = {A_d, B_d, C_d}; + auto size = sizeof(kernelParam); + void* kernel_parameter[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &kernelParam, + HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, + HIP_LAUNCH_PARAM_END}; + size_t codeSize; + HIPRTC_CHECK(hiprtcGetBitcodeSize(prog, &codeSize)); + std::vector codec(codeSize); + HIPRTC_CHECK(hiprtcGetBitcode(prog, codec.data())); + float wall_time; + int reg_count = 2; + int max_thread = 1; + unsigned int log_size = 5120; + char error_log[5120]; + char info_log[5120]; + std::vector jit_options = {HIPRTC_JIT_MAX_REGISTERS, + HIPRTC_JIT_THREADS_PER_BLOCK, + HIPRTC_JIT_WALL_TIME, + HIPRTC_JIT_INFO_LOG_BUFFER, + HIPRTC_JIT_INFO_LOG_BUFFER_SIZE_BYTES, + HIPRTC_JIT_ERROR_LOG_BUFFER, + HIPRTC_JIT_ERROR_LOG_BUFFER_SIZE_BYTES, + HIPRTC_JIT_LOG_VERBOSE}; + const void* lopts[] = {reinterpret_cast(®_count), + reinterpret_cast(&max_thread), + reinterpret_cast(&wall_time), + info_log, + reinterpret_cast(log_size), + error_log, + reinterpret_cast(log_size), + reinterpret_cast(1)}; + hiprtcLinkState rtc_link_state; + void* binary; + size_t binarySize; + int pass_count = 0; + hipModule_t module; + hipFunction_t function; + for (int i = 0; i < 2; i++) { + switch (i) { + case 0 : + HIPRTC_CHECK(hiprtcLinkCreate(0, nullptr, nullptr, &rtc_link_state)); + HIPRTC_CHECK(hiprtcLinkAddData(rtc_link_state, + HIPRTC_JIT_INPUT_LLVM_BITCODE, + codec.data(), codeSize, 0, 0, 0, 0)); + HIPRTC_CHECK(hiprtcLinkComplete(rtc_link_state, &binary, &binarySize)); + HIP_CHECK(hipModuleLoadData(&module, binary)); + HIP_CHECK(hipModuleGetFunction(&function, module, kername)); + HIP_CHECK(hipModuleLaunchKernel(function, 1, 1, 1, 1, 1, 1, 0, 0, + nullptr, kernel_parameter)); + pass_count++; + break; + case 1 : + HIPRTC_CHECK(hiprtcLinkCreate(8, jit_options.data(), + reinterpret_cast(&lopts), + &rtc_link_state)); + HIPRTC_CHECK(hiprtcLinkAddData(rtc_link_state, + HIPRTC_JIT_INPUT_LLVM_BITCODE, + codec.data(), codeSize, 0, 0, 0, 0)); + HIPRTC_CHECK(hiprtcLinkComplete(rtc_link_state, &binary, &binarySize)); + HIP_CHECK(hipModuleLoadData(&module, binary)); + HIP_CHECK(hipModuleGetFunction(&function, module, kername)); + HIP_CHECK(hipModuleLaunchKernel(function, 1, 1, 1, 1, 1, 1, 0, 0, + nullptr, kernel_parameter)); + pass_count++; + break; + default: + WARN(" NOT VALID INPUT "); + break; + } + } + HIP_CHECK(hipMemcpy(result, C_d, Nbytes, hipMemcpyDeviceToHost)); + for (int i = 0 ; i< 1; i++) { + if (result[i] != ((A_h[i] * B_h[i]))) { + WARN("Compiler Option : " << compiler_opt); + WARN("EXPECTED RESULT DOES NOT MATCH "); + WARN("INPUT A & B : " << A_h[i] <<" , "<< B_h[i]); + WARN("EXPECTED RES : " << (A_h[i] * B_h[i])); + WARN("OBTAINED RES : " << result[i]); + return 0; + } + } + if (pass_count == 2) { + return 1; + } else { + WARN(" pass_count IS NOT MATCHING "); + return 0; + } +} + +bool check_denormals_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "denormals"; + std::string retrieved_CO = get_string_parameters("compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + std::string kernel_name = get_string_parameters("kernel_name", block_name); + picojson::array Input_Vals = get_array_parameters("Input_Vals", block_name); + picojson::array Expected_Results = get_array_parameters("Expected_Results", + block_name); + const char* kername = kernel_name.c_str(); + const char* compiler_option = retrieved_CO.c_str(); + std::vector double_vec_input; + for (auto& indx : Input_Vals) { + double_vec_input.push_back(indx.get()); + } + std::vector Input_Vals_int; + for (auto& indx : double_vec_input) { + Input_Vals_int.push_back(static_cast(indx)); + } + std::vector double_vec_expected; + for (auto& indx : Expected_Results) { + double_vec_expected.push_back(indx.get()); + } + std::vector Expected_Results_int; + for (auto& indx : double_vec_expected) { + Expected_Results_int.push_back(static_cast(indx)); + } + int pass_count = 0; + int test_case, res_inc; + for (test_case = 0, res_inc = 0; test_case < Input_Vals_int.size() && + res_inc < Expected_Results_int.size(); test_case+=2, res_inc++) { + double *base_h, *power_h, *result_h; + double *base_d, *power_d, *result_d; + double Nbytes = sizeof(double); + base_h = new double[1]; + power_h = new double[1]; + result_h = new double[1]; + *base_h = Input_Vals_int[test_case]; + *power_h = Input_Vals_int[test_case+1]; + *result_h = 1; + HIP_CHECK(hipMalloc(&base_d, Nbytes)); + HIP_CHECK(hipMalloc(&power_d, Nbytes)); + HIP_CHECK(hipMalloc(&result_d, Nbytes)); + HIP_CHECK(hipMemcpy(base_d, base_h, Nbytes, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(power_d, power_h, Nbytes, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(result_d, result_h, Nbytes, hipMemcpyHostToDevice)); + hiprtcProgram program; + HIPRTC_CHECK(hiprtcCreateProgram(&program, denormals_string, + "denormals", 0, NULL, NULL)); + if (Combination_CO_size != -1) { + hiprtcResult compileResult{hiprtcCompileProgram(program, + Combination_CO_size, + Combination_CO)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << compiler_option); + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(program, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(program, &log[0])); + WARN(log); + } + return 0; + } + } else { + hiprtcResult compileResult{hiprtcCompileProgram(program, 1, + &compiler_option)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << compiler_option); + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(program, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(program, &log[0])); + WARN(log); + } + return 0; + } + } + size_t codeSize; + HIPRTC_CHECK(hiprtcGetCodeSize(program, &codeSize)); + std::vector codec(codeSize); + HIPRTC_CHECK(hiprtcGetCode(program, codec.data())); + void* kernelParam[] = {base_d, power_d, result_d}; + auto size = sizeof(kernelParam); + void* kernel_parameter[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &kernelParam, + HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, + HIP_LAUNCH_PARAM_END}; + hipModule_t module; + hipFunction_t function; + HIP_CHECK(hipModuleLoadData(&module, codec.data())); + HIP_CHECK(hipModuleGetFunction(&function, module, kername)); + hipError_t status = hipModuleLaunchKernel(function, 1, 1, 1, 1, 1, 1, 0, 0, + nullptr, kernel_parameter); + HIP_CHECK(hipMemcpy(result_h, result_d, sizeof(double), + hipMemcpyDeviceToHost)); + HIP_CHECK(hipDeviceSynchronize()); + HIP_CHECK(hipModuleUnload(module)); + HIPRTC_CHECK(hiprtcDestroyProgram(&program)); + if (*result_h != Expected_Results_int[res_inc]) { + WARN("Compiler Option : " << compiler_option); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("EXPECTED RESULT DOES NOT MATCH FOR " << res_inc); + WARN("th ITERATION (start iteration is 0 ) "); + WARN("INPUT : pow(2, " << *power_h << ") "); + WARN("EXPECTED OP: " << Expected_Results_int[res_inc]); + WARN("OBTAINED OP: " << *result_h); + return 0; + } + } + return 1; +} + +bool check_denormals_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "denormals"; + std::string retrieved_CO = get_string_parameters("reverse_compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + std::string kernel_name = get_string_parameters("kernel_name", block_name); + picojson::array Input_Vals = get_array_parameters("Input_Vals", block_name); + picojson::array Expected_Results_for_no = get_array_parameters( + "Expected_Results_for_no", block_name); + const char* kername = kernel_name.c_str(); + const char* compiler_option = retrieved_CO.c_str(); + int CO_size = 1; + std::vector double_vec_input; + for (auto& indx : Input_Vals) { + double_vec_input.push_back(indx.get()); + } + std::vector Input_Vals_int; + for (auto& indx : double_vec_input) { + Input_Vals_int.push_back(static_cast(indx)); + } + std::vector double_vec_expected_for_no; + for (auto& indx : Expected_Results_for_no) { + double_vec_expected_for_no.push_back(indx.get()); + } + std::vector Expected_Results_for_no_int; + for (auto& indx : double_vec_expected_for_no) { + Expected_Results_for_no_int.push_back(static_cast(indx)); + } + int pass_count = 0; + int test_case, res_inc; + for (test_case = 0, res_inc = 0; test_case < Input_Vals_int.size() && + res_inc < Expected_Results_for_no_int.size(); test_case+=2, res_inc++) { + double *base_h, *power_h, *result_h; + double *base_d, *power_d, *result_d; + double Nbytes = sizeof(double); + base_h = new double[1]; + power_h = new double[1]; + result_h = new double[1]; + *base_h = Input_Vals_int[test_case]; + *power_h = Input_Vals_int[test_case+1]; + *result_h = 0; + HIP_CHECK(hipMalloc(&base_d, Nbytes)); + HIP_CHECK(hipMalloc(&power_d, Nbytes)); + HIP_CHECK(hipMalloc(&result_d, Nbytes)); + HIP_CHECK(hipMemcpy(base_d, base_h, Nbytes, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(power_d, power_h, Nbytes, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(result_d, result_h, Nbytes, hipMemcpyHostToDevice)); + hiprtcProgram program; + HIPRTC_CHECK(hiprtcCreateProgram(&program, denormals_string, + "denormals", 0, NULL, NULL)); + if (Combination_CO_size != -1) { + hiprtcResult compileResult{hiprtcCompileProgram(program, + Combination_CO_size, + Combination_CO)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << compiler_option); + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(program, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(program, &log[0])); + WARN(log); + } + return 0; + } + } else { + hiprtcResult compileResult{hiprtcCompileProgram(program, 1, + &compiler_option)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << compiler_option); + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(program, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(program, &log[0])); + WARN(log); + } + return 0; + } + } + size_t codeSize; + HIPRTC_CHECK(hiprtcGetCodeSize(program, &codeSize)); + std::vector codec(codeSize); + HIPRTC_CHECK(hiprtcGetCode(program, codec.data())); + void* kernelParam[] = {base_d, power_d, result_d}; + auto size = sizeof(kernelParam); + void* kernel_parameter[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &kernelParam, + HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, + HIP_LAUNCH_PARAM_END}; + hipModule_t module; + hipFunction_t function; + HIP_CHECK(hipModuleLoadData(&module, codec.data())); + HIP_CHECK(hipModuleGetFunction(&function, module, kername)); + hipError_t status = hipModuleLaunchKernel(function, 1, 1, 1, 1, 1, 1, 0, 0, + nullptr, kernel_parameter); + HIP_CHECK(hipMemcpy(result_h, result_d, sizeof(double), + hipMemcpyDeviceToHost)); + HIP_CHECK(hipDeviceSynchronize()); + HIP_CHECK(hipModuleUnload(module)); + HIPRTC_CHECK(hiprtcDestroyProgram(&program)); + if (*result_h != Expected_Results_for_no_int[res_inc]) { + WARN("Compiler Option : " << compiler_option); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("EXPECTED RESULT DOES NOT MATCH FOR " << res_inc); + WARN("th ITERATION (start iteration is 0 ) "); + WARN("INPUT : pow(2, " << *power_h << ") "); + WARN("EXPECTED OP: "<< Expected_Results_for_no_int[res_inc]); + WARN("OBTAINED OP: "<< *result_h); + return 0; + } + } + return 1; +} + +bool check_ffp_contract_off(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "ffp_contract"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + picojson::array retrieved_CO = get_array_parameters("compiler_option", + block_name); + if (retrieved_CO.size() < 3) { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + std::vector CO_vec; + for (auto& indx : retrieved_CO) { + CO_vec.push_back(indx.get()); + } + int CO_IRadded_size = 3, a = 0; + const char** CO_IRadded = new const char*[3]; + std::string hold = CO_vec[0]; + CO_IRadded[0] = hold.c_str(); + CO_IRadded[1] = "-mllvm"; + CO_IRadded[2] = "-print-after=constmerge"; + std::string data = checking_IR(kername, CO_IRadded, CO_IRadded_size, + Combination_CO, Combination_CO_size); + if (data == "") { + WARN("Compiler option : " << retrieved_CO[0]); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR NOT GENERATED"); + return 0; + } + if (data.find("fmul contract") != -1 && + data.find("@llvm.fmuladd.f32") != -1) { + WARN("Compiler option : " << retrieved_CO[0]); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR CONTAIN EITHER"); + WARN("'fmul contract' or '@llvm.fmuladd.f32' or both "); + WARN("WHICH IS NOT EXPECTED"); + return 0; + } else { + return 1; + } +} + +bool check_ffp_contract_on(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "ffp_contract"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + picojson::array retrieved_CO = get_array_parameters("compiler_option", + block_name); + if (retrieved_CO.size() < 3) { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + std::vector CO_vec; + for (auto& indx : retrieved_CO) { + CO_vec.push_back(indx.get()); + } + int CO_IRadded_size = 3, a = 0; + const char** CO_IRadded = new const char*[3]; + std::string hold = CO_vec[1]; + CO_IRadded[0] = hold.c_str(); + CO_IRadded[1] = "-mllvm"; + CO_IRadded[2] = "-print-after=constmerge"; + std::string data = checking_IR(kername, CO_IRadded, + CO_IRadded_size, Combination_CO, + Combination_CO_size); + if (data == "") { + WARN("Compiler option : " << retrieved_CO[1]); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR NOT GENERATED"); + return 0; + } + if (fast_math_present!= -1) { + if (fast_math_present == 0 && data.find("@llvm.fmuladd.f32")!= -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO[1]); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN '@llvm.fmuladd.f32' "); + return 0; + } + } else { + if (data.find("@llvm.fmuladd.f32") != -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO[1]); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN '@llvm.fmuladd.f32' "); + return 0; + } + } +} + +bool check_ffp_contract_fast(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "ffp_contract"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + picojson::array retrieved_CO = get_array_parameters("compiler_option", + block_name); + if (retrieved_CO.size() < 3) { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + std::vector CO_vec; + for (auto& indx : retrieved_CO) { + CO_vec.push_back(indx.get()); + } + int CO_IRadded_size = 3, a = 0; + const char** CO_IRadded = new const char*[3]; + std::string hold = CO_vec[2]; + CO_IRadded[0] = hold.c_str(); + CO_IRadded[1] = "-mllvm"; + CO_IRadded[2] = "-print-after=constmerge"; + std::string data = checking_IR(kername, CO_IRadded, CO_IRadded_size, + Combination_CO, Combination_CO_size); + if (data == "") { + WARN("Compiler option : " << retrieved_CO[2]); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR NOT GENERATED"); + return 0; + } + if (fast_math_present!= -1) { + if (fast_math_present == 1 && data.find("contract")!= -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO[2]); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'fmul contract' "); + return 0; + } + } else { + if (data.find("fmul contract") != -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO[2]); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'fmul contract' "); + return 0; + } + } +} + +bool check_fast_math_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "fast_math"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::string retrieved_CO = get_string_parameters("compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + int CO_IRadded_size = 3, a = 0; + const char** CO_IRadded = new const char*[3]; + CO_IRadded[0] = retrieved_CO.c_str(); + CO_IRadded[1] = "-mllvm"; + CO_IRadded[2] = "-print-after=constmerge"; + std::string data = checking_IR(kername, CO_IRadded, CO_IRadded_size, + Combination_CO, Combination_CO_size); + if (data == "") { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR NOT GENERATED"); + return 0; + } + if (data.find("fmul fast")!= -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'fmul fast' "); + return 0; + } +} + +bool check_fast_math_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "fast_math"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::string retrieved_CO = get_string_parameters("reverse_compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + int CO_IRadded_size = 3, a = 0; + const char** CO_IRadded = new const char*[3]; + CO_IRadded[0] = retrieved_CO.c_str(); + CO_IRadded[1] = "-mllvm"; + CO_IRadded[2] = "-print-after=constmerge"; + std::string data = checking_IR(kername, CO_IRadded, CO_IRadded_size, + Combination_CO, Combination_CO_size); + if (data == "") { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR NOT GENERATED"); + return 0; + } + if (data.find("fmul fast")!= -1) { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'fmul fast' "); + return 0; + } else { + return 1; + } +} + +bool check_slp_vectorize_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "slp_vectorize"; + std::string retrieved_CO = get_string_parameters("compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + int CO_IRadded_size = 3, a = 0; + const char** CO_IRadded = new const char*[3]; + CO_IRadded[0] = retrieved_CO.c_str(); + CO_IRadded[1] = "-mllvm"; + CO_IRadded[2] = "-print-after=constmerge"; + __half2 *a_d, *x_d, *y_d; + __half2 a_h, x_h, *y_h; + a_h.data.x = 1.5; + x_h.data.y = 3.0; + CaptureStream capture(stderr); + HIP_CHECK(hipMalloc(&a_d, sizeof(__half2))); + HIP_CHECK(hipMalloc(&x_d, sizeof(__half2))); + HIP_CHECK(hipMalloc(&y_d, sizeof(__half2))); + HIP_CHECK(hipMemcpy(a_d, &a_h, sizeof(__half2), hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(x_d, &x_h, sizeof(__half2), hipMemcpyHostToDevice)); + hiprtcProgram prog; + HIPRTC_CHECK(hiprtcCreateProgram(&prog, slp_vectorize_string, + kername, 0, NULL, NULL)); + if (Combination_CO_size != -1) { + int Combination_CO_IRadded_size = Combination_CO_size+3; + int b = 0; + std::string add_ir_forcombi[Combination_CO_size+3]; + const char** Combination_CO_IRadded = + new const char*[Combination_CO_size+3]; + for (int i = 0; i < Combination_CO_size+3; ++i) { + if (i == Combination_CO_size) { + Combination_CO_IRadded[i] = "-fno-signed-zeros"; + Combination_CO_IRadded[i+1] = "-mllvm"; + Combination_CO_IRadded[i+2] = "-print-after=constmerge"; + break; + } + add_ir_forcombi[i] = Combination_CO[b]; + Combination_CO_IRadded[i] = add_ir_forcombi[i].c_str(); + b++; + } + capture.Begin(); + hiprtcResult compileResult{hiprtcCompileProgram(prog, + Combination_CO_IRadded_size, + Combination_CO_IRadded)}; + capture.End(); + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler option : " << retrieved_CO); + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size+3; i++) { + WARN(Combination_CO_IRadded[i]); + } + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } else { + capture.Begin(); + hiprtcResult compileResult{hiprtcCompileProgram(prog, CO_IRadded_size, + CO_IRadded)}; + capture.End(); + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler option : " << retrieved_CO); + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } + std::string data = capture.getData(); + std::stringstream dataStream; + size_t codeSize; + HIPRTC_CHECK(hiprtcGetCodeSize(prog, &codeSize)); + std::vector codec(codeSize); + HIPRTC_CHECK(hiprtcGetCode(prog, codec.data())); + void* kernelParam[] = {reinterpret_cast(a_d), + reinterpret_cast(x_d), + reinterpret_cast(y_d)}; + auto size = sizeof(kernelParam); + void* kernel_parameter[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &kernelParam, + HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, + HIP_LAUNCH_PARAM_END}; + hipModule_t module; + hipFunction_t function; + HIP_CHECK(hipModuleLoadData(&module, codec.data())); + HIP_CHECK(hipModuleGetFunction(&function, module, kername)); + HIP_CHECK(hipModuleLaunchKernel(function, 1, 1, 1, 1, 1, 1, 0, 0, nullptr, + kernel_parameter)); + HIP_CHECK(hipDeviceSynchronize()); + HIP_CHECK(hipModuleUnload(module)); + HIPRTC_CHECK(hiprtcDestroyProgram(&prog)); + if (data == "") { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR NOT GENERATED"); + return 0; + } + int times = 0; + if (data.find("contract <2 x half>", 0) != -1) { + times++; + } + int start = data.find("contract <2 x half>", 0) + 1; + while (data.find("contract <2 x half>", start) != -1) { + times++; + start = data.find("contract <2 x half>", start)+1; + } + if (times == 1) { + return 1; + } else if (times == 0) { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'fadd contract <2 x half>' "); + return 0; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR CONTAIN 'fadd contract <2 x half>' " << times << "times"); + WARN(" WHICH IS NOT EXPECTED (IT SHOULD BE PRESENT ONCE)"); + return 0; + } +} + +bool check_slp_vectorize_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "slp_vectorize"; + std::string retrieved_CO = get_string_parameters("reverse_compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME " << block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + int CO_IRadded_size = 3, a = 0; + const char** CO_IRadded = new const char*[3]; + CO_IRadded[0] = retrieved_CO.c_str(); + CO_IRadded[1] = "-mllvm"; + CO_IRadded[2] = "-print-after=constmerge"; + __half2 *a_d, *x_d, *y_d; + __half2 a_h, x_h, *y_h; + a_h.data.x = 1.5; + x_h.data.y = 3.0; + CaptureStream capture(stderr); + HIP_CHECK(hipMalloc(&a_d, sizeof(__half2))); + HIP_CHECK(hipMalloc(&x_d, sizeof(__half2))); + HIP_CHECK(hipMalloc(&y_d, sizeof(__half2))); + HIP_CHECK(hipMemcpy(a_d, &a_h, sizeof(__half2), hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(x_d, &x_h, sizeof(__half2), hipMemcpyHostToDevice)); + hiprtcProgram prog; + HIPRTC_CHECK(hiprtcCreateProgram(&prog, slp_vectorize_string, + kername, 0, NULL, NULL)); + if (Combination_CO_size != -1) { + int Combination_CO_IRadded_size = Combination_CO_size+3; + int b = 0; + std::string add_ir_forcombi[Combination_CO_size+3]; + const char** Combination_CO_IRadded = + new const char*[Combination_CO_size+3]; + for (int i = 0; i < Combination_CO_size+3; ++i) { + if (i == Combination_CO_size) { + Combination_CO_IRadded[i] = "-fno-signed-zeros"; + Combination_CO_IRadded[i+1] = "-mllvm"; + Combination_CO_IRadded[i+2] = "-print-after=constmerge"; + break; + } + add_ir_forcombi[i] = Combination_CO[b]; + Combination_CO_IRadded[i] = add_ir_forcombi[i].c_str(); + b++; + } + capture.Begin(); + hiprtcResult compileResult{hiprtcCompileProgram(prog, + Combination_CO_IRadded_size, + Combination_CO_IRadded)}; + capture.End(); + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler option : " << retrieved_CO); + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size+3; i++) { + WARN(Combination_CO_IRadded[i]); + } + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } else { + capture.Begin(); + hiprtcResult compileResult{hiprtcCompileProgram(prog, CO_IRadded_size, + CO_IRadded)}; + capture.End(); + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler option : " << retrieved_CO); + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } + std::string data = capture.getData(); + std::stringstream dataStream; + size_t codeSize; + HIPRTC_CHECK(hiprtcGetCodeSize(prog, &codeSize)); + std::vector codec(codeSize); + HIPRTC_CHECK(hiprtcGetCode(prog, codec.data())); + void* kernelParam[] = {reinterpret_cast(a_d), + reinterpret_cast(x_d), + reinterpret_cast(y_d)}; + auto size = sizeof(kernelParam); + void* kernel_parameter[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &kernelParam, + HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, + HIP_LAUNCH_PARAM_END}; + hipModule_t module; + hipFunction_t function; + HIP_CHECK(hipModuleLoadData(&module, codec.data())); + HIP_CHECK(hipModuleGetFunction(&function, module, kername)); + HIP_CHECK(hipModuleLaunchKernel(function, 1, 1, 1, 1, 1, 1, 0, 0, nullptr, + kernel_parameter)); + HIP_CHECK(hipDeviceSynchronize()); + HIP_CHECK(hipModuleUnload(module)); + HIPRTC_CHECK(hiprtcDestroyProgram(&prog)); + int times = 0; + if (data.find("contract <2 x half>", 0) != -1) { + times++; + } + int start = data.find("contract <2 x half>", 0) + 1; + while (data.find("contract <2 x half>", start) != -1) { + times++; + start = data.find("contract <2 x half>", start)+1; + } + if (times == 2) { + return 1; + } else if (times < 2) { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR CONTAIN 'fadd contract <2 x half>' " << times << "times"); + WARN(" WHICH IS NOT EXPECTED(IT SHOULD BE PRESENT TWICE)"); + return 0; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR CONTAIN 'fadd contract <2 x half>' " << times << "times"); + WARN(" WHICH IS NOT EXPECTED(IT SHOULD BE PRESENT TWICE)"); + return 0; + } +} + +bool check_macro(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "macro"; + std::string retrieved_CO = get_string_parameters("compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME " << block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + std::string kernel_name = get_string_parameters("kernel_name", block_name); + picojson::array Expected_Results = get_array_parameters("Expected_Results", + block_name); + const char* kername = kernel_name.c_str(); + std::vector double_vec_expected; + for (auto& indx : Expected_Results) { + double_vec_expected.push_back(indx.get()); + } + std::vector Expected_Results_int; + for (auto& indx : double_vec_expected) { + Expected_Results_int.push_back(static_cast(indx)); + } + const char* compiler_option = retrieved_CO.c_str(); + hiprtcProgram prog; + HIPRTC_CHECK(hiprtcCreateProgram(&prog, macro_string, + kername, 0, NULL, NULL)); + if (Combination_CO_size != -1) { + hiprtcResult compileResult{hiprtcCompileProgram(prog, Combination_CO_size, + Combination_CO)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << compiler_option); + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + WARN("hiprtcCompileProgram() api failed!! with error code: "); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } else { + hiprtcResult compileResult{hiprtcCompileProgram(prog, 1, + &compiler_option)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << compiler_option); + WARN("hiprtcCompileProgram() api failed!! with error code: "); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } + int *macro_value_h; + int *macro_value_d; + macro_value_h = new int[1]; + HIP_CHECK(hipMalloc(¯o_value_d, sizeof(int))); + *macro_value_h = 0; + HIP_CHECK(hipMemcpy(macro_value_d, macro_value_h, sizeof(int), + hipMemcpyHostToDevice)); + size_t codeSize; + HIPRTC_CHECK(hiprtcGetCodeSize(prog, &codeSize)); + std::vector codec(codeSize); + hiprtcGetCode(prog, codec.data()); + void* kernelParam[] = {macro_value_d}; + auto size = sizeof(kernelParam); + void* kernel_parameter[]={HIP_LAUNCH_PARAM_BUFFER_POINTER, &kernelParam, + HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, + HIP_LAUNCH_PARAM_END}; + hipModule_t module; + hipFunction_t function; + HIP_CHECK(hipModuleLoadData(&module, codec.data())); + HIP_CHECK(hipModuleGetFunction(&function, module, kername)); + HIP_CHECK(hipModuleLaunchKernel(function, 1, 1, 1, 1, 1, 1, 0, 0, nullptr, + kernel_parameter)); + HIP_CHECK(hipMemcpy(macro_value_h, macro_value_d, sizeof(int), + hipMemcpyDeviceToHost)); + HIP_CHECK(hipDeviceSynchronize()); + HIP_CHECK(hipModuleUnload(module)); + HIPRTC_CHECK(hiprtcDestroyProgram(&prog)); + if (*macro_value_h != Expected_Results_int[0]) { + WARN("Compiler Option : " << compiler_option); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("EXPECTED RESULT DOES NOT MATCH"); + WARN("INPUT: " << compiler_option); + WARN("EXPECTED OP : "<< Expected_Results_int[0]); + WARN("OBTAINED OP: "<< *macro_value_h); + return 0; + } else { + return 1; + } +} + +bool check_undef_macro(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "undef_macro"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + picojson::array comp_opt = get_array_parameters("compiler_option", + block_name); + if (comp_opt.size() < 2) { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME " << block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + std::vector compiler_option; + for (auto& indx : comp_opt) { + compiler_option.push_back(indx.get()); + } + std::string variable[compiler_option.size()]; + const char** appended_compiler_options = + new const char*[compiler_option.size()]; + for (int i = 0; i < compiler_option.size(); ++i) { + variable[i] = compiler_option[i]; + appended_compiler_options[i] = variable[i].c_str(); + } + hiprtcProgram prog; + HIPRTC_CHECK(hiprtcCreateProgram(&prog, undef_macro_string, + kername, 0, NULL, NULL)); + if (Combination_CO_size != -1) { + hiprtcResult compileResult{hiprtcCompileProgram(prog, Combination_CO_size, + Combination_CO)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + if (log.find("undeclared identifier")) { + return 1; + } + } else { + WARN("Compiler Option : " << appended_compiler_options[1]); + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + WARN("Expected error : 'undeclared identifier' NOT GENERATED"); + return 0; + } + } + } else { + hiprtcResult compileResult{hiprtcCompileProgram(prog, + compiler_option.size(), + appended_compiler_options)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + if (log.find("undeclared identifier")) { + return 1; + } + } else { + WARN("Compiler Option : " << appended_compiler_options[0]); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("Expected error : 'undeclared identifier' NOT GENERATED"); + return 0; + } + } + } + WARN("Compiler Option : " << appended_compiler_options[0]); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("EXPECTED ERROR WAS NOT GENERATED"); + return 0; +} + +bool check_header_dir(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "header_dir"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::string compiler_option = get_string_parameters("compiler_option", + block_name); + if (compiler_option == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + picojson::array Headers = get_array_parameters("Headers", block_name); + picojson::array depending_comp_optn = + get_array_parameters("depending_comp_optn", block_name); + picojson::array Src_headers = + get_array_parameters("Src_headers", block_name); + picojson::array Input_Thrd_Vals = + get_array_parameters("Input_Vals", block_name); + picojson::array Expected_Results = + get_array_parameters("Expected_Results", block_name); + std::string str = "pwd"; + const char *cmd = str.c_str(); + CaptureStream capture(stdout); + capture.Begin(); + system(cmd); + capture.End(); + std::string wor_dir = capture.getData(); + std::string break_dir = wor_dir.substr(0, wor_dir.find("build")); + std::string append_str = "catch/unit/rtc/headers"; + std::string CO = compiler_option + " " + break_dir + append_str; + const char* appended_CO = CO.c_str(); + std::vector Headers_list; + for (auto& indx : Headers) { + Headers_list.push_back(indx.get()); + } + std::vector Src_headers_list; + for (auto& indx : Src_headers) { + Src_headers_list.push_back(indx.get()); + } + std::vector depending_co_list; + for (auto& indx : depending_comp_optn) { + depending_co_list.push_back(indx.get()); + } + std::vector double_vec_target; + for (auto& indx : Input_Thrd_Vals) { + double_vec_target.push_back(indx.get()); + } + std::vector Input_Thrd_Vals_int; + for (auto& indx : double_vec_target) { + Input_Thrd_Vals_int.push_back(static_cast(indx)); + } + std::vector double_vec_expected; + for (auto& indx : Expected_Results) { + double_vec_expected.push_back(indx.get()); + } + std::vector Expected_Results_int; + for (auto& indx : double_vec_expected) { + Expected_Results_int.push_back(static_cast(indx)); + } + std::string src_var_hdr_lst[Src_headers_list.size()]; + const char** src_hder_lst = new const char*[Src_headers_list.size()]; + for (int i = 0; i < Src_headers_list.size(); ++i) { + src_var_hdr_lst[i] = Src_headers_list[i]; + src_hder_lst[i] = src_var_hdr_lst[i].c_str(); + } + std::string var_hdr_lst[Headers_list.size()]; + const char** hder_lst = new const char*[Headers_list.size()]; + for (int i = 0; i < Headers_list.size(); ++i) { + var_hdr_lst[i] = Headers_list[i]; + hder_lst[i] = var_hdr_lst[i].c_str(); + } + int pass_count = 0; + for (int senario = 0; senario< Input_Thrd_Vals_int.size(); senario++) { + hiprtcProgram prog; + HIPRTC_CHECK(hiprtcCreateProgram(&prog, header_dir_string, + kername, Headers_list.size(), + src_hder_lst, hder_lst)); + if (Combination_CO_size != -1) { + hiprtcResult compileResult{hiprtcCompileProgram(prog, + Combination_CO_size, + Combination_CO)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << appended_CO); + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } else { + hiprtcResult compileResult{hiprtcCompileProgram(prog, 1, + &appended_CO)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << appended_CO); + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } + size_t codeSize; + HIPRTC_CHECK(hiprtcGetCodeSize(prog, &codeSize)); + std::vector codec(codeSize); + HIPRTC_CHECK(hiprtcGetCode(prog, codec.data())); + int value_h = 0; + int* ptr_value_h = &value_h; + int input_h = Input_Thrd_Vals_int[senario]; + int* ptr_input_h = &input_h; + int* value_d; + int* input_d; + HIP_CHECK(hipMalloc(&value_d, sizeof(int))); + HIP_CHECK(hipMalloc(&input_d, sizeof(int))); + HIP_CHECK(hipMemcpy(value_d, ptr_value_h, sizeof(int), + hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(input_d, ptr_input_h, sizeof(int), + hipMemcpyHostToDevice)); + void* kernelParam[] = {value_d, input_d}; + auto size = sizeof(kernelParam); + void* kernel_parameter[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &kernelParam, + HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, + HIP_LAUNCH_PARAM_END}; + hipModule_t module; + hipFunction_t function; + HIP_CHECK(hipModuleLoadData(&module, codec.data())); + HIP_CHECK(hipModuleGetFunction(&function, module, kername)); + HIP_CHECK(hipModuleLaunchKernel(function, 1, 1, 1, 1, 1, 1, 0, 0, nullptr, + kernel_parameter)); + HIP_CHECK(hipMemcpy(ptr_value_h, value_d, sizeof(int), + hipMemcpyDeviceToHost)); + if (*ptr_value_h != Expected_Results_int[senario]) { + WARN("Compiler Option : " << appended_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN(" EXPECTED RESULT DOES NOT MATCH FOR " << senario); + WARN("th ITERATION (start iteration is 0 ) "); + WARN(" INPUT: " << Input_Thrd_Vals_int[senario]); + WARN(" EXPECTED OP: "<< Expected_Results_int[senario]); + WARN(" OBTAINED OP: "<< *ptr_value_h); + return 0; + } + HIP_CHECK(hipDeviceSynchronize()); + HIP_CHECK(hipModuleUnload(module)); + HIPRTC_CHECK(hiprtcDestroyProgram(&prog)); + } + return 1; +} + +bool check_warning(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "warning"; + std::string retrieved_CO = + get_string_parameters("compiler_option", block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME " << block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + const char* compiler_option = retrieved_CO.c_str(); + hiprtcProgram prog; + HIPRTC_CHECK(hiprtcCreateProgram(&prog, warning_string, kername, + 0, NULL, NULL)); + if (Combination_CO_size != -1) { + hiprtcResult compileResult{hiprtcCompileProgram(prog, Combination_CO_size, + Combination_CO)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << compiler_option); + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } else { + hiprtcResult compileResult{hiprtcCompileProgram(prog, 1, + &compiler_option)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << compiler_option); + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + if (-1 != log.find("#warning")) { + WARN("Compiler Option : " << compiler_option); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN(" WARNING MESSAGE IS PRINTING WHICH IS NOT SUPRESSED "); + return 0; + } else { + return 1; + } + } else { + return 1; + } +} + +bool check_Rpass_inline(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "Rpass_inline"; + std::string retrieved_CO = + get_string_parameters("compiler_option", block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME " << block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + const char* compiler_option = retrieved_CO.c_str(); + hiprtcProgram prog; + HIPRTC_CHECK(hiprtcCreateProgram(&prog, max_thread_string, + kername, 0, NULL, NULL)); + if (Combination_CO_size != -1) { + hiprtcResult compileResult{hiprtcCompileProgram(prog, Combination_CO_size, + Combination_CO)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << compiler_option); + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } else { + hiprtcResult compileResult{hiprtcCompileProgram(prog, 1, + &compiler_option)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << compiler_option); + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + if (log.find("inlined into")) { + return 1; + } else { + WARN("Compiler Option : " << compiler_option); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("EXPECTED STRING 'inlined into' IS NOT PRESENT IN LOG "); + return 0; + } + } else { + WARN("Compiler Option : " << compiler_option); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN(" LOG WITH EXPECTED STRING 'inlined into' IS NOT PRESENT "); + return 0; + } +} + +bool check_conversionerror_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "error"; + picojson::array retrieved_CO = get_array_parameters("compiler_option", + block_name); + if (retrieved_CO.size() < 4) { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::vector CO_vec; + for (auto& indx : retrieved_CO) { + CO_vec.push_back(indx.get()); + } + std::string variable = CO_vec[0]; + const char* compiler_option = variable.c_str(); + hiprtcProgram prog; + HIPRTC_CHECK(hiprtcCreateProgram(&prog, error_string, + kername, 0, NULL, NULL)); + if (Combination_CO_size != -1) { + hiprtcResult compileResult{hiprtcCompileProgram(prog, Combination_CO_size, + Combination_CO)}; + } else { + hiprtcResult compileResult{hiprtcCompileProgram(prog, 1, + &compiler_option)}; + } + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + std::string variable = "error"; + if (-1 != log.find(variable)) { + return 1; + } else { + WARN("Compiler Option : " << compiler_option); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("ERROR MSG : '" << variable <<"' NOT FOUND"); + return 0; + } + } else { + WARN("Compiler Option : " << compiler_option); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("LOG IS NOT GENERATED"); + WARN("maybe due to presence of '-w' compiler option"); + return 0; + } +} + +bool check_conversionerror_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "error"; + picojson::array retrieved_CO = get_array_parameters("compiler_option", + block_name); + if (retrieved_CO.size() < 4) { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::vector CO_vec; + for (auto& indx : retrieved_CO) { + CO_vec.push_back(indx.get()); + } + std::string variable = CO_vec[1]; + const char* compiler_option = variable.c_str(); + hiprtcProgram prog; + HIPRTC_CHECK(hiprtcCreateProgram(&prog, error_string, + kername, 0, NULL, NULL)); + if (Combination_CO_size != -1) { + hiprtcResult compileResult{hiprtcCompileProgram(prog, Combination_CO_size, + Combination_CO)}; + } else { + hiprtcResult compileResult{hiprtcCompileProgram(prog, 1, + &compiler_option)}; + }size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + if (-1 != log.find("error")) { + WARN("Compiler Option : " << compiler_option); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("LOG IS PRESENT WITH ERROR WHICH IS NOT EXPECTED : "); + WARN("maybe due to presence of '-w' compiler option"); + return 0; + } else { + return 1; + } + } else { + return 1; + } +} + +bool check_conversionwarning_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "error"; + picojson::array retrieved_CO = get_array_parameters("compiler_option", + block_name); + if (retrieved_CO.size() < 4) { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::vector CO_vec; + for (auto& indx : retrieved_CO) { + CO_vec.push_back(indx.get()); + } + std::string variable = CO_vec[2]; + const char* compiler_option = variable.c_str(); + hiprtcProgram prog; + HIPRTC_CHECK(hiprtcCreateProgram(&prog, error_string, + kername, 0, NULL, NULL)); + if (Combination_CO_size != -1) { + hiprtcResult compileResult{hiprtcCompileProgram(prog, Combination_CO_size, + Combination_CO)}; + } else { + hiprtcResult compileResult{hiprtcCompileProgram(prog, 1, + &compiler_option)}; + }size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + std::string variable = "warning"; + if (-1 != log.find(variable)) { + return 1; + } else { + WARN("Compiler Option : " << compiler_option); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("LOG DOESN'T CONTAIN WARNING AS EXP : " << compiler_option); + return 0; + } + } else { + WARN("Compiler Option : " << compiler_option); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("LOG IS NOT GENERATED"); + return 0; + } +} + +bool check_conversionwarning_disabled(const char** Combination_CO, + int Combination_CO_size, + int max_thread_pos, + int fast_math_present) { + std::string block_name = "error"; + picojson::array retrieved_CO = get_array_parameters("compiler_option", + block_name); + if (retrieved_CO.size() < 4) { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::vector CO_vec; + for (auto& indx : retrieved_CO) { + CO_vec.push_back(indx.get()); + } + std::string variable = CO_vec[3]; + const char* compiler_option = variable.c_str(); + hiprtcProgram prog; + HIPRTC_CHECK(hiprtcCreateProgram(&prog, error_string, + kername, 0, NULL, NULL)); + if (Combination_CO_size != -1) { + hiprtcResult compileResult{hiprtcCompileProgram(prog, Combination_CO_size, + Combination_CO)}; + } else { + hiprtcResult compileResult{hiprtcCompileProgram(prog, 1, + &compiler_option)}; + }size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + if (-1 != log.find("warning")) { + WARN("Compiler Option : " << compiler_option); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("WARNING IS GENERATED WHICH IS NOT EXPECTED"); + WARN(compiler_option); + return 0; + } else { + return 1; + } + } else { + return 1; + } +} + +bool check_max_thread(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "max_thread"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + std::string default_CO = get_string_parameters("kernel_name", block_name); + picojson::array Target_Thrd_Vals = get_array_parameters("Target_Vals", + block_name); + picojson::array Input_Thrd_Vals = get_array_parameters("Input_Vals", + block_name); + picojson::array Expected_Results = get_array_parameters("Expected_Results", + block_name); + const char* kername = kernel_name.c_str(); + std::string compiler_option = get_string_parameters("compiler_option", + block_name); + if (compiler_option == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + std::vector double_vec_target; + for (auto& indx : Target_Thrd_Vals) { + double_vec_target.push_back(indx.get()); + } + std::vector Target_Thrd_Vals_int; + for (auto& indx : double_vec_target) { + Target_Thrd_Vals_int.push_back(static_cast(indx)); + } + int a = 0; + std::string variable[Target_Thrd_Vals_int.size()]; + const char** appended_compiler_options = + new const char*[Target_Thrd_Vals_int.size()]; + for (int i = 0; i < Target_Thrd_Vals_int.size() ; i++) { + variable[i] = compiler_option + std::to_string(Target_Thrd_Vals_int[i]); + appended_compiler_options[i] = variable[i].c_str(); + } + std::vector double_vec_input; + for (auto& indx : Input_Thrd_Vals) { + double_vec_input.push_back(indx.get()); + } + std::vector Input_Thrd_Vals_int; + for (auto& indx : double_vec_input) { + Input_Thrd_Vals_int.push_back(static_cast(indx)); + } + std::vector double_vec_expected; + for (auto& indx : Expected_Results) { + double_vec_expected.push_back(indx.get()); + } + std::vector Expected_Results_int; + for (auto& indx : double_vec_expected) { + Expected_Results_int.push_back(static_cast(indx)); + } + int pass_count = 0; + int inc = (Input_Thrd_Vals_int.size()/Target_Thrd_Vals_int.size()); + int start = 0; + int check, test_case; + for (int senario = 0; senario < Target_Thrd_Vals_int.size(); senario++) { + if (Target_Thrd_Vals_int[senario] == 0) { + check = 0; + for (test_case = start; test_case< (start+inc); test_case++) { + if (check == Expected_Results_int[test_case]) { + pass_count++; + } + } + start+= inc; + continue; + } + hiprtcProgram prog; + HIPRTC_CHECK(hiprtcCreateProgram(&prog, max_thread_string, + kername, 0, NULL, NULL)); + if (Combination_CO_size != -1) { + std::string max_thread_string = variable[senario]; + Combination_CO[max_thread_pos] = max_thread_string.c_str(); + hiprtcResult compileResult{hiprtcCompileProgram(prog, + Combination_CO_size, + Combination_CO)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << appended_compiler_options[senario]); + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } else { + hiprtcResult compileResult{hiprtcCompileProgram(prog, 1, + &appended_compiler_options[senario])}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << appended_compiler_options[senario]); + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } + size_t codeSize; + HIPRTC_CHECK(hiprtcGetCodeSize(prog, &codeSize)); + std::vector codec(codeSize); + HIPRTC_CHECK(hiprtcGetCode(prog, codec.data())); + for (test_case = start; test_case< (start+inc); test_case++) { + int num_threads_h = 0; + int* ptr_num_threads_h = &num_threads_h; + int* Thread_count_d; + HIP_CHECK(hipMalloc(&Thread_count_d, sizeof(int))); + HIP_CHECK(hipMemcpy(Thread_count_d, ptr_num_threads_h, sizeof(int), + hipMemcpyHostToDevice)); + void* kernelParam[] = {Thread_count_d}; + auto size = sizeof(kernelParam); + void* kernel_parameter[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &kernelParam, + HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, + HIP_LAUNCH_PARAM_END}; + hipModule_t module; + hipFunction_t function; + HIP_CHECK(hipModuleLoadData(&module, codec.data())); + HIP_CHECK(hipModuleGetFunction(&function, module, kername)); + hipError_t status = hipModuleLaunchKernel(function, 1, 1, 1, + Input_Thrd_Vals_int[test_case], + 1, 1, 0, 0, nullptr, + kernel_parameter); + HIP_CHECK(hipMemcpy(ptr_num_threads_h, Thread_count_d, sizeof(int), + hipMemcpyDeviceToHost)); + if ((status == hipSuccess) && + (num_threads_h <= Target_Thrd_Vals_int[senario])) { + check = 1; + } else { + check = 0; + } + if (check != Expected_Results_int[test_case]) { + WARN("Compiler Option : " << appended_compiler_options[senario]); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + std::string max_thread_string = variable[senario]; + Combination_CO[max_thread_pos] = max_thread_string.c_str(); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("EXPECTED RESULT DOES NOT MATCH FOR " << test_case); + WARN("th ITERATION (start iteration is 0 ) "); + WARN("IP THREAD VAL: " << Input_Thrd_Vals_int[test_case]); + WARN("EXPECTED OP: "<< Expected_Results_int[test_case]); + WARN("OBTAINED OP: "<< check); + return 0; + } + HIP_CHECK(hipDeviceSynchronize()); + HIP_CHECK(hipModuleUnload(module)); + } + start+=inc; + HIPRTC_CHECK(hiprtcDestroyProgram(&prog)); + } + return 1; +} + +bool check_unsafe_atomic_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "unsafe_atomic"; + std::string compiler_option = get_string_parameters("compiler_option", + block_name); + if (compiler_option == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + const char *compiler_option_cstr = compiler_option.c_str(); + float *A_d; + int N = 1000; + float A_h[N]; + float Nbytes = N * sizeof(float); + double sum_w = 0, sum_wo = 0, sum_tocheck = 0; + for (int i = 0; i < N; i++) { + A_h[i] = 0.1f; + sum_tocheck += A_h[i] + 0.2f; + } + HIP_CHECK(hipMalloc(&A_d, Nbytes)); + HIP_CHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice)); + for (int senario = 0; senario < 2; senario ++) { + hiprtcProgram prog; + HIPRTC_CHECK(hiprtcCreateProgram(&prog, unsafe_atomic_string, + kername, 0, NULL, NULL)); + if (Combination_CO_size != -1) { + hiprtcResult compileResult{hiprtcCompileProgram(prog, + Combination_CO_size, + Combination_CO)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << compiler_option); + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } else { + hiprtcResult compileResult{hiprtcCompileProgram(prog, 1, + &compiler_option_cstr)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << compiler_option); + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } + size_t codeSize; + HIPRTC_CHECK(hiprtcGetCodeSize(prog, &codeSize)); + std::vector codec(codeSize); + HIPRTC_CHECK(hiprtcGetCode(prog, codec.data())); + void* kernelParam[] = {A_d}; + auto size = sizeof(kernelParam); + void* kernel_parameter[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &kernelParam, + HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, + HIP_LAUNCH_PARAM_END}; + hipModule_t module; + hipFunction_t function; + HIP_CHECK(hipModuleLoadData(&module, codec.data())); + HIP_CHECK(hipModuleGetFunction(&function, module, kername)); + HIP_CHECK(hipModuleLaunchKernel(function, N, 1, 1, N, 1, 1, 0, 0, + nullptr, kernel_parameter)); + HIP_CHECK(hipMemcpy(A_h, A_d, Nbytes, hipMemcpyDeviceToHost)); + for (int i = 0; i < N; i++) { + if (senario == 0) { + sum_wo += A_h[i]; + } else { + sum_w += A_h[i]; + } + } + HIP_CHECK(hipDeviceSynchronize()); + HIP_CHECK(hipModuleUnload(module)); + HIPRTC_CHECK(hiprtcDestroyProgram(&prog)); + } + if (sum_w != sum_tocheck) { + return 1; + } else { + WARN("Compiler Option : " << compiler_option); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("EXPECTED : " << sum_w << " != " << sum_tocheck); + return 0; + } +} + +bool check_unsafe_atomic_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "unsafe_atomic"; + std::string retrieved_CO = get_string_parameters("reverse_compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + const char* compiler_option = retrieved_CO.c_str(); + float *A_d; + int N = 1000; + float A_h[N]; + float Nbytes = N * sizeof(float); + double sum = 0, sum_tocheck = 0; + for (int i = 0; i < N; i++) { + A_h[i] = 0.1f; + sum_tocheck += A_h[i] + 0.2f; + } + HIP_CHECK(hipMalloc(&A_d, Nbytes)); + HIP_CHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice)); + hiprtcProgram prog; + HIPRTC_CHECK(hiprtcCreateProgram(&prog, unsafe_atomic_string, + kername, 0, NULL, NULL)); + if (Combination_CO_size != -1) { + hiprtcResult compileResult{hiprtcCompileProgram(prog, + Combination_CO_size, + Combination_CO)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << compiler_option); + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } else { + hiprtcResult compileResult{hiprtcCompileProgram(prog, 1, &compiler_option)}; + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler Option : " << compiler_option); + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return 0; + } + } + size_t codeSize; + HIPRTC_CHECK(hiprtcGetCodeSize(prog, &codeSize)); + std::vector codec(codeSize); + HIPRTC_CHECK(hiprtcGetCode(prog, codec.data())); + void* kernelParam[] = {A_d}; + auto size = sizeof(kernelParam); + void* kernel_parameter[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &kernelParam, + HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, + HIP_LAUNCH_PARAM_END}; + hipModule_t module; + hipFunction_t function; + HIP_CHECK(hipModuleLoadData(&module, codec.data())); + HIP_CHECK(hipModuleGetFunction(&function, module, kername)); + HIP_CHECK(hipModuleLaunchKernel(function, N, 1, 1, N, 1, 1, 0, 0, + nullptr, kernel_parameter)); + HIP_CHECK(hipMemcpy(A_h, A_d, Nbytes, hipMemcpyDeviceToHost)); + for (int i = 0; i < N; i++) { + sum += A_h[i]; + } + HIP_CHECK(hipDeviceSynchronize()); + HIP_CHECK(hipModuleUnload(module)); + HIPRTC_CHECK(hiprtcDestroyProgram(&prog)); + if (sum == sum_tocheck) { + return 1; + } else { + WARN("Compiler Option : " << compiler_option); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("EXPECTED RESULT IS NOT OBTAINED "); + WARN("EXPECTED RESULT: "<< sum_tocheck); + WARN("OBTAINED RESULT: "<< sum); + return 0; + } +} + +bool check_infinite_num_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "infinite_num"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::string retrieved_CO = get_string_parameters("compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + int CO_IRadded_size = 3, a = 0; + const char** CO_IRadded = new const char*[3]; + CO_IRadded[0] = retrieved_CO.c_str(); + CO_IRadded[1] = "-mllvm"; + CO_IRadded[2] = "-print-after=constmerge"; + std::string data = checking_IR(kername, CO_IRadded, CO_IRadded_size, + Combination_CO, Combination_CO_size); + if (data == "") { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR NOT GENERATED"); + return 0; + } + if (fast_math_present != -1) { + if (fast_math_present == 0 && data.find("contract") != -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'contract' "); + return 0; + } + } else { + if (data.find("ninf")!= -1) { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'ninf' "); + return 0; + } else { + return 1; + } + } +} + +bool check_infinite_num_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "infinite_num"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::string retrieved_CO = get_string_parameters("reverse_compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + int CO_IRadded_size = 3, a = 0; + const char** CO_IRadded = new const char*[3]; + CO_IRadded[0] = retrieved_CO.c_str(); + CO_IRadded[1] = "-mllvm"; + CO_IRadded[2] = "-print-after=constmerge"; + std::string data = checking_IR(kername, CO_IRadded, CO_IRadded_size, + Combination_CO, Combination_CO_size); + if (data == "") { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR NOT GENERATED"); + return 0; + } + if (fast_math_present != -1) { + if (fast_math_present == 1 && data.find("fmul fast")!= -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'fmul fast' "); + return 0; + } + } else { + if (data.find("ninf")!= -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'ninf' "); + return 0; + } + } +} + +bool check_NAN_num_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "NAN_num"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::string retrieved_CO = get_string_parameters("compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME "); + WARN(block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + int CO_IRadded_size = 3, a = 0; + const char** CO_IRadded = new const char*[3]; + CO_IRadded[0] = retrieved_CO.c_str(); + CO_IRadded[1] = "-mllvm"; + CO_IRadded[2] = "-print-after=constmerge"; + std::string data = checking_IR(kername, CO_IRadded, CO_IRadded_size, + Combination_CO, Combination_CO_size); + if (data == "") { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR NOT GENERATED"); + return 0; + } + if (fast_math_present!= -1) { + if (fast_math_present == 0 && data.find("contract")!= -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'contract' "); + return 0; + } + } else { + if (data.find("nnan")!= -1) { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'nnan' "); + return 0; + } else { + return 1; + } + } +} + +bool check_NAN_num_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "NAN_num"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::string retrieved_CO = get_string_parameters("reverse_compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME " << block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + int CO_IRadded_size = 3, a = 0; + const char** CO_IRadded = new const char*[3]; + CO_IRadded[0] = retrieved_CO.c_str(); + CO_IRadded[1] = "-mllvm"; + CO_IRadded[2] = "-print-after=constmerge"; + std::string data = checking_IR(kername, CO_IRadded, CO_IRadded_size, + Combination_CO, Combination_CO_size); + if (data == "") { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR NOT GENERATED"); + return 0; + } + if (fast_math_present!= -1) { + if (fast_math_present == 1 && data.find("fmul fast")!= -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'fmul fast' "); + return 0; + } + } else { + if (data.find("nnan")!= -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'nnan' "); + return 0; + } + } +} + +bool check_finite_math_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "finite_math"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::string retrieved_CO = get_string_parameters("compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME " << block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + int CO_IRadded_size = 3, a = 0; + const char** CO_IRadded = new const char*[3]; + CO_IRadded[0] = retrieved_CO.c_str(); + CO_IRadded[1] = "-mllvm"; + CO_IRadded[2] = "-print-after=constmerge"; + std::string data = checking_IR(kername, CO_IRadded, CO_IRadded_size, + Combination_CO, Combination_CO_size); + if (data == "") { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR NOT GENERATED"); + return 0; + } + if (fast_math_present!= -1) { + if (fast_math_present == 1 && data.find("fmul fast")!= -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'fmul fast'"); + return 0; + } + } else { + if (data.find("nnan")!= -1 && (data.find("ninf") != -1)) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'nnan' or 'ninf' or both "); + return 0; + } + } +} + +bool check_finite_math_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "finite_math"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::string retrieved_CO = get_string_parameters("reverse_compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME " << block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + int CO_IRadded_size = 3, a = 0; + const char** CO_IRadded = new const char*[3]; + CO_IRadded[0] = retrieved_CO.c_str(); + CO_IRadded[1] = "-mllvm"; + CO_IRadded[2] = "-print-after=constmerge"; + std::string data = checking_IR(kername, CO_IRadded, CO_IRadded_size, + Combination_CO, Combination_CO_size); + if (data == "") { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR NOT GENERATED"); + return 0; + } + if (fast_math_present!= -1) { + if (fast_math_present == 0 && data.find("contract")!= -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'contract'"); + return 0; + } + } else { + if (data.find("nnan")!= -1 && (data.find("ninf") != -1)) { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR CONTAIN 'nnan' or 'ninf' or both WHICH IS NOT EXPECTED "); + return 0; + } else { + return 1; + } + } +} + +bool check_associative_math_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "associative_math"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::string retrieved_CO = get_string_parameters("compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME " << block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + int CO_IRadded_size = 4, a = 0; + const char** CO_IRadded = new const char*[4]; + CO_IRadded[0] = retrieved_CO.c_str(); + CO_IRadded[1] = "-fno-signed-zeros"; + CO_IRadded[2] = "-mllvm"; + CO_IRadded[3] = "-print-after=constmerge"; + std::string data; + if (Combination_CO_size != -1) { + int Combination_CO_IRadded_size = Combination_CO_size+1; + int b = 0; + std::string add_ir_forcombi[Combination_CO_size+1]; + const char** Combination_CO_IRadded = + new const char*[Combination_CO_size+1]; + for (int i = 0; i < Combination_CO_size+1; ++i) { + if (i == Combination_CO_size) { + Combination_CO_IRadded[i] = "-fno-signed-zeros"; + break; + } + add_ir_forcombi[i] = Combination_CO[b]; + Combination_CO_IRadded[i] = add_ir_forcombi[i].c_str(); + b++; + } + data = checking_IR(kername, CO_IRadded, CO_IRadded_size, + Combination_CO_IRadded, + Combination_CO_IRadded_size); + } else { + data = checking_IR(kername, CO_IRadded, CO_IRadded_size, Combination_CO, + Combination_CO_size); + } + if (data == "") { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR NOT GENERATED"); + return 0; + } + if (fast_math_present!= -1) { + if (fast_math_present == 1 && data.find("fmul fast")!= -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'fmul fast' "); + return 0; + } + } else { + if (data.find("reassoc") != -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'reassoc' "); + WARN(data); + return 0; + } + } +} + +bool check_associative_math_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "associative_math"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::string retrieved_CO = get_string_parameters("reverse_compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME " << block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + int CO_IRadded_size = 4, a = 0; + const char** CO_IRadded = new const char*[4]; + CO_IRadded[0] = retrieved_CO.c_str(); + CO_IRadded[1] = "-fno-signed-zeros"; + CO_IRadded[2] = "-mllvm"; + CO_IRadded[3] = "-print-after=constmerge"; + std::string data; + if (Combination_CO_size != -1) { + int Combination_CO_IRadded_size = Combination_CO_size+1; + int b = 0; + std::string add_ir_forcombi[Combination_CO_size+1]; + const char** Combination_CO_IRadded = + new const char*[Combination_CO_size+1]; + for (int i = 0; i < Combination_CO_size+1; ++i) { + if (i == Combination_CO_size) { + Combination_CO_IRadded[i] = "-fno-signed-zeros"; + break; + } + add_ir_forcombi[i] = Combination_CO[b]; + Combination_CO_IRadded[i] = add_ir_forcombi[i].c_str(); + b++; + } + data = checking_IR(kername, CO_IRadded, CO_IRadded_size, + Combination_CO_IRadded, + Combination_CO_IRadded_size); + } else { + data = checking_IR(kername, CO_IRadded, CO_IRadded_size, Combination_CO, + Combination_CO_size); + } + if (data == "") { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR NOT GENERATED"); + return 0; + } + if (fast_math_present!= -1) { + if (fast_math_present == 0 && data.find("contract")!= -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'contract' "); + return 0; + } + } else { + if (data.find("reassoc")!= -1) { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR CONTAIN 'reassoc' WHICH IS NOT EXPECTED "); + return 0; + } else { + return 1; + } + } +} + +bool check_signed_zeros_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "signed_zeros"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::string retrieved_CO = get_string_parameters("compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME " << block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + int CO_IRadded_size = 3, a = 0; + const char** CO_IRadded = new const char*[3]; + CO_IRadded[0] = retrieved_CO.c_str(); + CO_IRadded[1] = "-mllvm"; + CO_IRadded[2] = "-print-after=constmerge"; + std::string data = checking_IR(kername, CO_IRadded, CO_IRadded_size, + Combination_CO, Combination_CO_size); + if (data == "") { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR NOT GENERATED"); + return 0; + } + if (fast_math_present!= -1) { + if (fast_math_present == 0 && data.find("contract")!= -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'contract' "); + return 0; + } + } else { + if (data.find("nsz") != -1) { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR CONTAIN 'nsz' WHICH IS NOT EXPECTED "); + return 0; + } else { + return 1; + } + } +} + +bool check_signed_zeros_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "signed_zeros"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::string retrieved_CO = get_string_parameters("reverse_compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME " << block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + int CO_IRadded_size = 3, a = 0; + const char** CO_IRadded = new const char*[3]; + CO_IRadded[0] = retrieved_CO.c_str(); + CO_IRadded[1] = "-mllvm"; + CO_IRadded[2] = "-print-after=constmerge"; + std::string data = checking_IR(kername, CO_IRadded, CO_IRadded_size, + Combination_CO, Combination_CO_size); + if (data == "") { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR NOT GENERATED"); + return 0; + } + if (fast_math_present!= -1) { + if (fast_math_present == 1 && data.find("fmul fast")!= -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'fmul fast' "); + return 0; + } + } else { + if (data.find("nsz") != -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN 'nsz' "); + return 0; + } + } +} + +bool check_trapping_math_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "trapping_math"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::string retrieved_CO = get_string_parameters("compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME " << block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + int CO_IRadded_size = 3, a = 0; + const char** CO_IRadded = new const char*[3]; + CO_IRadded[0] = retrieved_CO.c_str(); + CO_IRadded[1] = "-mllvm"; + CO_IRadded[2] = "-print-after=constmerge"; + std::string data = checking_IR(kername, CO_IRadded, CO_IRadded_size, + Combination_CO, Combination_CO_size); + if (data == "") { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR NOT GENERATED"); + return 0; + } + if (data.find("\"no-trapping-math\"=\"true\"") != -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN '\"no-trapping-math\"=\"true\"'"); + return 0; + } +} + +bool check_trapping_math_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present) { + std::string block_name = "trapping_math"; + std::string kernel_name = get_string_parameters("kernel_name", block_name); + const char* kername = kernel_name.c_str(); + std::string retrieved_CO = get_string_parameters("reverse_compiler_option", + block_name); + if (retrieved_CO == "") { + WARN("COMPILER OPTION NOT PROVIDED FOR BLOCK NAME " << block_name); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + return 0; + } + int CO_IRadded_size = 3, a = 0; + const char** CO_IRadded = new const char*[3]; + CO_IRadded[0] = retrieved_CO.c_str(); + CO_IRadded[1] = "-mllvm"; + CO_IRadded[2] = "-print-after=constmerge"; + std::string data = checking_IR(kername, CO_IRadded, CO_IRadded_size, + Combination_CO, Combination_CO_size); + if (data == "") { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR NOT GENERATED"); + return 0; + } + if (data.find("\"no-trapping-math\"=\"true\"") != -1) { + return 1; + } else { + WARN("Compiler option : " << retrieved_CO); + if (Combination_CO_size != -1) { + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + } + WARN("IR DOESN'T CONTAIN '\"no-trapping-math\"=\"true\"'"); + return 0; + } +} + +std::string checking_IR(const char* kername, const char** extra_CO_IRadded, + int extra_CO_IRadded_size, const char** Combination_CO, + int Combination_CO_size) { + float *A_d, *B_d, *C_d; + float *A_h, *B_h, *C_h, *result; + float Nbytes = sizeof(float); + A_h = new float[1]; + B_h = new float[1]; + C_h = new float[1]; + result = new float[1]; + for (int i = 0; i < 1; i++) { + A_h[i] = 0.1f; + B_h[i] = 0.1f; + C_h[i] = 0.1f; + result[i] = 0.2f; + } + HIP_CHECK(hipMalloc(&A_d, Nbytes)); + HIP_CHECK(hipMalloc(&B_d, Nbytes)); + HIP_CHECK(hipMalloc(&C_d, Nbytes)); + HIP_CHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(C_d, C_h, Nbytes, hipMemcpyHostToDevice)); + hiprtcProgram prog; + HIPRTC_CHECK(hiprtcCreateProgram(&prog, ffp_contract_string, + kername, 0, NULL, NULL)); + int Combination_CO_IRadded_size; + CaptureStream capture(stderr); + if (Combination_CO_size != -1) { + Combination_CO_IRadded_size = Combination_CO_size+2; + int b = 0; + std::string add_ir_forcombi[Combination_CO_size+2]; + const char** Combination_CO_IRadded = + new const char*[Combination_CO_size+2]; + for (int i = 0; i < Combination_CO_size+2; ++i) { + if (i == Combination_CO_size) { + Combination_CO_IRadded[i] = "-mllvm"; + Combination_CO_IRadded[i+1] = "-print-after=constmerge"; + break; + } + add_ir_forcombi[i] = Combination_CO[b]; + Combination_CO_IRadded[i] = add_ir_forcombi[i].c_str(); + b++; + } + capture.Begin(); + hiprtcResult compileResult{hiprtcCompileProgram(prog, + Combination_CO_IRadded_size, + Combination_CO_IRadded)}; + capture.End(); + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("Compiler option : " << extra_CO_IRadded[0]); + WARN("FAILED IN COMBINATION :"); + for (int i = 0; i < Combination_CO_size; i++) { + WARN(Combination_CO[i]); + } + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return ""; + } + } else { + capture.Begin(); + hiprtcResult compileResult{hiprtcCompileProgram(prog, + extra_CO_IRadded_size, + extra_CO_IRadded)}; + capture.End(); + if (!(compileResult == HIPRTC_SUCCESS)) { + WARN("hiprtcCompileProgram() api failed!! with error code: "); + WARN(compileResult); + size_t logSize; + HIPRTC_CHECK(hiprtcGetProgramLogSize(prog, &logSize)); + if (logSize) { + std::string log(logSize, '\0'); + HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); + WARN(log); + } + return""; + } + } + size_t codeSize; + HIPRTC_CHECK(hiprtcGetCodeSize(prog, &codeSize)); + std::vector codec(codeSize); + HIPRTC_CHECK(hiprtcGetCode(prog, codec.data())); + void* kernelParam[] = {A_d, B_d, C_d}; + auto size = sizeof(kernelParam); + void* kernel_parameter[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &kernelParam, + HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, + HIP_LAUNCH_PARAM_END}; + hipModule_t module; + hipFunction_t function; + HIP_CHECK(hipModuleLoadData(&module, codec.data())); + HIP_CHECK(hipModuleGetFunction(&function, module, kername)); + HIP_CHECK(hipModuleLaunchKernel(function, 1, 1, 1, 1, 1, 1, 0, 0, nullptr, + kernel_parameter)); + HIP_CHECK(hipMemcpy(result, C_d, Nbytes, hipMemcpyDeviceToHost)); + for (int i = 0; i< 1; i++) { + if (result[i] != ((A_h[i] * B_h[i]) + C_h[i])) { + return ""; + } + } + std::string data = capture.getData(); + std::stringstream dataStream; + HIP_CHECK(hipModuleUnload(module)); + HIPRTC_CHECK(hiprtcDestroyProgram(&prog)); + return data; +} diff --git a/catch/unit/rtc/RtcUtility.cpp b/catch/unit/rtc/RtcUtility.cpp new file mode 100644 index 0000000000..2463a73fd1 --- /dev/null +++ b/catch/unit/rtc/RtcUtility.cpp @@ -0,0 +1,507 @@ +/* +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 sindxl +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 file has definition of functions for the following functinality: + +1) get_combi_string_vec() : Retrieve the combination string which contains +contains the combination of block name which indicate the respective compiler +option seperated by ':' from RtcConfig.jason file and returns them in the +form of vectors. + +2) split_comb_string() : The combination of blockname which are seperated by +':' has to split so that their respective compiler option can be retrieved +from the json file. This functn internally calls calling_combination_function() +for each of the combination of compiler options. This function returns a +int value i.e the total failed cases in that combination which is obtained +by calling_combination_function() function. + +3) calling_combination_function() : This function takes the combination of +blockname as the input. The respective compiler option for that block name is +retrieved from the json file and store the compiler options in a array. +calling_resp_function() is called which mapps the compiler option function +which has to be called with a set of required parameters +(combination of compiler options is one among them). this function returns +the status of execution ie 1 or 0 (bool). + +4) getblock_fromconfig() : This function is used to open the RtcConfig.json +file and return the blocks. + +5) get_string_parameters() and get_array_parameters() : retrieved the +parameters of the respective block name. + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include "headers/RtcUtility.h" +#include "headers/RtcFunctions.h" +#include "headers/RtcKernels.h" +#include +#include "headers/printf_common.h" + +std::vector get_combi_string_vec() { + picojson::array combi_string = get_array_parameters("Combi_CO", + "all_compier_options"); + std::vector combi_string_list; + for (auto& indx : combi_string) { + combi_string_list.push_back(indx.get()); + } + return combi_string_list; +} + +int split_comb_string(std::string option) { + int start_collon_index = option.find(':'); + int start_index = 0; + std::vector combi_block_name; + while (start_collon_index != std::string::npos) { + std::string singleoption = option.substr(start_index, + start_collon_index - start_index); + combi_block_name.push_back(singleoption); + start_index = start_collon_index + 1; + start_collon_index = option.find(':', start_index); + } + std::string last_option = option.substr(start_index, + option.length() - start_index); + combi_block_name.push_back(last_option); + return calling_combination_function(combi_block_name); +} + +int calling_combination_function(std::vector combi_vec_list) { + int combi_size = combi_vec_list.size(); + int fast_math_present = -1, undef_present = 0; + int a = 0; + int max_thread_position; + std::string hold_CO[combi_size]; + const char** Combination_CO = new const char*[combi_size]; + picojson::array undef_compiler_option = get_array_parameters( + "compiler_option", "undef_macro"); + std::vector undef_CO_vec; + for (auto& indx : undef_compiler_option) { + undef_CO_vec.push_back(indx.get()); + } + for (int i=0; i< combi_size; i++) { + if (combi_vec_list[i] == "max_thread") { + std::string ready_CO = get_string_parameters("ready_compiler_option", + combi_vec_list[i]); + hold_CO[i] = ready_CO; + if (combi_vec_list[i] == "max_thread") { + max_thread_position = i; + } + } else if (combi_vec_list[i] == "header_dir") { + std::string retrived_CO = get_string_parameters("compiler_option", + "header_dir"); + std::string str = "pwd"; + const char *cmd = str.c_str(); + CaptureStream capture(stdout); + capture.Begin(); + system(cmd); + capture.End(); + std::string wor_dir = capture.getData(); + std::string break_dir = wor_dir.substr(0, wor_dir.find("build")); + std::string append_str = "catch/unit/rtc/headers"; + std::string CO = retrived_CO + " " + break_dir + append_str; + hold_CO[i] = CO; + } else if (combi_vec_list[i] == "architecture") { + std::string retrived_CO = get_string_parameters("compiler_option", + "architecture"); + hipDeviceProp_t prop; + HIP_CHECK(hipGetDeviceProperties(&prop, 0)); + std::string actual_architecture = prop.gcnArchName; + std::string complete_CO = retrived_CO + actual_architecture; + hold_CO[i] = complete_CO; + } else if (check_positive_CO_present(combi_vec_list[i]) == 1) { + std::string positive_CO = get_string_parameters("compiler_option", + combi_vec_list[i]); + hold_CO[i] = positive_CO; + if (combi_vec_list[i] == "fast_math") + fast_math_present = 1; + } else if (check_negative_CO_present(combi_vec_list[i]) == 1) { + std::string split_block_name = combi_vec_list[i].substr(3, + combi_vec_list[i].length() - 3); + std::string negative_CO = get_string_parameters( + "reverse_compiler_option", split_block_name); + hold_CO[i] = negative_CO; + if (split_block_name == "fast_math") + fast_math_present = 0; + } else if ( combi_vec_list[i] == "conversion_error" + || combi_vec_list[i] == "conversion_no_error" + || combi_vec_list[i] == "conversion_no_warning" + || combi_vec_list[i] == "conversion_warning") { + picojson::array compiler_option = get_array_parameters("compiler_option", + "error"); + std::vector CO_vec; + for (auto& indx : compiler_option) { + CO_vec.push_back(indx.get()); + } + if (combi_vec_list[i] == "conversion_error") { + hold_CO[i] = CO_vec[0]; + } else if (combi_vec_list[i] == "conversion_no_error") { + hold_CO[i] = CO_vec[1]; + } else if (combi_vec_list[i] == "conversion_warning") { + hold_CO[i] = CO_vec[2]; + } else if (combi_vec_list[i] == "conversion_no_warning") { + hold_CO[i] = CO_vec[3]; + } + } else if (combi_vec_list[i] == "off_ffp_contract" + || combi_vec_list[i] == "on_ffp_contract" + || combi_vec_list[i] == "fast_ffp_contract" + || combi_vec_list[i] == "pragmas_ffp_contract") { + picojson::array compiler_option = get_array_parameters("compiler_option", + "ffp_contract"); + std::vector CO_vec; + for (auto& indx : compiler_option) { + CO_vec.push_back(indx.get()); + } + if (combi_vec_list[i] == "off_ffp_contract") { + hold_CO[i] = CO_vec[0]; + } else if (combi_vec_list[i] == "on_ffp_contract") { + hold_CO[i] = CO_vec[1]; + } else if (combi_vec_list[i] == "fast_ffp_contract") { + hold_CO[i] = CO_vec[2]; + } else if (combi_vec_list[i] == "pragmas_ffp_contract") { + hold_CO[i] = CO_vec[3]; + } + } else if (combi_vec_list[i] =="undef_macro") { + hold_CO[i] = undef_CO_vec[1].c_str(); + undef_present = 1; + } else { + WARN("BLOCK NAME " << combi_vec_list[i] << " NOT PRESENT"); + } + Combination_CO[i] = hold_CO[i].c_str(); + } + int errors = 0; + for (int j = 0; j< combi_size; j++) { + std::string block_name = combi_vec_list[j].c_str(); + if (!calling_resp_function(block_name, Combination_CO, combi_size, + max_thread_position, fast_math_present)) { + errors++; + } + Combination_CO[j] = hold_CO[j].c_str(); + } + return errors; +} + +int check_positive_CO_present(std::string find_string) { + static std::vector positive_CO = {"macro", "warning", "rdc", + "denormals", "fp32_div_sqrt", + "Rpass_inline", "fast_math", + "slp_vectorize", + "amdgpu_ieee", + "unsafe_atomic", + "infinite_num", "NAN_num", + "slp_vectorize", "math_errno", + "associative_math", + "signed_zeros", "finite_math", + "trapping_math"}; + if (std::find(positive_CO.begin(), positive_CO.end(), + find_string) != positive_CO.end()) + return 1; + else + return 0; +} + +int check_negative_CO_present(std::string find_string) { + static std::vector negative_CO = {"no_fast_math", + "no_fp32_div_sqrt", + "no_denormals", + "no_slp_vectorize", + "no_amdgpu_ieee", + "no_unsafe_atomic", + "no_infinite_num", + "no_slp_vectorize", + "no_NAN_num", + "no_math_errno", + "no_associative_math", + "no_signed_zeros", + "no_finite_math", + "no_trapping_math"}; + if (std::find(negative_CO.begin(), negative_CO.end(), + find_string) != negative_CO.end()) + return 1; + else + return 0; +} + +bool calling_resp_function(const std::string block_name, + const char** Combination_CO, + int Combination_CO_size, int max_thread_position, + int fast_math_present) { + if (block_name == "max_thread") { + return check_max_thread(Combination_CO, Combination_CO_size, + max_thread_position, fast_math_present); + } else if (block_name == "architecture") { + return check_architecture(Combination_CO, Combination_CO_size, + max_thread_position, fast_math_present); + } else if (block_name == "rdc") { + return check_rdc(Combination_CO, Combination_CO_size, + max_thread_position, fast_math_present); + } else if (block_name == "denormals") { + return check_denormals_enabled(Combination_CO, Combination_CO_size, + max_thread_position, fast_math_present); + } else if (block_name == "no_denormals") { + return check_denormals_disabled(Combination_CO, Combination_CO_size, + max_thread_position, fast_math_present); + } else if (block_name == "warning") { + return check_warning(Combination_CO, Combination_CO_size, + max_thread_position, fast_math_present); + } else if (block_name == "conversion_error") { + return check_conversionerror_enabled(Combination_CO, Combination_CO_size, + max_thread_position, + fast_math_present); + } else if (block_name == "conversion_no_error") { + return check_conversionerror_disabled(Combination_CO, Combination_CO_size, + max_thread_position, + fast_math_present); + } else if (block_name == "conversion_warning") { + return check_conversionwarning_enabled(Combination_CO, Combination_CO_size, + max_thread_position, + fast_math_present); + } else if (block_name == "conversion_no_warning") { + return check_conversionwarning_disabled(Combination_CO, + Combination_CO_size, + max_thread_position, + fast_math_present); + } else if (block_name == "Rpass_inline") { + return check_Rpass_inline(Combination_CO, Combination_CO_size, + max_thread_position, fast_math_present); + } else if (block_name == "macro") { + return check_macro(Combination_CO, Combination_CO_size, + max_thread_position, fast_math_present); + } else if (block_name == "undef_macro") { + return check_undef_macro(Combination_CO, Combination_CO_size, + max_thread_position, fast_math_present); + } else if (block_name == "header_dir") { + return check_header_dir(Combination_CO, Combination_CO_size, + max_thread_position, fast_math_present); + } else if (block_name == "no_fast_math") { + return check_fast_math_disabled(Combination_CO, Combination_CO_size, + max_thread_position, fast_math_present); + } else if (block_name == "fast_math") { + return check_fast_math_enabled(Combination_CO, Combination_CO_size, + max_thread_position, fast_math_present); + } else if (block_name == "off_ffp_contract") { + return check_ffp_contract_off(Combination_CO, Combination_CO_size, + max_thread_position, fast_math_present); + } else if (block_name == "on_ffp_contract") { + return check_ffp_contract_on(Combination_CO, Combination_CO_size, + max_thread_position, fast_math_present); + } else if (block_name == "fast_ffp_contract") { + return check_ffp_contract_fast(Combination_CO, Combination_CO_size, + max_thread_position, fast_math_present); + } else if (block_name == "no_unsafe_atomic") { + return check_unsafe_atomic_disabled(Combination_CO, Combination_CO_size, + max_thread_position, + fast_math_present); + } else if (block_name == "unsafe_atomic") { + return check_unsafe_atomic_enabled(Combination_CO, Combination_CO_size, + max_thread_position, + fast_math_present); + } else if (block_name == "no_slp_vectorize") { + return check_slp_vectorize_disabled(Combination_CO, Combination_CO_size, + max_thread_position, + fast_math_present); + } else if (block_name == "slp_vectorize") { + return check_slp_vectorize_enabled(Combination_CO, Combination_CO_size, + max_thread_position, + fast_math_present); + } else if (block_name == "infinite_num") { + return check_infinite_num_enabled(Combination_CO, Combination_CO_size, + max_thread_position, + fast_math_present); + } else if (block_name == "no_infinite_num") { + return check_infinite_num_disabled(Combination_CO, Combination_CO_size, + max_thread_position, + fast_math_present); + } else if (block_name == "NAN_num") { + return check_NAN_num_enabled(Combination_CO, Combination_CO_size, + max_thread_position, fast_math_present); + } else if (block_name == "no_NAN_num") { + return check_NAN_num_disabled(Combination_CO, Combination_CO_size, + max_thread_position, fast_math_present); + } else if (block_name == "finite_math") { + return check_finite_math_enabled(Combination_CO, Combination_CO_size, + max_thread_position, fast_math_present); + } else if (block_name == "no_finite_math") { + return check_finite_math_disabled(Combination_CO, Combination_CO_size, + max_thread_position, fast_math_present); + } else if (block_name == "associative_math") { + return check_associative_math_enabled(Combination_CO, Combination_CO_size, + max_thread_position, + fast_math_present); + } else if (block_name == "no_associative_math") { + return check_associative_math_disabled(Combination_CO, Combination_CO_size, + max_thread_position, + fast_math_present); + } else if (block_name == "signed_zeros") { + return check_signed_zeros_enabled(Combination_CO, Combination_CO_size, + max_thread_position, + fast_math_present); + } else if (block_name == "no_signed_zeros") { + return check_signed_zeros_disabled(Combination_CO, Combination_CO_size, + max_thread_position, + fast_math_present); + } else if (block_name == "trapping_math") { + return check_trapping_math_enabled(Combination_CO, Combination_CO_size, + max_thread_position, + fast_math_present); + } else if (block_name == "no_trapping_math") { + return check_trapping_math_disabled(Combination_CO, Combination_CO_size, + max_thread_position, + fast_math_present); + } else { + WARN("BLOCK NAME '" << block_name << "' not found"); + return 0; + } +} + +picojson::array getblock_fromconfig() { + std::string str = "pwd"; + const char *cmd = str.c_str(); + CaptureStream capture(stdout); + capture.Begin(); + system(cmd); + capture.End(); + std::string wor_dir = capture.getData(); + std::string break_dir = wor_dir.substr(0, wor_dir.find("build")); + std::string append_str = "catch/unit/rtc/RtcConfig.json"; + std::string config_path = break_dir + append_str; + std::string returnValue = ""; + std::ifstream json_file(config_path.c_str()); + if (!json_file.is_open()) { + WARN("Error loading config.jason"); + exit(0); + } + std::string json_str((std::istreambuf_iterator(json_file)), + std::istreambuf_iterator()); + picojson::value v; + std::string err = picojson::parse(v, json_str); + if (!err.empty()) { + WARN("empty config.jason"); + exit(0); + } + picojson::array& blocks = v.get(); + return blocks; +} + +std::string get_string_parameters(std::string para_name_to_retrieve, + std::string block_name) { + std::string returnValue = ""; + picojson::array blocks = getblock_fromconfig(); + for (picojson::value& block : blocks) { + picojson::object& block_obj = block.get(); + std::string blk_name = block_obj.at("block_name").get(); + if (blk_name == block_name) { + if (para_name_to_retrieve == "compiler_option") { + std::string compiler_opt = + block_obj.at("compiler_option").get(); + returnValue += compiler_opt; + } else if (para_name_to_retrieve == "Target_Vals") { + std::string Target_Vals = + block_obj.at("Target_Vals").get(); + returnValue += Target_Vals; + } else if (para_name_to_retrieve == "kernel_name") { + std::string ker_name = block_obj.at("kernel_name").get(); + returnValue += ker_name; + } else if (para_name_to_retrieve == "reverse_compiler_option") { + std::string reverse = + block_obj.at("reverse_compiler_option").get(); + returnValue += reverse; + } else if (para_name_to_retrieve == "ready_compiler_option") { + std::string ready_CO = + block_obj.at("ready_compiler_option").get(); + returnValue += ready_CO; + } else { + WARN("REQUESTED FIELD not present : " << para_name_to_retrieve); + } + } else { + continue; + } + } + return returnValue; +} + +picojson::array get_array_parameters(std::string para_name_to_retrieve, + std::string block_name) { + std::string returnValue = ""; + picojson::array blocks = getblock_fromconfig(); + for (picojson::value& block : blocks) { + picojson::object& block_obj = block.get(); + std::string blk_name = block_obj.at("block_name").get(); + if (blk_name == block_name) { + if (para_name_to_retrieve == "Target_Vals") { + picojson::array& Target_Vals = + block_obj.at("Target_Vals").get(); + return Target_Vals; + } else if (para_name_to_retrieve == "single_CO") { + picojson::array& single_CO = + block_obj.at("single_CO").get(); + return single_CO; + } else if (para_name_to_retrieve == "Combi_CO") { + picojson::array& Combi_CO = + block_obj.at("Combi_CO").get(); + return Combi_CO; + } else if (para_name_to_retrieve == "Input_Vals") { + picojson::array& Input_Vals = + block_obj.at("Input_Vals").get(); + return Input_Vals; + } else if (para_name_to_retrieve == "Expected_Results") { + picojson::array& Expected = + block_obj.at("Expected_Results").get(); + return Expected; + } else if (para_name_to_retrieve == "Expected_Results_for_no") { + picojson::array& Expected_for_no = + block_obj.at("Expected_Results_for_no").get(); + return Expected_for_no; + } else if (para_name_to_retrieve == "compiler_option") { + picojson::array& compiler_option = + block_obj.at("compiler_option").get(); + return compiler_option; + } else if (para_name_to_retrieve == "reverse_compiler_option") { + picojson::array& reverse_compiler_option = + block_obj.at("reverse_compiler_option").get(); + return reverse_compiler_option; + } else if (para_name_to_retrieve == "Headers") { + picojson::array& Headers = + block_obj.at("Headers").get(); + return Headers; + } else if (para_name_to_retrieve == "Src_headers") { + picojson::array& Src_headers = + block_obj.at("Src_headers").get(); + return Src_headers; + } else if (para_name_to_retrieve == "depending_comp_optn") { + picojson::array& depending_comp_optn = + block_obj.at("depending_comp_optn").get(); + return depending_comp_optn; + } else { + WARN("REQUESTED FIELD not present : " << para_name_to_retrieve); + return picojson::array(); + } + } else { + continue; + } + } + WARN("REQUESTED BLOCK " << block_name << " is not present "); + return picojson::array(); +} diff --git a/catch/unit/rtc/headers/RtcFact.h b/catch/unit/rtc/headers/RtcFact.h new file mode 100644 index 0000000000..43e19bff41 --- /dev/null +++ b/catch/unit/rtc/headers/RtcFact.h @@ -0,0 +1,38 @@ +/* +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. +*/ + +/* +This file is being read by a function defined check_headers which is present in +RtcFunctions.cpp file, it requires a function named 'fact' to be present +in a separate file. The -I compiler option uses this function fact's path as an +input to find this file and access it. +*/ + +#ifndef CATCH_UNIT_RTC_HEADERS_RTCFACT_H_ +#define CATCH_UNIT_RTC_HEADERS_RTCFACT_H_ + +__device__ int fact(int num) { + int fact = 1; + for (int i = 1; i <= num; i++) { + fact *= i; + } + return fact; +} + +#endif // CATCH_UNIT_RTC_HEADERS_RTCFACT_H_ diff --git a/catch/unit/rtc/headers/RtcFunctions.h b/catch/unit/rtc/headers/RtcFunctions.h new file mode 100644 index 0000000000..46f0d27810 --- /dev/null +++ b/catch/unit/rtc/headers/RtcFunctions.h @@ -0,0 +1,178 @@ +/* +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. +*/ + +/* +The Functions defined in RtcFunctions.cpp are declared here in RtcFunctions.h. +*/ + +#ifndef CATCH_UNIT_RTC_HEADERS_RTCFUNCTIONS_H_ +#define CATCH_UNIT_RTC_HEADERS_RTCFUNCTIONS_H_ +#include + +bool check_architecture(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_rdc(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_denormals_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_denormals_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_ffp_contract_off(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_ffp_contract_on(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_ffp_contract_fast(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_fast_math_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_fast_math_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_slp_vectorize_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_slp_vectorize_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_macro(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_undef_macro(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_header_dir(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_warning(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_Rpass_inline(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_conversionerror_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_conversionerror_disabled(const char** Combination_CO, + int Combination_CO_size, + int max_thread_pos, + int fast_math_present); + +bool check_conversionwarning_enabled(const char** Combination_CO, + int Combination_CO_size, + int max_thread_pos, + int fast_math_present); + +bool check_conversionwarning_disabled(const char** Combination_CO, + int Combination_CO_size, + int max_thread_pos, + int fast_math_present); + +bool check_max_thread(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_unsafe_atomic_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_unsafe_atomic_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_infinite_num_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_infinite_num_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_NAN_num_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_NAN_num_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_finite_math_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_finite_math_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_associative_math_enabled(const char** Combination_CO, + int Combination_CO_size, + int max_thread_pos, + int fast_math_present); + +bool check_associative_math_disabled(const char** Combination_CO, + int Combination_CO_size, + int max_thread_pos, + int fast_math_present); + +bool check_signed_zeros_enabled(const char** Combination_CO, + int Combination_CO_size, + int max_thread_pos, + int fast_math_present); + +bool check_signed_zeros_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_trapping_math_enabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +bool check_trapping_math_disabled(const char** Combination_CO, + int Combination_CO_size, int max_thread_pos, + int fast_math_present); + +std::string checking_IR(const char* kername, const char** extra_CO_IRadded, + int extra_CO_IRadded_size, const char** Combination_CO, + int Combination_CO_size); + +#endif // CATCH_UNIT_RTC_HEADERS_RTCFUNCTIONS_H_ diff --git a/catch/unit/rtc/headers/RtcKernels.h b/catch/unit/rtc/headers/RtcKernels.h new file mode 100644 index 0000000000..f3ff6aac83 --- /dev/null +++ b/catch/unit/rtc/headers/RtcKernels.h @@ -0,0 +1,163 @@ +/* +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. +*/ + +/* +RtcKernels.h contains the string's with the which includes the kernel code. +They are utilized by the compiler option functions, defined in RtcFunctions.cpp +*/ + +#ifndef CATCH_UNIT_RTC_HEADERS_RTCKERNELS_H_ +#define CATCH_UNIT_RTC_HEADERS_RTCKERNELS_H_ +#include +#include +#include + +static constexpr auto max_thread_string { +R"( +extern "C" +__global__ void max_thread(int* a) { + int BD = blockDim.x; + *a = BD; +} +)"}; + +static constexpr auto denormals_string { +R"( +extern "C" +__global__ void denormals(double* base, double* power, double* result) { + float denorm = powf(*base, *power); + if (*result == 0 || *result ==1 ) + *result = (denorm==0) ? 0 : 1; + else + *result = powf(*base, *power); +} +)"}; + +static constexpr auto warning_string { +R"( +extern "C" +__global__ void warning() { + #warning "Just printing a WARNING message onto the terminal"; +} +)"}; + +static constexpr auto fp32_div_sqrt_string { +R"( +extern "C" +__global__ void fp32_div_sqrt(float* result) { + float input = 109.6209; + *result = sqrt(input); +} +)"}; + +static constexpr auto error_string { +R"( +extern "C" +__global__ void error() { + unsigned int a = -1; + unsigned int b = +1; + signed int c = -1; + signed int d = +1; +} +)"}; + +static constexpr auto macro_string { +R"( +extern "C" +__global__ void macro(int *result) { + *result = PI; +} +)"}; + +static constexpr auto undef_macro_string { +R"( +extern "C" +__global__ void undef_macro() { + int a = Z; +} +)"}; + +static constexpr auto header_dir_string { +R"( +#include "RtcFact.h" +extern "C" +__global__ void header_dir(int* a, int* val) { + *a = fact(*val); +} +)"}; + +static constexpr auto rdc_string { +R"( +extern "C" +__global__ void rdc(float* a, float* b, float* c) { + *c = *a * *b; +} +)"}; + +static constexpr auto ffp_contract_string { +R"( +extern "C" +__global__ void ffp_contract(float* a, float* b, float* c) { + *c = *a * *b + *c; +} +)"}; + +static constexpr auto slp_vectorize_string { +R"( +extern "C" +__global__ void slp_vectorize(__half2 a, __half2 x, __half2 *y) { + (*y).data.x = x.data.x + a.data.x; + (*y).data.y = x.data.y + a.data.y; +} +)"}; + +static constexpr auto unsafe_atomic_string { +R"( +extern "C" +__global__ void unsafe_atomic(float* a) { + int id = threadIdx.x + blockIdx.x * blockDim.x; + if (id < 1000) { + unsafeAtomicAdd(&a[id], 0.2f); + } +} +)"}; + +static constexpr auto amdgpu_ieee_string { +R"( +extern "C" +__global__ void amdgpu_ieee(float* a, float* b, float* c) { + *c = sqrt(*a / *b); + printf("sqrt(a * b) = %f\n", *c); +} +)"}; + +static constexpr auto associative_math_string { +R"( +extern "C" +__global__ void associative_math(int* check) { + double x = 0.1f; + double y = 0.2f; + double z = 0.3f; + if((x*y)*z != x*(y*z)) + *check = 1; + else *check = 0; +} +)"}; + +#endif // CATCH_UNIT_RTC_HEADERS_RTCKERNELS_H_ diff --git a/catch/unit/rtc/headers/RtcUtility.h b/catch/unit/rtc/headers/RtcUtility.h new file mode 100644 index 0000000000..c7fdd71372 --- /dev/null +++ b/catch/unit/rtc/headers/RtcUtility.h @@ -0,0 +1,53 @@ +/* +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. +*/ + +/* +The Functions defined in RtcUtility.cpp are declared here in RtcUtility.h. +*/ + +#ifndef CATCH_UNIT_RTC_HEADERS_RTCUTILITY_H_ +#define CATCH_UNIT_RTC_HEADERS_RTCUTILITY_H_ +#include +#include +#include + +std::vector get_combi_string_vec(); + +int split_comb_string(std::string option); + +int calling_combination_function(std::vector combi_vec_list); + +int check_positive_CO_present(std::string find_string); + +int check_negative_CO_present(std::string find_string); + +bool calling_resp_function(const std::string block_name, + const char** Combination_CO, + int Combination_CO_size, int max_thread_position, + int fast_math_present); + +picojson::array getblock_fromconfig(); + +std::string get_string_parameters(std::string para_name_to_retrieve, + std::string block_name); + +picojson::array get_array_parameters(std::string para_name_to_retrieve, + std::string block_name); + +#endif // CATCH_UNIT_RTC_HEADERS_RTCUTILITY_H_ diff --git a/catch/unit/rtc/headers/printf_common.h b/catch/unit/rtc/headers/printf_common.h new file mode 100644 index 0000000000..bd17d24f33 --- /dev/null +++ b/catch/unit/rtc/headers/printf_common.h @@ -0,0 +1,181 @@ +/* +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 CATCH_UNIT_RTC_HEADERS_PRINTF_COMMON_H_ +#define CATCH_UNIT_RTC_HEADERS_PRINTF_COMMON_H_ +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_WIN32) +#include +#else +#include +#include +#endif + +#if defined(_WIN32) +class CaptureStream { + private: + FILE* stream; + int fdPipe[2]; + int fd; + + static constexpr size_t bufferSize = 25 * 1024 * 1024; + + public: + explicit CaptureStream(FILE *original) { + stream = original; + + if (pipe(fdPipe, bufferSize, O_TEXT) != 0) { + fprintf(stderr, "pipe(3) failed with error %d\n", errno); + assert(false); + } + + if ((fd = dup(fileno(stream))) == -1) { + fprintf(stderr, "dup(1) failed with error %d\n", errno); + assert(false); + } + } + + ~CaptureStream() { + close(fd); + close(fdPipe[1]); + close(fdPipe[0]); + } + + void Begin() { + fflush(stream); + + if (dup2(fdPipe[1], fileno(stream)) == -1) { + fprintf(stderr, "dup2(2) failed with error %d\n", errno); + assert(false); + } + + setvbuf(stream, NULL, _IONBF, 0); + } + + void End() { + if (dup2(fd, fileno(stream)) == -1) { + fprintf(stderr, "dup2(2) failed with error %d\n", errno); + assert(false); + } + } + + std::string getData() { + std::string data; + data.resize(bufferSize); + + int numRead = read(fdPipe[0], const_cast(data.c_str()), bufferSize); + data[numRead] = '\0'; + + data.resize(strlen(data.c_str())); + data.shrink_to_fit(); + + return data; + } +}; +#else +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); + } + } + + void Begin() { + 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 End() { + 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); + } + } + + std::string getData() { + std::ifstream tmpFileStream(tempname); + std::stringstream strStream; + strStream << tmpFileStream.rdbuf(); + return strStream.str(); + } + + ~CaptureStream() { + if (remove(tempname) != 0) { + error(0, errno, "Error"); + assert(false); + } + } + + // Truncate the file up to size if we don't want too long log + void Truncate(size_t size) { + struct stat sb = { 0 }; + if (::stat(tempname, &sb) == -1) { + std::cout << "failed lstat " << tempname; + std::cout << "with error: " << ::strerror(errno) << std::endl; + return; + } + if (sb.st_size > size) { + if (::truncate(tempname, static_cast(size)) == -1) { + std::cout << "failed truncate " << tempname; + std::cout << "with error: " << ::strerror(errno) << std::endl; + return; + } + } + } +}; +#endif + +#define DECLARE_DATA() \ + const char *msg_short = "Carpe diem."; \ + const char *msg_long1 = "Lorem ipsum dolor sit amet, consectetur nullam. " \ + "In mollis imperdiet nibh nec ullamcorper."; \ + const char *msg_long2 = "Curabitur nec metus sit amet augue vehicula " \ + "ultrices ut id leo. Lorem ipsum dolor sit amet, " \ + "consectetur adipiscing elit amet."; + +#endif // CATCH_UNIT_RTC_HEADERS_PRINTF_COMMON_H_ diff --git a/catch/unit/rtc/hiprtcComplrOptnTesting.cc b/catch/unit/rtc/hiprtcComplrOptnTesting.cc new file mode 100644 index 0000000000..53809539cd --- /dev/null +++ b/catch/unit/rtc/hiprtcComplrOptnTesting.cc @@ -0,0 +1,244 @@ +/* +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include "headers/RtcUtility.h" +#include "headers/RtcFunctions.h" +#include "headers/RtcKernels.h" +#include "headers/printf_common.h" + +/* +Unit_hiprtcSingleComplrOptnTst is a test scenario which validates each +HIPRTC supported compiler option idividually. +*/ +// SINGLE COMPILER OPTION TESTING +const char** null = {}; +TEST_CASE("Unit_hiprtcGpuArchComplrOptnTst") { + INFO("Testing '--gpu-architecture=gfx906:sramecc+:xnack-' compiler opt") + REQUIRE(check_architecture(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcGpuRdcComplrOptnTst") { + INFO("Testing '-fgpu-rdc' compiler option") + REQUIRE(check_rdc(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcEnabledDenormalsComplrOptnTst") { + INFO("Testing '-fgpu-flush-denormals-to-zero' compiler option") + REQUIRE(check_denormals_enabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcDisabledDenormalsComplrOptnTst") { + INFO("Testing '-fno-gpu-flush-denormals-to-zero' compiler option") + REQUIRE(check_denormals_disabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcOff_ffpContractComplrOptnTst") { + INFO("Testing '-ffp-contract=off' compiler option") + REQUIRE(check_ffp_contract_off(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcOnffpContractComplrOptnTst") { + INFO("Testing '-ffp-contract=on' compiler option") + REQUIRE(check_ffp_contract_on(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcFastffpContractComplrOptnTst") { + INFO("Testing '-ffp-contract=fast' compiler option") + REQUIRE(check_ffp_contract_fast(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcEnabledFastMathComplrOptnTst") { + INFO("Testing '-ffast-math' compiler option") + REQUIRE(check_fast_math_enabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcDisabledFastMathComplrOptnTst") { + INFO("Testing '-fno-fast-math' compiler option") + REQUIRE(check_fast_math_disabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcEnabledSlpVectorizeComplrOptnTst") { + INFO("Testing '-fslp-vectorize' compiler option") + REQUIRE(check_slp_vectorize_enabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcDisabledSlpVectorizeComplrOptnTst") { + INFO("Testing '-fno-slp-vectorize' compiler option") + REQUIRE(check_slp_vectorize_disabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcDefineMacroComplrOptnTst") { + INFO("Testing '-D' compiler option") + REQUIRE(check_macro(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcUndefMacroComplrOptnTst") { + INFO("Testing '-U' compiler option") + REQUIRE(check_undef_macro(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcHeaderDirectoryComplrOptnTst") { + INFO("Testing '-I' compiler option") + REQUIRE(check_header_dir(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcWarningComplrOptnTst") { + INFO("Testing '-w' compiler option") + REQUIRE(check_warning(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcRpassInlineComplrOptnTst") { + INFO("Testing '-Rpass=inline' compiler option") + REQUIRE(check_Rpass_inline(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcEnabledConversionErrComplrOptnTst") { + INFO("Testing '-Werror=conversion' compiler option") + REQUIRE(check_conversionerror_enabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcDisabledConversionErrComplrOptnTst") { + INFO("Testing '-Wno-error=conversion' compiler option") + REQUIRE(check_conversionerror_disabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcEnabledConversionWarningComplrOptnTst") { + INFO("Testing '-Wconversion' compiler option") + REQUIRE(check_conversionwarning_enabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcDisabledConversionWarningComplrOptnTst") { + INFO("Testing '-Wno-conversion' compiler option") + REQUIRE(check_conversionwarning_disabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcGpuMaxThreadPerBlockComplrOptnTst") { + INFO("Testing '--gpu-max-threads-per-block=n' compiler option") + REQUIRE(check_max_thread(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcEnabledUnsafeAtomicComplrOptnTst") { + INFO("Testing '-munsafe-fp-atomics' compiler option") + REQUIRE(check_unsafe_atomic_enabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcDisabledUnsafeAtomicComplrOptnTst") { + INFO("Testing '-mno-unsafe-fp-atomics' compiler option") + REQUIRE(check_unsafe_atomic_disabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcEnabledInfiniteNumComplrOptnTst") { + INFO("Testing '-fhonor-infinities' compiler option") + REQUIRE(check_infinite_num_enabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcDisabledInfiniteNumComplrOptnTst") { + INFO("Testing '-fno-honor-infinities' compiler option") + REQUIRE(check_infinite_num_disabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcEnabledNANComplrOptnTst") { + INFO("Testing '-fhonor-nans' compiler option") + REQUIRE(check_NAN_num_enabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcDisabledNANComplrOptnTst") { + INFO("Testing '-fno-honor-nans' compiler option") + REQUIRE(check_NAN_num_disabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcEnabledFiniteMathComplrOptnTst") { + INFO("Testing '-ffinite-math-only' compiler option") + REQUIRE(check_finite_math_enabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcDisabledFiniteMathComplrOptnTst") { + INFO("Testing '-fno-finite-math-only' compiler option") + REQUIRE(check_finite_math_disabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcEnabledAssociativeMathComplrOptnTst") { + INFO("Testing '-fassociative-math' compiler option") + REQUIRE(check_associative_math_enabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcDisabledAssociativeMathComplrOptnTst") { + INFO("Testing '-fno-associative-math' compiler option") + REQUIRE(check_associative_math_disabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcEnabledSignedZerosComplrOptnTst") { + INFO("Testing '-fsigned-zeros' compiler option") + REQUIRE(check_signed_zeros_enabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcDisabledSignedZerosComplrOptnTst") { + INFO("Testing '-fno-signed-zeros' compiler option") + REQUIRE(check_signed_zeros_disabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcEnabledTrappingMathComplrOptnTst") { + INFO("Testing '-ftrapping-math' compiler option") + REQUIRE(check_trapping_math_enabled(null, -1, -1, -1)); +} + +TEST_CASE("Unit_hiprtcDisabledTrappingMathComplrOptnTst") { + INFO("Testing '-fno-trapping-math' compiler option") + REQUIRE(check_trapping_math_disabled(null, -1, -1, -1)); +} + +/* +Unit_hiprtcCombiComplrOptnTst is a test scenario which validates +a combination of HIPRTC supported compiler options which a retrieved from +RtcConfig.jason file. +*/ + +TEST_CASE("Unit_hiprtcCombiComplrOptnTst") { + // COMBINATION COMPILER OPTIONS + std::vector CombiCompOptions = get_combi_string_vec(); + int TotalCombos = CombiCompOptions.size(); + REQUIRE(TotalCombos != -1); + /* + use '-Werror=conversion' and '-Wconversion' compiler option individually as + the generate ERROR and WARNING message which might effect when used in + combination. + + These can be used only if the ERROR and WARNING messages are required. + '-fgpu-rdc' has to be tested in ISOLATION, cannot be validated with + combi compiler options. + */ + int TotalErrors = 0; + for (int i = 0; i < TotalCombos; i++) { + std::string one_combi = CombiCompOptions[i]; + TotalErrors += split_comb_string(one_combi); + } + if (TotalErrors) { + WARN("TOTAL FAILED CASES : " << TotalErrors); + } + REQUIRE(!TotalErrors); +} From cf174d5a470946c9c836a3e7394b47b50e826431 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Mon, 14 Aug 2023 21:17:55 +0530 Subject: [PATCH 15/30] SWDEV-403471 - [catch2][dtest] Converting perftests-memory files from HIT to catch2 (#342) Change-Id: I13d2513f31dffe0b280039c888a97cc0d7bba31f --- catch/CMakeLists.txt | 1 + catch/perftests/CMakeLists.txt | 24 + catch/perftests/memory/CMakeLists.txt | 47 ++ .../memory/hipPerfBufferCopyRectSpeed.cc | 242 ++++++++ .../memory/hipPerfBufferCopySpeed.cc | 258 +++++++++ .../memory/hipPerfDevMemReadSpeed.cc | 154 +++++ .../memory/hipPerfDevMemWriteSpeed.cc | 147 +++++ .../perftests/memory/hipPerfHostNumaAlloc.cc | 191 ++++++ catch/perftests/memory/hipPerfMemFill.cc | 545 ++++++++++++++++++ .../memory/hipPerfMemMallocCpyFree.cc | 144 +++++ catch/perftests/memory/hipPerfMemcpy.cc | 118 ++++ catch/perftests/memory/hipPerfMemset.cc | 419 ++++++++++++++ catch/perftests/memory/hipPerfSampleRate.cc | 311 ++++++++++ .../memory/hipPerfSharedMemReadSpeed.cc | 262 +++++++++ 14 files changed, 2863 insertions(+) create mode 100644 catch/perftests/CMakeLists.txt create mode 100644 catch/perftests/memory/CMakeLists.txt create mode 100644 catch/perftests/memory/hipPerfBufferCopyRectSpeed.cc create mode 100644 catch/perftests/memory/hipPerfBufferCopySpeed.cc create mode 100644 catch/perftests/memory/hipPerfDevMemReadSpeed.cc create mode 100644 catch/perftests/memory/hipPerfDevMemWriteSpeed.cc create mode 100644 catch/perftests/memory/hipPerfHostNumaAlloc.cc create mode 100644 catch/perftests/memory/hipPerfMemFill.cc create mode 100644 catch/perftests/memory/hipPerfMemMallocCpyFree.cc create mode 100644 catch/perftests/memory/hipPerfMemcpy.cc create mode 100644 catch/perftests/memory/hipPerfMemset.cc create mode 100644 catch/perftests/memory/hipPerfSampleRate.cc create mode 100644 catch/perftests/memory/hipPerfSharedMemReadSpeed.cc diff --git a/catch/CMakeLists.txt b/catch/CMakeLists.txt index e34f59180d..8f7aa92624 100644 --- a/catch/CMakeLists.txt +++ b/catch/CMakeLists.txt @@ -241,6 +241,7 @@ add_subdirectory(kernels ${CATCH_BUILD_DIR}/kernels) add_subdirectory(hipTestMain ${CATCH_BUILD_DIR}/hipTestMain) add_subdirectory(stress ${CATCH_BUILD_DIR}/stress) add_subdirectory(TypeQualifiers ${CATCH_BUILD_DIR}/TypeQualifiers) +add_subdirectory(perftests ${CATCH_BUILD_DIR}/perftests) if(UNIX) add_subdirectory(multiproc ${CATCH_BUILD_DIR}/multiproc) endif() diff --git a/catch/perftests/CMakeLists.txt b/catch/perftests/CMakeLists.txt new file mode 100644 index 0000000000..be81c63a12 --- /dev/null +++ b/catch/perftests/CMakeLists.txt @@ -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 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. + +add_custom_target(perf_test COMMAND "${CMAKE_CTEST_COMMAND}" -R "Perf_" + COMMENT "Build complete, now executing the performnce test ...") + +add_subdirectory(memory) diff --git a/catch/perftests/memory/CMakeLists.txt b/catch/perftests/memory/CMakeLists.txt new file mode 100644 index 0000000000..542fdfe3f8 --- /dev/null +++ b/catch/perftests/memory/CMakeLists.txt @@ -0,0 +1,47 @@ +# 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. + +set(TEST_SRC + hipPerfMemcpy.cc + hipPerfBufferCopyRectSpeed.cc + hipPerfBufferCopySpeed.cc + hipPerfDevMemReadSpeed.cc + hipPerfDevMemWriteSpeed.cc + hipPerfMemFill.cc + hipPerfMemMallocCpyFree.cc + hipPerfMemset.cc + hipPerfSampleRate.cc + hipPerfSharedMemReadSpeed.cc +) + +if(HIP_PLATFORM MATCHES "amd") + set(TEST_SRC + ${TEST_SRC} + hipPerfHostNumaAlloc.cc) + +hip_add_exe_to_target(NAME perfMemoryTest + TEST_SRC ${TEST_SRC} + TEST_TARGET_NAME perf_test + LINKER_LIBS numa) +else() +hip_add_exe_to_target(NAME perfMemoryTest + TEST_SRC ${TEST_SRC} + TEST_TARGET_NAME perf_test) +endif() diff --git a/catch/perftests/memory/hipPerfBufferCopyRectSpeed.cc b/catch/perftests/memory/hipPerfBufferCopyRectSpeed.cc new file mode 100644 index 0000000000..2676140a15 --- /dev/null +++ b/catch/perftests/memory/hipPerfBufferCopyRectSpeed.cc @@ -0,0 +1,242 @@ +/* +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 hipMemcpy2DAsync hipMemcpy2DAsync +* @{ +* @ingroup perfMemoryTest +* `hipMemcpy2DAsync(void* dst, size_t dpitch, const void* src, size_t spitch, +* size_t width, size_t height, hipMemcpyKind kind, hipStream_t stream = 0)` - +* Copies data between host and device. +*/ + +#include + +#define NUM_SIZES 8 +// 4KB, 8KB, 64KB, 256KB, 1 MB, 4MB, 16 MB, 16MB+10 +static const unsigned int Sizes[NUM_SIZES] = + {4096, 8192, 65536, 262144, 1048576, 4194304, 16777216, 16777216+10}; + +static const unsigned int Iterations[2] = {1, 1000}; + +#define BUF_TYPES 4 +// 16 ways to combine 4 different buffer types +#define NUM_SUBTESTS (BUF_TYPES*BUF_TYPES) + +static void setData(void *ptr, unsigned int size, char value) { + char *ptr2 = reinterpret_cast(ptr); + for (unsigned int i = 0; i < size ; i++) { + ptr2[i] = value; + } +} + +static bool hipPerfBufferCopyRectSpeed_test(int p_tests) { + unsigned int bufSize_; + unsigned int numIter; + bool hostMalloc[2] = {false}; + bool hostRegister[2] = {false}; + bool unpinnedMalloc[2] = {false}; + void *memptr[2] = {NULL}; + void *alignedmemptr[2] = {NULL}; + void *srcBuffer = NULL; + void *dstBuffer = NULL; + + int numTests = (p_tests == -1) ? (NUM_SIZES*NUM_SUBTESTS*2 - 1) : p_tests; + int test = (p_tests == -1) ? 0 : p_tests; + + for ( ; test <= numTests ; test++ ) { + unsigned int srcTest = (test / NUM_SIZES) % BUF_TYPES; + unsigned int dstTest = (test / (NUM_SIZES*BUF_TYPES)) % BUF_TYPES; + bufSize_ = Sizes[test % NUM_SIZES]; + hostMalloc[0] = hostMalloc[1] = false; + hostRegister[0] = hostRegister[1] = false; + unpinnedMalloc[0] = unpinnedMalloc[1] = false; + srcBuffer = dstBuffer = 0; + memptr[0] = memptr[1] = 0; + alignedmemptr[0] = alignedmemptr[1] = NULL; + + size_t width = static_cast(sqrt(static_cast(bufSize_))); + + if (srcTest == 3) { + hostRegister[0] = true; + } else if (srcTest == 2) { + hostMalloc[0] = true; + } else if (srcTest == 1) { + unpinnedMalloc[0] = true; + } + + if (dstTest == 1) { + unpinnedMalloc[1] = true; + } else if (dstTest == 2) { + hostMalloc[1] = true; + } else if (dstTest == 3) { + hostRegister[1] = true; + } + + numIter = Iterations[test / (NUM_SIZES * NUM_SUBTESTS)]; + + if (hostMalloc[0]) { + HIP_CHECK(hipHostMalloc(reinterpret_cast(&srcBuffer), + bufSize_, 0)); + setData(srcBuffer, bufSize_, 0xd0); + } else if (hostRegister[0]) { + memptr[0] = malloc(bufSize_ + 4096); + alignedmemptr[0] = reinterpret_cast(memptr[0]); + srcBuffer = alignedmemptr[0]; + setData(srcBuffer, bufSize_, 0xd0); + HIP_CHECK(hipHostRegister(srcBuffer, bufSize_, 0)); + } else if (unpinnedMalloc[0]) { + memptr[0] = malloc(bufSize_ + 4096); + alignedmemptr[0] = reinterpret_cast(memptr[0]); + srcBuffer = alignedmemptr[0]; + setData(srcBuffer, bufSize_, 0xd0); + } else { + HIP_CHECK(hipMalloc(&srcBuffer, bufSize_)); + HIP_CHECK(hipMemset(srcBuffer, 0xd0, bufSize_)); + } + + if (hostMalloc[1]) { + HIP_CHECK(hipHostMalloc(reinterpret_cast(&dstBuffer), + bufSize_, 0)); + } else if (hostRegister[1]) { + memptr[1] = malloc(bufSize_ + 4096); + alignedmemptr[1] = reinterpret_cast(memptr[0]); + dstBuffer = alignedmemptr[1]; + HIP_CHECK(hipHostRegister(dstBuffer, bufSize_, 0)); + } else if (unpinnedMalloc[1]) { + memptr[1] = malloc(bufSize_ + 4096); + alignedmemptr[1] = reinterpret_cast(memptr[0]); + dstBuffer = alignedmemptr[1]; + } else { + HIP_CHECK(hipMalloc(&dstBuffer, bufSize_)); + } + + // warm up + HIP_CHECK(hipMemcpy2D(dstBuffer, width, srcBuffer, + width, width, width, hipMemcpyDefault)); + + // measure performance based on host time + auto all_start = std::chrono::steady_clock::now(); + + for (unsigned int i = 0; i < numIter; i++) { + HIP_CHECK(hipMemcpy2DAsync(dstBuffer, width, srcBuffer, + width, width, width, hipMemcpyDefault, NULL)); + } + HIP_CHECK(hipDeviceSynchronize()); + + auto all_end = std::chrono::steady_clock::now(); + std::chrono::duration elapsed_secs = all_end - all_start; + + // read speed in GB/s + double perf = (static_cast(bufSize_ * numIter) * + static_cast(1e-09)) / elapsed_secs.count(); + + const char *strSrc = NULL; + const char *strDst = NULL; + if (hostMalloc[0]) + strSrc = "hHM"; + else if (hostRegister[0]) + strSrc = "hHR"; + else if (unpinnedMalloc[0]) + strSrc = "unp"; + else + strSrc = "hM"; + + if (hostMalloc[1]) + strDst = "hHM"; + else if (hostRegister[1]) + strDst = "hHR"; + else if (unpinnedMalloc[1]) + strDst = "unp"; + else + strDst = "hM"; + + // Double results when src and dst are both on device + if ((!hostMalloc[0] && !hostRegister[0] && !unpinnedMalloc[0]) && + (!hostMalloc[1] && !hostRegister[1] && !unpinnedMalloc[1])) + perf *= 2.0; + // Double results when src and dst are both in sysmem + if ((hostMalloc[0] || hostRegister[0] || unpinnedMalloc[0]) && + (hostMalloc[1] || hostRegister[1] || unpinnedMalloc[1])) + perf *= 2.0; + + INFO("hipPerfBufferCopyRectSpeed[" << test << "]\t( " << bufSize_ << + ")\ts:" << strSrc << " d:" << strDst << "\ti:" << numIter << + "\t(GB/s) perf\t" << (float)perf); + + // Free src + if (hostMalloc[0]) { + HIP_CHECK(hipHostFree(srcBuffer)); + } else if (hostRegister[0]) { + HIP_CHECK(hipHostUnregister(srcBuffer)); + free(memptr[0]); + } else if (unpinnedMalloc[0]) { + free(memptr[0]); + } else { + HIP_CHECK(hipFree(srcBuffer)); + } + + // Free dst + if (hostMalloc[1]) { + HIP_CHECK(hipHostFree(dstBuffer)); + } else if (hostRegister[1]) { + HIP_CHECK(hipHostUnregister(dstBuffer)); + free(memptr[1]); + } else if (unpinnedMalloc[1]) { + free(memptr[1]); + } else { + HIP_CHECK(hipFree(dstBuffer)); + } + } + return true; +} + +/** +* Test Description +* ------------------------ +*  - Verify hipPerfBufferCopy status. +* Test source +* ------------------------ +*  - perftests/memory/hipPerfBufferCopyRectSpeed.cc +* Test requirements +* ------------------------ +*  - HIP_VERSION >= 5.6 +*/ + +TEST_CASE("Perf_hipPerfBufferCopyRectSpeed_test") { + int numDevices = 0; + HIP_CHECK(hipGetDeviceCount(&numDevices)); + + if (numDevices <= 0) { + SUCCEED("Skipped testcase hipPerfBufferCopyRectSpeed" + "as there is no device to test."); + } else { + int deviceId = 0; + HIP_CHECK(hipSetDevice(deviceId)); + hipDeviceProp_t props = {0}; + HIP_CHECK(hipGetDeviceProperties(&props, deviceId)); + + INFO("hipPerfBufferCopyRectSpeed - info: Set device to " << deviceId + << " : " << props.name << "Legend: unp - unpinned(malloc)," + " hM - hipMalloc(device)\n hHR - hipHostRegister(pinned)," + " hHM - hipHostMalloc(prePinned)\n"); + + REQUIRE(true == hipPerfBufferCopyRectSpeed_test(1)); + } +} diff --git a/catch/perftests/memory/hipPerfBufferCopySpeed.cc b/catch/perftests/memory/hipPerfBufferCopySpeed.cc new file mode 100644 index 0000000000..f9201bd672 --- /dev/null +++ b/catch/perftests/memory/hipPerfBufferCopySpeed.cc @@ -0,0 +1,258 @@ +/* +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 hipMemcpyAsync hipMemcpyAsync +* @{ +* @ingroup perfMemoryTest +* `hipMemcpyAsync(void* dst, const void* src, size_t count, +* hipMemcpyKind kind, hipStream_t stream = 0)` - +* Copies data between host and device. +*/ + +#include + +#define NUM_SIZES 9 +// 4KB, 8KB, 64KB, 256KB, 1 MB, 4MB, 16 MB, 16MB+10 +static const unsigned int Sizes[NUM_SIZES] = + {4096, 8192, 65536, 262144, 524288, 1048576, 4194304, 16777216, 16777216+10}; + +static const unsigned int Iterations[2] = {1, 1000}; + +#define BUF_TYPES 4 +// 16 ways to combine 4 different buffer types +#define NUM_SUBTESTS (BUF_TYPES*BUF_TYPES) + +static void setData(void *ptr, unsigned int size, char value) { + char *ptr2 = reinterpret_cast(ptr); + for (unsigned int i = 0; i < size ; i++) { + ptr2[i] = value; + } +} + +static void checkData(void *ptr, unsigned int size, char value) { + char *ptr2 = reinterpret_cast(ptr); + for (unsigned int i = 0; i < size; i++) { + if (ptr2[i] != value) { + INFO("Validation failed at " << i << " Got " << ptr2[i] << + " Expected " << value); + REQUIRE(false); + } + } +} + +static bool hipPerfBufferCopySpeed_test(int p_tests) { + unsigned int bufSize_; + unsigned int numIter; + bool hostMalloc[2] = {false}; + bool hostRegister[2] = {false}; + bool unpinnedMalloc[2] = {false}; + void *memptr[2] = {NULL}; + void *alignedmemptr[2] = {NULL}; + void *srcBuffer = NULL; + void *dstBuffer = NULL; + + int numTests = (p_tests == -1) ? (NUM_SIZES*NUM_SUBTESTS*2 - 1) : p_tests; + int test = (p_tests == -1) ? 0 : p_tests; + + for ( ; test <= numTests; test++ ) { + unsigned int srcTest = (test / NUM_SIZES) % BUF_TYPES; + unsigned int dstTest = (test / (NUM_SIZES*BUF_TYPES)) % BUF_TYPES; + bufSize_ = Sizes[test % NUM_SIZES]; + hostMalloc[0] = hostMalloc[1] = false; + hostRegister[0] = hostRegister[1] = false; + unpinnedMalloc[0] = unpinnedMalloc[1] = false; + srcBuffer = dstBuffer = 0; + memptr[0] = memptr[1] = NULL; + alignedmemptr[0] = alignedmemptr[1] = NULL; + + if (srcTest == 3) { + hostRegister[0] = true; + } else if (srcTest == 2) { + hostMalloc[0] = true; + } else if (srcTest == 1) { + unpinnedMalloc[0] = true; + } + + if (dstTest == 1) { + unpinnedMalloc[1] = true; + } else if (dstTest == 2) { + hostMalloc[1] = true; + } else if (dstTest == 3) { + hostRegister[1] = true; + } + + numIter = Iterations[test / (NUM_SIZES * NUM_SUBTESTS)]; + + if (hostMalloc[0]) { + HIP_CHECK(hipHostMalloc(reinterpret_cast(&srcBuffer), + bufSize_, 0)); + setData(srcBuffer, bufSize_, 0xd0); + } else if (hostRegister[0]) { + memptr[0] = malloc(bufSize_ + 4096); + alignedmemptr[0] = reinterpret_cast(memptr[0]); + srcBuffer = alignedmemptr[0]; + setData(srcBuffer, bufSize_, 0xd0); + HIP_CHECK(hipHostRegister(srcBuffer, bufSize_, 0)); + } else if (unpinnedMalloc[0]) { + memptr[0] = malloc(bufSize_ + 4096); + alignedmemptr[0] = reinterpret_cast(memptr[0]); + srcBuffer = alignedmemptr[0]; + setData(srcBuffer, bufSize_, 0xd0); + } else { + HIP_CHECK(hipMalloc(&srcBuffer, bufSize_)); + HIP_CHECK(hipMemset(srcBuffer, 0xd0, bufSize_)); + } + + if (hostMalloc[1]) { + HIP_CHECK(hipHostMalloc(reinterpret_cast(&dstBuffer), + bufSize_, 0)); + } else if (hostRegister[1]) { + memptr[1] = malloc(bufSize_ + 4096); + alignedmemptr[1] = reinterpret_cast(memptr[1]); + dstBuffer = alignedmemptr[1]; + HIP_CHECK(hipHostRegister(dstBuffer, bufSize_, 0)); + } else if (unpinnedMalloc[1]) { + memptr[1] = malloc(bufSize_ + 4096); + alignedmemptr[1] = reinterpret_cast(memptr[1]); + dstBuffer = alignedmemptr[1]; + } else { + HIP_CHECK(hipMalloc(&dstBuffer, bufSize_)); + } + + // warm up + HIP_CHECK(hipMemcpy(dstBuffer, srcBuffer, bufSize_, hipMemcpyDefault)); + + // measure performance based on host time + auto all_start = std::chrono::steady_clock::now(); + + for (unsigned int i = 0; i < numIter; i++) { + HIP_CHECK(hipMemcpyAsync(dstBuffer, srcBuffer, bufSize_, + hipMemcpyDefault, NULL)); + } + HIP_CHECK(hipDeviceSynchronize()); + + auto all_end = std::chrono::steady_clock::now(); + std::chrono::duration elapsed_secs = all_end - all_start; + + // read speed in GB/s + double perf = (static_cast(bufSize_ * numIter) * + static_cast(1e-09)) / elapsed_secs.count(); + + const char *strSrc = NULL; + const char *strDst = NULL; + if (hostMalloc[0]) + strSrc = "hHM"; + else if (hostRegister[0]) + strSrc = "hHR"; + else if (unpinnedMalloc[0]) + strSrc = "unp"; + else + strSrc = "hM"; + + if (hostMalloc[1]) + strDst = "hHM"; + else if (hostRegister[1]) + strDst = "hHR"; + else if (unpinnedMalloc[1]) + strDst = "unp"; + else + strDst = "hM"; + + // Double results when src and dst are both on device + if ((!hostMalloc[0] && !hostRegister[0] && !unpinnedMalloc[0]) && + (!hostMalloc[1] && !hostRegister[1] && !unpinnedMalloc[1])) + perf *= 2.0; + // Double results when src and dst are both in sysmem + if ((hostMalloc[0] || hostRegister[0] || unpinnedMalloc[0]) && + (hostMalloc[1] || hostRegister[1] || unpinnedMalloc[1])) + perf *= 2.0; + + INFO("HIPPerfBufferCopySpeed[" << test << "]\t( " << bufSize_ << + ")\ts:" << strSrc << " d:" << strDst << "\ti:" << numIter << + "\t(GB/s) perf\t" << (float)perf); + + // Verification + void* temp = malloc(bufSize_ + 4096); + void* chkBuf = reinterpret_cast(temp); + HIP_CHECK(hipMemcpy(chkBuf, dstBuffer, bufSize_, hipMemcpyDefault)); + checkData(chkBuf, bufSize_, 0xd0); + free(temp); + + // Free src + if (hostMalloc[0]) { + HIP_CHECK(hipHostFree(srcBuffer)); + } else if (hostRegister[0]) { + HIP_CHECK(hipHostUnregister(srcBuffer)); + free(memptr[0]); + } else if (unpinnedMalloc[0]) { + free(memptr[0]); + } else { + HIP_CHECK(hipFree(srcBuffer)); + } + + // Free dst + if (hostMalloc[1]) { + HIP_CHECK(hipHostFree(dstBuffer)); + } else if (hostRegister[1]) { + HIP_CHECK(hipHostUnregister(dstBuffer)); + free(memptr[1]); + } else if (unpinnedMalloc[1]) { + free(memptr[1]); + } else { + HIP_CHECK(hipFree(dstBuffer)); + } + } + + return true; +} + +/** +* Test Description +* ------------------------ +*  - Verify hipPerfBufferCopySpeed status. +* Test source +* ------------------------ +*  - perftests/memory/hipPerfBufferCopySpeed.cc +* Test requirements +* ------------------------ +*  - HIP_VERSION >= 5.6 +*/ + +TEST_CASE("Perf_hipPerfBufferCopySpeed_test") { + int numDevices = 0; + HIP_CHECK(hipGetDeviceCount(&numDevices)); + + if (numDevices <= 0) { + SUCCEED("Skipped testcase hipPerfBufferCopySpeed as" + "there is no device to test."); + } else { + int deviceId = 0; + HIP_CHECK(hipSetDevice(deviceId)); + hipDeviceProp_t props = {0}; + HIP_CHECK(hipGetDeviceProperties(&props, deviceId)); + + INFO("hipPerfBufferCopySpeed - info: Set device to " << deviceId + << " : " << props.name << "Legend: unp - unpinned(malloc)," + " hM - hipMalloc(device)\n hHR - hipHostRegister(pinned)," + " hHM - hipHostMalloc(prePinned)\n"); + + REQUIRE(true == hipPerfBufferCopySpeed_test(1)); + } +} diff --git a/catch/perftests/memory/hipPerfDevMemReadSpeed.cc b/catch/perftests/memory/hipPerfDevMemReadSpeed.cc new file mode 100644 index 0000000000..dad9bfcef4 --- /dev/null +++ b/catch/perftests/memory/hipPerfDevMemReadSpeed.cc @@ -0,0 +1,154 @@ +/* +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 hipMemcpyKernel hipMemcpyKernel +* @{ +* @ingroup perfMemoryTest +* `hipMemcpy(void* dst, const void* src, size_t count, hipMemcpyKind kind)` - +* Copies data between host and device. +*/ + +#include + +#define ARRAY_SIZE 16 + +typedef struct d_uint16 { + uint data[ARRAY_SIZE]; +} d_uint16; + +__global__ static void read_kernel(d_uint16 *src, ulong N, uint *dst) { + size_t idx = (blockIdx.x * blockDim.x + threadIdx.x); + size_t stride = blockDim.x * gridDim.x; + + uint tmp = 0; + for (size_t i = idx; i < N; i += stride) { + for (size_t j = 0; j < ARRAY_SIZE; j++) { + tmp += src[i].data[j]; + } + } + + atomicAdd(dst, tmp); +} + +static bool hipPerfDevMemReadSpeed_test() { + d_uint16 *dSrc, *hSrc; + uint *dDst, *hDst; + hipStream_t stream; + ulong N = 4 * 1024 * 1024; + uint nBytes = N * sizeof(d_uint16); + + int deviceId = 0; + HIP_CHECK(hipSetDevice(deviceId)); + hipDeviceProp_t props = {0}; + HIP_CHECK(hipGetDeviceProperties(&props, deviceId)); + + INFO("info: running on bus " << "0x" << props.pciBusID << " " << + props.name << " with " << props.multiProcessorCount << " CUs \n"); + + const unsigned threadsPerBlock = 64; + const unsigned blocks = props.multiProcessorCount * 4; + + uint inputData = 0x1; + int nIter = 1000; + + hSrc = new d_uint16[nBytes]; + REQUIRE(hSrc != nullptr); + hDst = new uint; + REQUIRE(hDst != nullptr); + hDst[0] = 0; + + for (size_t i = 0; i < N; i++) { + for (int j = 0; j < ARRAY_SIZE; j++) { + hSrc[i].data[j] = inputData; + } + } + + HIP_CHECK(hipMalloc(&dSrc, nBytes)); + HIP_CHECK(hipMalloc(&dDst, sizeof(uint))); + + HIP_CHECK(hipStreamCreate(&stream)); + + HIP_CHECK(hipMemcpy(dSrc, hSrc, nBytes, hipMemcpyHostToDevice)); + HIP_CHECK(hipMemcpy(dDst, hDst, sizeof(uint), hipMemcpyHostToDevice)); + + hipLaunchKernelGGL(read_kernel, dim3(blocks), dim3(threadsPerBlock), + 0, stream, dSrc, N, dDst); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipMemcpy(hDst, dDst, sizeof(uint), hipMemcpyDeviceToHost)); + HIP_CHECK(hipDeviceSynchronize()); + + if (hDst[0] != (nBytes / sizeof(uint))) { + INFO("hipPerfDevMemReadSpeed - Data validation failed for warm up run!" << + " expected " << nBytes / sizeof(uint) << " got " << hDst[0]); + return false; + } + + // measure performance based on host time + auto all_start = std::chrono::steady_clock::now(); + + for (int i = 0; i < nIter; i++) { + hipLaunchKernelGGL(read_kernel, dim3(blocks), dim3(threadsPerBlock), + 0, stream, dSrc, N, dDst); + HIP_CHECK(hipGetLastError()); + } + HIP_CHECK(hipDeviceSynchronize()); + + auto all_end = std::chrono::steady_clock::now(); + std::chrono::duration all_kernel_time = all_end - all_start; + + // read speed in GB/s + double perf = (static_cast(nBytes * nIter * (1e-09))) / + all_kernel_time.count(); + + INFO("hipPerfDevMemReadSpeed - info: average read speed of " << + perf << " GB/s " << "achieved for memory size of " << + nBytes / (1024 * 1024) << " MB"); + + delete [] hSrc; + delete hDst; + HIP_CHECK(hipFree(dSrc)); + HIP_CHECK(hipFree(dDst)); + HIP_CHECK(hipStreamDestroy(stream)); + return true; +} + +/** +* Test Description +* ------------------------ +*  - Verify hipPerfDevMemReadSpeed status. +* Test source +* ------------------------ +*  - perftests/memory/hipPerfDevMemReadSpeed.cc +* Test requirements +* ------------------------ +*  - HIP_VERSION >= 5.6 +*/ + +TEST_CASE("Perf_hipPerfDevMemReadSpeed_test") { + int numDevices = 0; + HIP_CHECK(hipGetDeviceCount(&numDevices)); + + if (numDevices <= 0) { + SUCCEED("Skipped testcase hipPerfDevMemReadSpeed as" + "there is no device to test."); + } else { + REQUIRE(true == hipPerfDevMemReadSpeed_test()); + } +} diff --git a/catch/perftests/memory/hipPerfDevMemWriteSpeed.cc b/catch/perftests/memory/hipPerfDevMemWriteSpeed.cc new file mode 100644 index 0000000000..ebc80d702b --- /dev/null +++ b/catch/perftests/memory/hipPerfDevMemWriteSpeed.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 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 hipMemcpyKernel hipMemcpyKernel +* @{ +* @ingroup perfMemoryTest +* `hipMemcpy(void* dst, const void* src, size_t count, hipMemcpyKind kind)` - +* Copies data between host and device. +*/ + +#include + +#define ARRAY_SIZE 16 + +typedef struct d_uint16 { + uint data[ARRAY_SIZE]; +} d_uint16; + +__global__ void write_kernel(d_uint16 *dst, ulong N, d_uint16 pval) { + size_t idx = (blockIdx.x * blockDim.x + threadIdx.x); + size_t stride = blockDim.x * gridDim.x; + for (size_t i = idx; i < N; i += stride) { + dst[i] = pval; + } +} + +static bool hipPerfDevMemWriteSpeed_test() { + d_uint16 *dDst, *hDst; + ulong N = 4 * 1024 * 1024; + uint nBytes = N * sizeof(d_uint16); + + uint inputData = 0xabababab; + int nIter = 1000; + d_uint16 pval; + + int deviceId = 0; + HIP_CHECK(hipSetDevice(deviceId)); + hipDeviceProp_t props = {0}; + HIP_CHECK(hipGetDeviceProperties(&props, deviceId)); + + INFO("info: running on bus " << "0x" << props.pciBusID << " " << + props.name << " with " << props.multiProcessorCount << " CUs \n"); + + const unsigned threadsPerBlock = 64; + const unsigned blocks = props.multiProcessorCount * 4; + + for (int i = 0; i < ARRAY_SIZE; i++) { + pval.data[i] = inputData; + } + + hDst = new d_uint16[nBytes]; + REQUIRE(hDst != nullptr); + + for (size_t i = 0; i < N; i++) { + for (size_t j = 0; j < ARRAY_SIZE; j++) { + hDst[i].data[j] = 0; + } + } + + hipStream_t stream; + HIP_CHECK(hipStreamCreate(&stream)); + + HIP_CHECK(hipMalloc(&dDst, nBytes)); + hipLaunchKernelGGL(write_kernel, dim3(blocks), dim3(threadsPerBlock), + 0, stream, dDst, N, pval); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipMemcpy(hDst, dDst, nBytes , hipMemcpyDeviceToHost)); + HIP_CHECK(hipDeviceSynchronize()); + + for (uint i = 0; i < N; i++) { + for (uint j = 0; j < ARRAY_SIZE; j++) { + if (hDst[i].data[j] != inputData) { + INFO("hipPerfDevMemWriteSpeed - Data validation failed for warm up run!" + << "at index i: " << i << " element j: " << j << + "expected " << inputData << " but got " << hDst[i].data[j]); + return false; + } + } + } + + // measure performance based on host time + auto all_start = std::chrono::steady_clock::now(); + + for (int i = 0; i < nIter; i++) { + hipLaunchKernelGGL(write_kernel, dim3(blocks), dim3(threadsPerBlock), + 0, stream, dDst, N, pval); + HIP_CHECK(hipGetLastError()); + } + HIP_CHECK(hipDeviceSynchronize()); + + auto all_end = std::chrono::steady_clock::now(); + std::chrono::duration all_kernel_time = all_end - all_start; + + // read speed in GB/s + double perf = (static_cast(nBytes * nIter * (1e-09))) / + all_kernel_time.count(); + + INFO("hipPerfDevMemReadSpeed - info: average write speed of " << + perf << " GB/s " << "achieved for memory size of " << + nBytes / (1024 * 1024) << " MB"); + + delete [] hDst; + HIP_CHECK(hipFree(dDst)); + HIP_CHECK(hipStreamDestroy(stream)); + return true; +} + +/** +* Test Description +* ------------------------ +*  - Verify hipPerfDevMemWriteSpeed status. +* Test source +* ------------------------ +*  - perftests/memory/hipPerfDevMemWriteSpeed.cc +* Test requirements +* ------------------------ +*  - HIP_VERSION >= 5.6 +*/ + +TEST_CASE("Perf_hipPerfDevMemWriteSpeed_test") { + int numDevices = 0; + HIP_CHECK(hipGetDeviceCount(&numDevices)); + + if (numDevices <= 0) { + SUCCEED("Skipped testcase hipPerfDevMemWriteSpeed as" + "there is no device to test."); + } else { + REQUIRE(true == hipPerfDevMemWriteSpeed_test()); + } +} diff --git a/catch/perftests/memory/hipPerfHostNumaAlloc.cc b/catch/perftests/memory/hipPerfHostNumaAlloc.cc new file mode 100644 index 0000000000..4c7e4b7a86 --- /dev/null +++ b/catch/perftests/memory/hipPerfHostNumaAlloc.cc @@ -0,0 +1,191 @@ +/* +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 hipMemcpyKernel hipMemcpyKernel +* @{ +* @ingroup perfMemoryTest +* `hipMemcpy(void* dst, const void* src, size_t count, hipMemcpyKind kind)` - +* Copies data between host and device. +*/ + +#include +#include + +// To run it correctly, we must not export HIP_VISIBLE_DEVICES. +// And we must explicitly link libnuma because of numa api move_pages(). +#define NUM_PAGES 4 +char *h = nullptr; +char *d_h = nullptr; +char *m = nullptr; +char *d_m = nullptr; +int page_size = 1024; + +const int mode[] = { MPOL_DEFAULT, MPOL_BIND, MPOL_PREFERRED, MPOL_INTERLEAVE }; +const char* modeStr[] = { "MPOL_DEFAULT", "MPOL_BIND", + "MPOL_PREFERRED", "MPOL_INTERLEAVE" }; + +std::string exeCommand(const char* cmd) { + std::array buff; + std::string result; + std::unique_ptr pipe(popen(cmd, "r"), pclose); + if (!pipe) { + return result; + } + while (fgets(buff.data(), buff.size(), pipe.get()) != nullptr) { + result += buff.data(); + } + return result; +} + +int getCpuAgentCount() { + const char* cmd = + "cat /proc/cpuinfo | grep \"physical id\" | sort | uniq | wc -l"; + int cpuAgentCount = std::atoi(exeCommand(cmd).c_str()); + return cpuAgentCount; +} + +bool test(int cpuId, int gpuId, int numaMode, unsigned int hostMallocflags) { + void *pages[NUM_PAGES]; + int status[NUM_PAGES]; + int nodes[NUM_PAGES]; + int ret_code; + + INFO("set cpu " << cpuId << ", gpu " << gpuId << ", numaMode " + << numaMode << ", hostMallocflags " << hostMallocflags << "\n"); + + if (cpuId >= 0) { + unsigned long nodeMask = 1 << cpuId; //NOLINT + unsigned long maxNode = sizeof(nodeMask) * 8; //NOLINT + if (set_mempolicy(numaMode, numaMode == MPOL_DEFAULT ? NULL : &nodeMask, + numaMode == MPOL_DEFAULT ? 0 : maxNode) == -1) { + WARN("set_mempolicy() failed with err " << errno << "\n"); + return false; + } + } + + if (gpuId >= 0) { + HIP_CHECK(hipSetDevice(gpuId)); + } + + posix_memalign(reinterpret_cast(&m), page_size, page_size*NUM_PAGES); + HIP_CHECK(hipHostRegister(m, page_size * NUM_PAGES, hipHostRegisterMapped)); + HIP_CHECK(hipHostGetDevicePointer(reinterpret_cast(&d_m), m, 0)); + + status[0] = -1; + pages[0] = m; + for (int i = 1; i < NUM_PAGES; i++) { + pages[i] = reinterpret_cast(pages[0]) + page_size; + } + + ret_code = move_pages(0, NUM_PAGES, pages, NULL, status, 0); + INFO("Memory (malloc) ret " << ret_code << " at " << m << + " (dev " << d_m << "%p) is at node: "); + for (int i = 0; i < NUM_PAGES; i++) { + INFO(status[i]); // Don't verify as it's out of our control + } + INFO("\n"); + + HIP_CHECK(hipHostMalloc(reinterpret_cast(&h), + page_size*NUM_PAGES, hostMallocflags)); + pages[0] = h; + for (int i = 1; i < NUM_PAGES; i++) { + pages[i] = reinterpret_cast(pages[0]) + page_size; + } + ret_code = move_pages(0, NUM_PAGES, pages, NULL, status, 0); + d_h = nullptr; + if (hostMallocflags & hipHostMallocMapped) { + HIP_CHECK(hipHostGetDevicePointer(reinterpret_cast(&d_h), h, 0)); + INFO("Memory (hipHostMalloc) ret " << ret_code << " at " << h + << " (dev " << d_h << ") is at node: "); + } else { + INFO("Memory (hipHostMalloc) ret " << ret_code << " at " + << h << " is at node: "); + } + for (int i = 0; i < NUM_PAGES; i++) { + INFO(status[i]); // Always print it even if it's wrong. Verify later + } + INFO("\n"); + + HIP_CHECK(hipHostFree(reinterpret_cast(h))); + HIP_CHECK(hipHostUnregister(m)); + free(m); + + if (cpuId >= 0 && (numaMode == MPOL_BIND || numaMode == MPOL_PREFERRED)) { + for (int i = 0; i < NUM_PAGES; i++) { + if (status[i] != cpuId) { // Now verify + WARN("Failed at " << i << " status[i] = " << status[i] + << " cpuId " << cpuId << "\n"); + return false; + } + } + } + return true; +} + +bool runTest(const int &cpuCount, const int &gpuCount, + unsigned int hostMallocflags, const std::string &str) { + INFO("Test- " << str.c_str() << "\n"); + + for (int m = 0; m < sizeof(mode) / sizeof(mode[0]); m++) { + INFO("Testing " << modeStr[m] << "\n"); + + for (int i = 0; i < cpuCount; i++) { + for (int j = 0; j < gpuCount; j++) { + if (!test(i, j, mode[m], hostMallocflags)) { + return false; + } + } + } + } + return true; +} + +/** +* Test Description +* ------------------------ +*  - Verify hipPerfHostNumaAlloc status. +* Test source +* ------------------------ +*  - perftests/memory/hipPerfHostNumaAlloc.cc +* Test requirements +* ------------------------ +*  - HIP_VERSION >= 5.6 +*/ + +TEST_CASE("Perf_hipPerfHostNumaAlloc_test") { + int gpuCount = 0; + HIP_CHECK(hipGetDeviceCount(&gpuCount)); + int cpuCount = getCpuAgentCount(); + INFO("Cpu count " << cpuCount << ", Gpu count " << gpuCount << "\n"); + + if (cpuCount < 0 || gpuCount < 0) { + SUCCEED("Skipped testcase hipPerfHostNumaAlloc as " + "there is no device to test.\n"); + return; + } + + REQUIRE(true == runTest(cpuCount, gpuCount, + hipHostMallocDefault | hipHostMallocNumaUser, + "Testing hipHostMallocDefault | hipHostMallocNumaUser......")); + + REQUIRE(true == runTest(cpuCount, gpuCount, + hipHostMallocMapped | hipHostMallocNumaUser, + "Testing hipHostMallocMapped | hipHostMallocNumaUser.......")); +} diff --git a/catch/perftests/memory/hipPerfMemFill.cc b/catch/perftests/memory/hipPerfMemFill.cc new file mode 100644 index 0000000000..ae10829d17 --- /dev/null +++ b/catch/perftests/memory/hipPerfMemFill.cc @@ -0,0 +1,545 @@ +/* + 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 hipMemcpyKernel hipMemcpyKernel +* @{ +* @ingroup perfMemoryTest +* `hipMemcpy(void* dst, const void* src, size_t count, hipMemcpyKind kind)` - +* Copies data between host and device. +*/ + +#include + +#define SIMPLY_ASSIGN 0 +#define USE_HIPTEST_SETNUMBLOCKS 0 + +template +__global__ void vec_fill(T *x, T coef, int N) { + const int istart = threadIdx.x + blockIdx.x * blockDim.x; + const int ishift = blockDim.x * gridDim.x; + for (int i = istart; i < N; i += ishift) { +#if SIMPLY_ASSIGN + x[i] = coef; +#else + x[i] = coef * i; +#endif + } +} + +__device__ void print_log(int i, double value, double expected) { + printf("failed at %d: val=%g, expected=%g\n", i, value, expected); +} + +__device__ void print_log(int i, int value, int expected) { + printf("failed at %d: val=%d, expected=%d\n", i, value, expected); +} + +template +__global__ void vec_verify(T *x, T coef, int N) { + const int istart = threadIdx.x + blockIdx.x * blockDim.x; + const int ishift = blockDim.x * gridDim.x; + for (int i = istart; i < N; i += ishift) { +#if SIMPLY_ASSIGN + if (x[i] != coef) { + print_log(i, x[i], coef); + } +#else + if (x[i] != coef * i) { + print_log(i, x[i], coef * i); + } +#endif + } +} + +template +__global__ void daxpy(T *__restrict__ x, T *__restrict__ y, + const T coef, int Niter, int N) { + const int istart = threadIdx.x + blockIdx.x * blockDim.x; + const int ishift = blockDim.x * gridDim.x; + for (int iter = 0; iter < Niter; ++iter) { + T iv = coef * iter; + for (int i = istart; i < N; i += ishift) + y[i] = iv * x[i] + y[i]; + } +} + +template +class hipPerfMemFill { + private: + static constexpr int NUM_START = 27; + static constexpr int NUM_SIZE = 5; + static constexpr int NUM_ITER = 10; + static constexpr double NUM_1GB = 1024.0 * 1024.0 * 1024.0; + size_t totalSizes_[NUM_SIZE]; + hipDeviceProp_t props_; + const T coef_ = getCoefficient(3.14159); + const unsigned int threadsPerBlock_ = 64; + unsigned int blocksPerCU_; + + public: + hipPerfMemFill() { + for (int i = 0; i < NUM_SIZE; i++) { + // 128M, 256M, 512M, 1024M, 2048M + totalSizes_[i] = 1ull << (i + NUM_START); + } + } + + ~hipPerfMemFill() { } + + bool supportLargeBar() { + return props_.isLargeBar != 0; + } + + bool supportManagedMemory() { + return props_.managedMemory != 0; + } + + const T getCoefficient(double val) { + return static_cast(val); + } + + void setHostBuffer(T *A, T val, size_t size) { + size_t len = size / sizeof(T); + for (int i = 0; i < len; i++) { + A[i] = val; + } + } + + bool open(int deviceId) { + int nGpu = 0; + HIP_CHECK(hipGetDeviceCount(&nGpu)); + if (nGpu < 1) { + printf("No GPU!"); + return false; + } else if (deviceId >= nGpu) { + printf("Info: wrong GPU Id %d\n", deviceId); + return false; + } + + HIP_CHECK(hipSetDevice(deviceId)); + memset(&props_, 0, sizeof(props_)); + HIP_CHECK(hipGetDeviceProperties(&props_, deviceId)); + blocksPerCU_ = props_.multiProcessorCount * 4; + + std::cout << "Info: running on device: id: " << deviceId << ", bus: 0x" + << props_.pciBusID << " " << props_.name << " with " + << props_.multiProcessorCount << " CUs, large bar: " + << supportLargeBar() << ", managed memory: " << supportManagedMemory() + << ", DeviceMallocFinegrained: " << supportDeviceMallocFinegrained() + << std::endl; + return true; + } + + void log_host(const char* title, double GBytes, double sec) { + std::cout << title << " [" << std::setw(7) << GBytes << " GB]: cost " + << std::setw(10) << sec << " s in bandwidth " << std::setw(10) + << GBytes / sec << " [GB/s]" << std::endl; + } + + void log_kernel(const char* title, double GBytes, double sec, + double sec_hv, double sec_kv) { + std::cout << title << " [" << std::setw(7) << GBytes << " GB]: cost " + << std::setw(10) << sec << " s in bandwidth " << std::setw(10) + << GBytes / sec << " [GB/s]" << ", hostVerify cost " + << std::setw(10) << sec_hv << " s in bandwidth " << std::setw(10) + << GBytes / sec_hv << " [GB/s]" << ", kernelVerify cost " + << std::setw(10) << sec_kv << " s in bandwidth " << std::setw(10) + << GBytes / sec_kv << " [GB/s]" << std::endl; + } + + void hostFill(size_t size, T *data, T coef, double *sec) { + size_t num = size / sizeof(T); // Size of elements + auto start = std::chrono::steady_clock::now(); + for (int i = 0; i < num; ++i) { +#if SIMPLY_ASSIGN + data[i] = coef; +#else + data[i] = coef * i; +#endif + } + auto end = std::chrono::steady_clock::now(); + std::chrono::duration diff = end - start; // in second + *sec = diff.count(); + } + + void kernelFill(size_t size, T *data, T coef, double *sec) { + size_t num = size / sizeof(T); // Size of elements + unsigned blocks = setNumBlocks(num); + + // kernel will be loaded first time + hipLaunchKernelGGL(HIP_KERNEL_NAME(vec_fill), dim3(blocks), + dim3(threadsPerBlock_), 0, 0, data, 0, num); + HIP_CHECK(hipDeviceSynchronize()); + + auto start = std::chrono::steady_clock::now(); + + for (int iter = 0; iter < NUM_ITER; ++iter) { + hipLaunchKernelGGL(HIP_KERNEL_NAME(vec_fill), dim3(blocks), + dim3(threadsPerBlock_), 0, 0, data, coef, num); + } + HIP_CHECK(hipDeviceSynchronize()); + + auto end = std::chrono::steady_clock::now(); + std::chrono::duration diff = end - start; // in second + *sec = diff.count() / NUM_ITER; // in second + } + + void hostVerify(size_t size, T *data, T coef, double *sec) { + size_t num = size / sizeof(T); // Size of elements + auto start = std::chrono::steady_clock::now(); + for (int i = 0; i < num; ++i) { +#if SIMPLY_ASSIGN + if (data[i] != coef) { + std::cout << "hostVerify failed: i=" << i << ", data[i]=" << data[i] + << ", expected=" << coef << std::endl; + REQUIRE(false); + } +#else + if (data[i] != coef * i) { + std::cout << "hostVerify failed: i=" << i << ", data[i]=" << data[i] + << ", expected=" << coef * i << std::endl; + REQUIRE(false); + } +#endif + } + auto end = std::chrono::steady_clock::now(); + std::chrono::duration diff = end - start; // in second + *sec = diff.count(); + } + + void kernelVerify(size_t size, T *data, T coef, double *sec) { + size_t num = size / sizeof(T); // Size of elements + unsigned blocks = setNumBlocks(num); + + // kernel will be loaded first time + hipLaunchKernelGGL(HIP_KERNEL_NAME(vec_verify), dim3(blocks), + dim3(threadsPerBlock_), 0, 0, data, coef, num); + HIP_CHECK(hipDeviceSynchronize()); + + // Now all data verified. The following is to test bandwidth. + auto start = std::chrono::steady_clock::now(); + + for (int iter = 0; iter < NUM_ITER; ++iter) { + hipLaunchKernelGGL(HIP_KERNEL_NAME(vec_verify), dim3(blocks), + dim3(threadsPerBlock_), 0, 0, data, coef, num); + } + HIP_CHECK(hipDeviceSynchronize()); + + auto end = std::chrono::steady_clock::now(); + std::chrono::duration diff = end - start; // in second + *sec = diff.count() / NUM_ITER; // in second + } + + bool testLargeBarDeviceMemoryHostFill(size_t size) { + if (!supportLargeBar()) { + return false; + } + + double GBytes = static_cast(size) / NUM_1GB; + + T *A; + HIP_CHECK(hipMalloc(&A, size)); + double sec = 0; + hostFill(size, A, coef_, &sec); // Cpu can access device mem in LB + HIP_CHECK(hipFree(A)); + + log_host("Largebar: host fill", GBytes, sec); + return true; + } + + bool testLargeBar() { + if (!supportLargeBar()) { + return false; + } + + std::cout << "Test large bar device memory host filling" << std::endl; + for (int i = 0; i < NUM_SIZE; i++) { + if (!testLargeBarDeviceMemoryHostFill(totalSizes_[i])) { + return false; + } + } + + return true; + } + + bool testManagedMemoryHostFill(size_t size) { + if (!supportManagedMemory()) { + return false; + } + double GBytes = static_cast(size) / NUM_1GB; + + T *A; + HIP_CHECK(hipMallocManaged(&A, size)); + double sec = 0; + hostFill(size, A, coef_, &sec); // Cpu can access HMM mem + HIP_CHECK(hipFree(A)); + + log_host("Managed: host fill", GBytes, sec); + return true; + } + + bool testManagedMemoryKernelFill(size_t size) { + if (!supportManagedMemory()) { + return false; + } + double GBytes = static_cast(size) / NUM_1GB; + + T *A; + HIP_CHECK(hipMallocManaged(&A, size)); + + double sec = 0, sec_hv = 0, sec_kv = 0; + kernelFill(size, A, coef_, &sec); + // Managed memory can be verified by host + hostVerify(size, A, coef_, &sec_hv); + kernelVerify(size, A, coef_, &sec_kv); + HIP_CHECK(hipFree(A)); + + log_kernel("Managed: kernel fill", GBytes, sec, sec_hv, sec_kv); + + return true; + } + + bool testManagedMemory() { + if (!supportManagedMemory()) { + return false; + } + + std::cout << "Test managed memory host filling" << std::endl; + for (int i = 0; i < NUM_SIZE; i++) { + if (!testManagedMemoryHostFill(totalSizes_[i])) { + return false; + } + } + + std::cout << "Test managed memory kernel filling" << std::endl; + for (int i = 0; i < NUM_SIZE; i++) { + if (!testManagedMemoryKernelFill(totalSizes_[i])) { + return false; + } + } + + return true; + } + + bool testHostMemoryHostFill(size_t size, unsigned int flags) { + double GBytes = static_cast(size) / NUM_1GB; + T *A; + HIP_CHECK(hipHostMalloc(&A, size, flags)); + double sec = 0; + hostFill(size, A, coef_, &sec); + HIP_CHECK(hipHostFree(A)); + + log_host("Host: host fill", GBytes, sec); + return true; + } + + bool testHostMemoryKernelFill(size_t size, unsigned int flags) { + double GBytes = static_cast(size) / NUM_1GB; + + T *A; + HIP_CHECK(hipHostMalloc(reinterpret_cast(&A), size, flags)); + double sec = 0, sec_hv = 0, sec_kv = 0; + kernelFill(size, A, coef_, &sec); + hostVerify(size, A, coef_, &sec_hv); + kernelVerify(size, A, coef_, &sec_kv); + HIP_CHECK(hipHostFree(A)); + + log_kernel("Host: kernel fill", GBytes, sec, sec_hv, sec_kv); + return true; + } + + bool testHostMemory() { + std::cout << "Test coherent host memory host filling" << std::endl; + for (int i = 0; i < NUM_SIZE; i++) { + if (!testHostMemoryHostFill(totalSizes_[i], hipHostMallocCoherent)) { + return false; + } + } + + std::cout << "Test non-coherent host memory host filling" << std::endl; + for (int i = 0; i < NUM_SIZE; i++) { + if (!testHostMemoryHostFill(totalSizes_[i], hipHostMallocNonCoherent)) { + return false; + } + } + + std::cout << "Test coherent host memory kernel filling" << std::endl; + for (int i = 0; i < NUM_SIZE; i++) { + if (!testHostMemoryKernelFill(totalSizes_[i], hipHostMallocCoherent)) { + return false; + } + } + + std::cout << "Test non-coherent host memory kernel filling" << std::endl; + for (int i = 0; i < NUM_SIZE; i++) { + if (!testHostMemoryKernelFill(totalSizes_[i], hipHostMallocNonCoherent)) { + return false; + } + } + + return true; + } + + /* This function should be via device attribute query*/ + bool supportDeviceMallocFinegrained() { +#ifdef __HIP_PLATFORM_AMD__ + T *A = nullptr; + hipError_t err; + err = hipExtMallocWithFlags(reinterpret_cast(&A), sizeof(T), + hipDeviceMallocFinegrained); + if (err || !A) { + return false; + } + HIP_CHECK(hipFree(A)); + return true; +#else + return false; +#endif + } + + unsigned int setNumBlocks(size_t size) { + size_t num = size/sizeof(T); + +#if USE_HIPTEST_SETNUMBLOCKS + return HipTest::setNumBlocks(blocksPerCU_, threadsPerBlock_, num); +#else + return (num + threadsPerBlock_ - 1) / threadsPerBlock_; +#endif + } + +#ifdef __HIP_PLATFORM_AMD__ + bool testExtDeviceMemoryHostFill(size_t size, unsigned int flags) { + double GBytes = static_cast(size) / NUM_1GB; + + T *A = nullptr; + HIP_CHECK(hipExtMallocWithFlags(reinterpret_cast(&A), + size, flags)); + if (!A) { + std::cout << "failed hipExtMallocWithFlags() with size =" << + size << " flags="<< std::hex << flags << std::endl; + return false; + } + + double sec = 0; + hostFill(size, A, coef_, &sec); // Cpu can access this mem + HIP_CHECK(hipFree(A)); + + log_host("ExtDevice: host fill", GBytes, sec); + return true; + } + + bool testExtDeviceMemoryKernelFill(size_t size, unsigned int flags) { + double GBytes = static_cast(size) / NUM_1GB; + + T *A = nullptr; + HIP_CHECK(hipExtMallocWithFlags(reinterpret_cast(&A), + size, flags)); + if (!A) { + std::cout << "failed hipExtMallocWithFlags() with size =" << + size << " flags=" << std::hex << flags << std::endl; + return false; + } + + double sec = 0, sec_hv = 0, sec_kv = 0; + kernelFill(size, A, coef_, &sec); + // Fine grained device memory can be verified by host + hostVerify(size, A, coef_, &sec_hv); + kernelVerify(size, A, coef_, &sec_kv); + HIP_CHECK(hipFree(A)); + + log_kernel("ExtDevice: kernel fill", GBytes, sec, sec_hv, sec_kv); + + return true; + } + + bool testExtDeviceMemory() { + std::cout << "Test fine grained device memory host filling" + << std::endl; + for (int i = 0; i < NUM_SIZE; i++) { + if (!testExtDeviceMemoryHostFill(totalSizes_[i], + hipDeviceMallocFinegrained)) { + return false; + } + } + + std::cout << "Test fine grained device memory kernel filling" + << std::endl; + for (int i = 0; i < NUM_SIZE; i++) { + if (!testExtDeviceMemoryKernelFill(totalSizes_[i], + hipDeviceMallocFinegrained)) { + return false; + } + } + + return true; + } +#endif + + bool run() { + if (supportLargeBar()) { + if (!testLargeBar()) { + return false; + } + } + + if (supportManagedMemory()) { + if (!testManagedMemory()) { + return false; + } + } + + if (!testHostMemory()) { + return false; + } + +#ifdef __HIP_PLATFORM_AMD__ + if (supportDeviceMallocFinegrained()) { + if (!testExtDeviceMemory()) { + return false; + } + } +#endif + return true; + } +}; + +/** +* Test Description +* ------------------------ +*  - Verify hipPerfMemFill status. +* Test source +* ------------------------ +*  - perftests/memory/hipPerfMemFill.cc +* Test requirements +* ------------------------ +*  - HIP_VERSION >= 5.6 +*/ + +TEST_CASE("Perf_hipPerfMemFill_test") { + std::cout << "Test int" << std::endl; + hipPerfMemFill hipPerfMemFillInt; + REQUIRE(true == hipPerfMemFillInt.open(0)); + REQUIRE(true == hipPerfMemFillInt.run()); + + std::cout << "Test double" << std::endl; + hipPerfMemFill hipPerfMemFillDouble; + REQUIRE(true == hipPerfMemFillDouble.open(0)); + REQUIRE(true == hipPerfMemFillDouble.run()); +} diff --git a/catch/perftests/memory/hipPerfMemMallocCpyFree.cc b/catch/perftests/memory/hipPerfMemMallocCpyFree.cc new file mode 100644 index 0000000000..74d9adc346 --- /dev/null +++ b/catch/perftests/memory/hipPerfMemMallocCpyFree.cc @@ -0,0 +1,144 @@ +/* +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 hipMemcpy hipMemcpy +* @{ +* @ingroup perfMemoryTest +* `hipMemcpy(void* dst, const void* src, size_t count, hipMemcpyKind kind)` - +* Copies data between host and device. +*/ + +#include +#include + +#define NUM_SIZE 19 // size up to 16M +#define NUM_ITER 500 // Total GPU memory up to 16M*500=8G + +void valSet(int* A, int val, size_t size) { + size_t len = size / sizeof(int); + for (int i = 0; i < len; i++) { + A[i] = val; + } +} + +void setup(size_t *size, int *num, int **pA, const size_t totalGlobalMem) { + for (int i = 0; i < *num; i++) { + size[i] = 1 << (i + 6); + if ((NUM_ITER + 1) * size[i] > totalGlobalMem) { + *num = i; + break; + } + } + *pA = reinterpret_cast(malloc(size[*num - 1])); + valSet(*pA, 1, size[*num - 1]); +} + +void testInit(size_t size, int *A) { + int *Ad; + + clock_t start = clock(); + HIP_CHECK(hipMalloc(&Ad, size)); // hip::init() will be called + clock_t end = clock(); + double uS = (end - start) * 1000000. / CLOCKS_PER_SEC; + INFO("Initial: hipMalloc(" << size << ") cost " << uS << "us" << "\n"); + + start = clock(); + HIP_CHECK(hipMemcpy(Ad, A, size, hipMemcpyHostToDevice)); + HIP_CHECK(hipDeviceSynchronize()); + end = clock(); + uS = (end - start) * 1000000. / CLOCKS_PER_SEC; + INFO("hipMemcpy(" << size << ") cost " << uS << "us" << "\n"); + + start = clock(); + HIP_CHECK(hipFree(Ad)); + end = clock(); + uS = (end - start) * 1000000. / CLOCKS_PER_SEC; + INFO("hipFree(" << size << ") cost " << uS << "us" << "\n"); +} + +static bool hipPerfMemMallocCpyFree_test() { + double uS; + clock_t start, end; + size_t size[NUM_SIZE] = { 0 }; + int *Ad[NUM_ITER] = { nullptr }; + int *A; + hipDeviceProp_t props; + memset(&props, 0, sizeof(props)); + HIP_CHECK(hipGetDeviceProperties(&props, 0)); + INFO("totalGlobalMem: " << props.totalGlobalMem << "\n"); + + int num = NUM_SIZE; + setup(size, &num, &A, props.totalGlobalMem); + testInit(size[0], A); + + for (int i = 0; i < num; i++) { + start = clock(); + for (int j = 0; j < NUM_ITER; j++) { + HIP_CHECK(hipMalloc(&Ad[j], size[i])); + } + end = clock(); + uS = (end - start) * 1000000. / (NUM_ITER * CLOCKS_PER_SEC); + INFO("hipMalloc(" << size[i] << ") cost " << uS << "us" << "\n"); + + start = clock(); + for (int j = 0; j < NUM_ITER; j++) { + HIP_CHECK(hipMemcpy(Ad[j], A, size[i], hipMemcpyHostToDevice)); + } + HIP_CHECK(hipDeviceSynchronize()); + end = clock(); + uS = (end - start) * 1000000. / (NUM_ITER * CLOCKS_PER_SEC); + INFO("hipMemcpy(" << size[i] << ") cost " << uS << "us" << "\n"); + + start = clock(); + for (int j = 0; j < NUM_ITER; j++) { + HIP_CHECK(hipFree(Ad[j])); + Ad[j] = nullptr; + } + end = clock(); + double uS = (end - start) * 1000000. / (NUM_ITER * CLOCKS_PER_SEC); + INFO("hipFree(" << size[i] << ") cost " << uS << "us" << "\n"); + } + free(A); + return true; +} + +/** +* Test Description +* ------------------------ +*  - Verify hipPerfMemMallocCpyFree status. +* Test source +* ------------------------ +*  - perftests/memory/hipPerfMemMallocCpyFree.cc +* Test requirements +* ------------------------ +*  - HIP_VERSION >= 5.6 +*/ + +TEST_CASE("Perf_hipPerfMemMallocCpyFree_test") { + int numDevices = 0; + HIP_CHECK(hipGetDeviceCount(&numDevices)); + + if (numDevices <= 0) { + SUCCEED("Skipped testcase hipPerfDevMemReadSpeed as" + "there is no device to test."); + } else { + REQUIRE(true == hipPerfMemMallocCpyFree_test()); + } +} diff --git a/catch/perftests/memory/hipPerfMemcpy.cc b/catch/perftests/memory/hipPerfMemcpy.cc new file mode 100644 index 0000000000..bc40760411 --- /dev/null +++ b/catch/perftests/memory/hipPerfMemcpy.cc @@ -0,0 +1,118 @@ +/* + 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 hipMemcpy hipMemcpy +* @{ +* @ingroup perfMemoryTest +* `hipMemcpy(void* dst, const void* src, size_t count, hipMemcpyKind kind)` - +* Copies data between host and device. +*/ + +#include + +#define NUM_SIZE 8 +#define NUM_ITER 0x40000 + +class hipPerfMemcpy { + private: + unsigned int numBuffers_; + size_t totalSizes_[NUM_SIZE]; + void setHostBuffer(int *A, int val, size_t size); + public: + hipPerfMemcpy(); + ~hipPerfMemcpy() {} + bool run(unsigned int numTests); +}; + +hipPerfMemcpy::hipPerfMemcpy() : numBuffers_(0) { + for (int i = 0; i < NUM_SIZE; i++) { + totalSizes_[i] = 1 << (i + 6); + } +} + +void hipPerfMemcpy::setHostBuffer(int *A, int val, size_t size) { + size_t len = size / sizeof(int); + for (int i = 0; i < len; i++) { + A[i] = val; + } +} + +bool hipPerfMemcpy::run(unsigned int numTests) { + int *A, *Ad; + A = new int[totalSizes_[numTests]]; + setHostBuffer(A, 1, totalSizes_[numTests]); + HIP_CHECK(hipMalloc(&Ad, totalSizes_[numTests])); + + // measure performance based on host time + auto all_start = std::chrono::steady_clock::now(); + + for (int j = 0; j < NUM_ITER; j++) { + HIP_CHECK(hipMemcpy(Ad, A, totalSizes_[numTests], hipMemcpyHostToDevice)); + } + + HIP_CHECK(hipDeviceSynchronize()); + + auto all_end = std::chrono::steady_clock::now(); + std::chrono::duration diff = all_end - all_start; + + INFO("hipPerfMemcpy[" << numTests << "] " << "Host to Device copy took " + << diff.count() / NUM_ITER << " sec for memory size of " << + totalSizes_[numTests] << " Bytes."); + + delete [] A; + HIP_CHECK(hipFree(Ad)); + + return true; +} + +/** +* Test Description +* ------------------------ +*  - Verify hipPerfMemcpy status. +* Test source +* ------------------------ +*  - perftests/memory/hipPerfMemcpy.cc +* Test requirements +* ------------------------ +*  - HIP_VERSION >= 5.6 +*/ + +TEST_CASE("Perf_hipPerfMemcpy_test") { + int numDevices = 0; + HIP_CHECK(hipGetDeviceCount(&numDevices)); + + if (numDevices <= 0) { + SUCCEED("Skipped testcase hipPerfMemcpy as there is no device to test."); + } else { + int deviceId = 0; + HIP_CHECK(hipSetDevice(deviceId)); + hipDeviceProp_t props = {0}; + HIP_CHECK(hipGetDeviceProperties(&props, deviceId)); + + INFO("info: running on bus " << "0x" << props.pciBusID << " " << + props.name << " with " << props.multiProcessorCount << " CUs " + << " and device id: " << deviceId); + + hipPerfMemcpy hipPerfMemcpy; + for (auto testCase = 0; testCase < NUM_SIZE; testCase++) { + REQUIRE(true == hipPerfMemcpy.run(testCase)); + } + } +} diff --git a/catch/perftests/memory/hipPerfMemset.cc b/catch/perftests/memory/hipPerfMemset.cc new file mode 100644 index 0000000000..7ae952e02c --- /dev/null +++ b/catch/perftests/memory/hipPerfMemset.cc @@ -0,0 +1,419 @@ +/* + 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 hipMemsetKernel hipMemsetKernel +* @{ +* @ingroup perfMemoryTest +* `hipMemset(void* devPtr, int value, size_t count)` - +* Initializes or sets device memory to a value. +*/ + +#include + +static size_t typeSizeList[] = { + 1, 2, 4, 8, 16, 32, 64, 128, +}; + +static unsigned int sizeList[] = { + 256, 512, 1024, 2048, 4096, 8192, +}; + +static unsigned int eleNumList[] = { + 0x0020000, 0x0080000, 0x0200000, 0x0800000, 0x2000000, +}; + +typedef struct _dataType { + char memsetval = 0x42; + char memsetD8val = 0xDE; + int16_t memsetD16val = 0xDEAD; + int memsetD32val = 0xDEADBEEF; +}dataType; + +#define NUM_ITER 100 + +enum MemsetType { + hipMemsetTypeDefault, + hipMemsetTypeD8, + hipMemsetTypeD16, + hipMemsetTypeD32 +}; + +class hipPerfMemset { + private: + unsigned int bufSize_; + unsigned int num_typeSize_; + unsigned int num_elements_; + size_t testTypeSize_; + unsigned int testNumEle_; + unsigned int _numSubTests = 0; + unsigned int _numSubTests2D = 0; + unsigned int _numSubTests3D = 0; + unsigned int num_sizes_ = 0; + + public: + hipPerfMemset() { + num_typeSize_ = sizeof(typeSizeList) / sizeof(size_t); + num_elements_ = sizeof(eleNumList) / sizeof(unsigned int); + _numSubTests = num_elements_ * num_typeSize_; + + num_sizes_ = sizeof(sizeList) / sizeof(unsigned int); + _numSubTests2D = num_sizes_; + _numSubTests3D = _numSubTests2D; + } + + ~hipPerfMemset() {} + + bool open(int deviceID); + + template + void run1D(unsigned int test, T memsetval, enum MemsetType type, bool async); + + template + void run2D(unsigned int test, T memsetval, enum MemsetType type, bool async); + + template + void run3D(unsigned int test, T memsetval, enum MemsetType type, bool async); + + uint getNumTests() { + return _numSubTests; + } + + uint getNumTests2D() { + return _numSubTests2D; + } + uint getNumTests3D() { + return _numSubTests3D; + } +}; + +bool hipPerfMemset::open(int deviceId) { + int nGpu = 0; + HIP_CHECK(hipGetDeviceCount(&nGpu)); + if (nGpu < 1) { + return false; + } + + HIP_CHECK(hipSetDevice(deviceId)); + hipDeviceProp_t props = {0}; + HIP_CHECK(hipGetDeviceProperties(&props, deviceId)); + INFO("info: running on bus " << "0x" << props.pciBusID << " " << props.name + << " with " << props.multiProcessorCount << " CUs and device id: " + << deviceId << "\n"); + return true; +} + +template +void hipPerfMemset::run1D(unsigned int test, T memsetval, + enum MemsetType type, bool async) { + T *A_h, *A_d; + + testTypeSize_ = typeSizeList[(test / num_elements_) % num_typeSize_]; + testNumEle_ = eleNumList[test % num_elements_]; + + bufSize_ = testNumEle_ * 4; + + HIP_CHECK(hipMalloc(&A_d, bufSize_)); + + A_h = reinterpret_cast (malloc(bufSize_)); + + hipStream_t stream; + HIP_CHECK(hipStreamCreate(&stream)); + + // Warm-up + HIP_CHECK(hipMemset(reinterpret_cast(A_d), memsetval, bufSize_)); + + auto start = std::chrono::steady_clock::now(); + + for (uint i = 0; i < NUM_ITER; i++) { + if (type == hipMemsetTypeDefault && !async) { + HIP_CHECK(hipMemset(reinterpret_cast(A_d), memsetval, bufSize_)); + } else if (type == hipMemsetTypeDefault && async) { + HIP_CHECK(hipMemsetAsync(A_d, memsetval, bufSize_, stream)); + } else if (type == hipMemsetTypeD8 && !async) { + HIP_CHECK(hipMemsetD8((hipDeviceptr_t)A_d, memsetval, bufSize_)); + } else if (type == hipMemsetTypeD8 && async) { + HIP_CHECK(hipMemsetD8Async((hipDeviceptr_t)A_d, memsetval, bufSize_)); + } else if (type == hipMemsetTypeD16 && !async) { + HIP_CHECK(hipMemsetD16((hipDeviceptr_t)A_d, memsetval, + bufSize_/sizeof(T))); + } else if (type == hipMemsetTypeD16 && async) { + HIP_CHECK(hipMemsetD16Async((hipDeviceptr_t)A_d, memsetval, + bufSize_/sizeof(T))); + } else if (type == hipMemsetTypeD32 && !async) { + HIP_CHECK(hipMemsetD32((hipDeviceptr_t)A_d, memsetval, + bufSize_/sizeof(T))); + } else if (type == hipMemsetTypeD32 && async) { + HIP_CHECK(hipMemsetD32Async((hipDeviceptr_t)A_d, memsetval, + bufSize_/sizeof(T))); + } + } + + HIP_CHECK(hipDeviceSynchronize()); + + auto end = std::chrono::steady_clock::now(); + + HIP_CHECK(hipMemcpy(A_h, A_d, bufSize_, hipMemcpyDeviceToHost) ); + + for (int i = 0; i < bufSize_/testTypeSize_; i++) { + if (A_h[i] != memsetval) { + INFO("mismatch at index " << i << " computed: " << + static_cast (A_h[i]) << ", memsetval: " << + static_cast (memsetval) << "\n"); + REQUIRE(false); + } + } + + HIP_CHECK(hipFree(A_d)); + free(A_h); + + std::chrono::duration diff = end - start; + + auto sec = diff.count(); + auto perf = static_cast((bufSize_ * NUM_ITER * (1e-09)) / sec); + + INFO("hipPerf1DMemset[" << test << "] " << (int)bufSize_/1024 << " Kb " + << std::setw(4) << " typeSize " << (int) testTypeSize_ << ":" + << std::setw(5) << perf << " GB/s \n"); +} + +template +void hipPerfMemset::run2D(unsigned int test, T memsetval, + enum MemsetType type, bool async) { + bufSize_ = sizeList[test % num_sizes_]; + size_t numH = bufSize_; + size_t numW = bufSize_; + size_t pitch_A; + size_t width = numW * sizeof(char); + size_t sizeElements = width * numH; + size_t elements = numW* numH; + + T * A_h, * A_d; + + HIP_CHECK(hipMallocPitch(reinterpret_cast(&A_d), + &pitch_A, width, numH)); + A_h = reinterpret_cast(malloc(sizeElements)); + + for (size_t i=0; i < elements; i++) { + A_h[i] = 1; + } + + hipStream_t stream; + HIP_CHECK(hipStreamCreate(&stream)); + + // Warm-up + HIP_CHECK(hipMemset2D(A_d, pitch_A, memsetval, numW, numH)); + + auto start = std::chrono::steady_clock::now(); + + for (uint i = 0; i < NUM_ITER; i++) { + if (type == hipMemsetTypeDefault && !async) { + HIP_CHECK(hipMemset2D(A_d, pitch_A, memsetval, numW, numH)); + } else if (type == hipMemsetTypeDefault && async) { + HIP_CHECK(hipMemset2DAsync(A_d, pitch_A, memsetval, numW, numH, stream)); + } + } + + HIP_CHECK(hipStreamSynchronize(stream)); + + auto end = std::chrono::steady_clock::now(); + + HIP_CHECK(hipMemcpy2D(A_h, width, A_d, pitch_A, numW, numH, + hipMemcpyDeviceToHost)); + + for (int i=0; i < elements; i++) { + if (A_h[i] != memsetval) { + INFO("mismatch at index " << i << " computed: " << + static_cast (A_h[i]) << ", memsetval: " << + static_cast (memsetval) << "\n"); + REQUIRE(false); + } + } + + std::chrono::duration diff = end - start; + + auto sec = diff.count(); + auto perf = static_cast((sizeElements* NUM_ITER * (1e-09)) / sec); + + INFO("hipPerf2DMemset[" << test << "] " <<" " << "(GB/s) for " << + (int)bufSize_ << " x " << bufSize_ << " bytes : " << std::setw(5) << + perf << "\n"); + + HIP_CHECK(hipStreamDestroy(stream)); + HIP_CHECK(hipFree(A_d)); + free(A_h); +} + +template +void hipPerfMemset::run3D(unsigned int test, T memsetval, + enum MemsetType type, bool async) { + bufSize_ = sizeList[test % num_sizes_]; + + size_t numH = bufSize_; + size_t numW = bufSize_; + size_t depth = 10; + size_t width = numW * sizeof(char); + size_t sizeElements = width * numH * depth; + size_t elements = numW* numH* depth; + + hipStream_t stream; + HIP_CHECK(hipStreamCreate(&stream)); + + T *A_h; + + hipExtent extent = make_hipExtent(width, numH, depth); + hipPitchedPtr devPitchedPtr; + + HIP_CHECK(hipMalloc3D(&devPitchedPtr, extent)); + A_h = reinterpret_cast(malloc(sizeElements)); + HIPASSERT(A_h != NULL); + + for (size_t i = 0; i < elements; i++) { + A_h[i] = 1; + } + + // Warm up + HIP_CHECK(hipMemset3D(devPitchedPtr, memsetval, extent)); + + auto start = std::chrono::steady_clock::now(); + + for (uint i = 0; i < NUM_ITER; i++) { + if (type == hipMemsetTypeDefault && !async) { + HIP_CHECK(hipMemset3D(devPitchedPtr, memsetval, extent)); + } else if (type == hipMemsetTypeDefault && async) { + HIP_CHECK(hipMemset3DAsync(devPitchedPtr, memsetval, extent, stream)); + } + } + + HIP_CHECK(hipStreamSynchronize(stream)); + + auto end = std::chrono::steady_clock::now(); + + hipMemcpy3DParms myparms = {0}; + myparms.srcPos = make_hipPos(0, 0, 0); + myparms.dstPos = make_hipPos(0, 0, 0); + myparms.dstPtr = make_hipPitchedPtr(A_h, width , numW, numH); + myparms.srcPtr = devPitchedPtr; + myparms.extent = extent; + + myparms.kind = hipMemcpyDeviceToHost; + + HIP_CHECK(hipMemcpy3D(&myparms)); + + for (int i=0; i < elements; i++) { + if (A_h[i] != memsetval) { + INFO("mismatch at index " << i << " computed: " << + static_cast (A_h[i]) << ", memsetval: " << + static_cast (memsetval) << "\n"); + REQUIRE(false); + } + } + + std::chrono::duration diff = end - start; + + auto sec = diff.count(); + auto perf = static_cast((sizeElements * NUM_ITER * (1e-09)) / sec); + + INFO("hipPerf3DMemset[" << test << "] " <<" " << "(GB/s) for " << + (int)bufSize_ << " x " << bufSize_ << " x " <= 5.6 +*/ + +TEST_CASE("Perf_hipPerfMemset_test") { + hipPerfMemset hipPerfMemset; + + int deviceId = 0; + REQUIRE(hipPerfMemset.open(deviceId)); + + dataType pattern; + + int numTests = hipPerfMemset.getNumTests(); + int numTests2D = hipPerfMemset.getNumTests2D(); + int numTests3D = hipPerfMemset.getNumTests3D(); + + bool async = false; + + for (uint i = 0; i < 2 ; i++) { + if (async) { + INFO("Perf of hipMemsetAsync for 1D arrays \n"); + } else { + INFO("Perf of hipMemset for 1D arrays \n"); + } + + for (auto testCase = 0; testCase < numTests; testCase++) { + if (testCase < 5) { + INFO("API: hipMemset \n"); + hipPerfMemset.run1D(testCase, pattern.memsetval, + hipMemsetTypeDefault, async); + } else if (testCase < 10) { + INFO("API: hipMemsetD16 \n"); + hipPerfMemset.run1D(testCase, pattern.memsetD16val, + hipMemsetTypeD16, async); + } else if (testCase < 15) { + INFO("API: hipMemsetD32 \n"); + hipPerfMemset.run1D(testCase, pattern.memsetD32val, + hipMemsetTypeD32, async); + } else { + INFO("API: hipMemset \n"); + hipPerfMemset.run1D(testCase, pattern.memsetval, + hipMemsetTypeDefault, async); + } + } + async = true; + } + + for (uint i = 0; i < 2; i++) { + if (async) { + INFO("Perf of hipMemset2DAsync for 2D arrays \n"); + } else { + INFO("Perf of hipMemset2D for 2D arrays \n"); + } + + for (uint test = 0; test < numTests2D; test++) { + hipPerfMemset.run2D(test, pattern.memsetval, hipMemsetTypeDefault, async); + } + async = false; + } + + for (uint i = 0; i < 2; i++) { + if (async) { + INFO("Perf of hipMemset3DAsync for 3D arrays \n"); + } else { + INFO("Perf of hipMemset3D for 3D arrays \n"); + } + + for (uint test = 0; test < numTests3D; test++) { + hipPerfMemset.run3D(test, pattern.memsetval, hipMemsetTypeDefault, async); + } + } +} diff --git a/catch/perftests/memory/hipPerfSampleRate.cc b/catch/perftests/memory/hipPerfSampleRate.cc new file mode 100644 index 0000000000..1f5ac59ffa --- /dev/null +++ b/catch/perftests/memory/hipPerfSampleRate.cc @@ -0,0 +1,311 @@ +/* + 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 hipMemcpyKernel hipMemcpyKernel +* @{ +* @ingroup perfMemoryTest +* `hipMemcpy(void* dst, const void* src, size_t count, hipMemcpyKind kind)` - +* Copies data between host and device. +*/ + +#include + +#define NUM_TYPES 3 +std::vector types = {"float", "float2", "float4"}; +std::vector typeSizes = {4, 8, 16}; + +#define NUM_SIZES 12 +std::vector sizes = {1, 2, 4, 8, 16, 32, + 64, 128, 256, 512, 1024, 2048}; + +#define NUM_BUFS 6 +#define MAX_BUFS (1 << (NUM_BUFS - 1)) + +#ifdef __HIP_PLATFORM_NVIDIA__ +__host__ __device__ void operator+=(float2 &a, float2 b) { //NOLINT + a.x += b.x; a.y += b.y; +} + +__host__ __device__ void operator+=(float4 &a, float4 b) { //NOLINT + a.x += b.x; a.y += b.y; a.z += b.z; a.w += b.w; +} +#endif + +template +__global__ void sampleRate(T * outBuffer, unsigned int inBufSize, + unsigned int writeIt, T **inBuffer, int numBufs) { + uint gid = (blockIdx.x * blockDim.x + threadIdx.x); + uint inputIdx = gid % inBufSize; + + T tmp; + memset(&tmp, 0, sizeof(T)); + for (int i = 0; i < numBufs; i++) { + tmp += *(*(inBuffer+i)+inputIdx); + } + + if (writeIt*(unsigned int)tmp.x) { + outBuffer[gid] = tmp; + } +} + +template +__global__ void sampleRateFloat(T * outBuffer, unsigned int inBufSize, + unsigned int writeIt, T ** inBuffer, int numBufs) { + uint gid = (blockIdx.x * blockDim.x + threadIdx.x); + uint inputIdx = gid % inBufSize; + + T tmp = (T)0.0f; + + for (int i = 0; i < numBufs; i++) { + tmp += *((*inBuffer+i)+inputIdx); + } + + if (writeIt*(unsigned int)tmp) { + outBuffer[gid] = tmp; + } +} + +class hipPerfSampleRate { + public: + hipPerfSampleRate(); + ~hipPerfSampleRate(); + + bool open(void); + void run(unsigned int testCase); + void close(void); + + // array of funtion pointers + typedef void (hipPerfSampleRate::*funPtr)(void * outBuffer, unsigned int + inBufSize, unsigned int writeIt, void **inBuffer, int numBufs, + int grids, int blocks, int threads_per_block); + + // Wrappers + void float_kernel(void * outBuffer, unsigned int inBufSize, + unsigned int writeIt, void **inBuffer, int numBufs, + int grids, int blocks, int threads_per_block); + + void float2_kernel(void * outBuffer, unsigned int inBufSize, + unsigned int writeIt, void **inBuffer, int numBufs, + int grids, int blocks, int threads_per_block); + + void float4_kernel(void * outBuffer, unsigned int inBufSize, + unsigned int writeIt, void **inBuffer, int numBufs, + int grids, int blocks, int threads_per_block); + + private: + void setData(void *ptr, unsigned int value); + void checkData(uint *ptr); + + unsigned int width_; + unsigned int bufSize_; + int numCUs; + + unsigned int outBufSize_; + static const unsigned int MAX_ITERATIONS = 25; + unsigned int numBufs_; + unsigned int typeIdx_; +}; + +hipPerfSampleRate::hipPerfSampleRate() {} +hipPerfSampleRate::~hipPerfSampleRate() {} +void hipPerfSampleRate::close() {} + +bool hipPerfSampleRate::open(void) { + int nGpu = 0; + HIP_CHECK(hipGetDeviceCount(&nGpu)); + if (nGpu < 1) { + return false; + } + + int deviceId = 0; + hipDeviceProp_t props = {0}; + props = {0}; + HIP_CHECK(hipSetDevice(deviceId)); + HIP_CHECK(hipGetDeviceProperties(&props, deviceId)); + INFO("info: running on bus " << "0x" << props.pciBusID << " " << + props.name << " with " << props.multiProcessorCount << + " CUs" << " and device id: " << deviceId << "\n"); + numCUs = props.multiProcessorCount; + return true; +} + +// Wrappers for the kernel launches +void hipPerfSampleRate::float_kernel(void * outBuffer, unsigned int inBufSize, + unsigned int writeIt, void **inBuffer, int numBufs, + int grids, int blocks, int threads_per_block) { + hipLaunchKernelGGL(sampleRateFloat, dim3(grids, grids, grids), + dim3(blocks), 0, 0, reinterpret_cast(outBuffer), + inBufSize, writeIt, reinterpret_cast(inBuffer), numBufs); +} + +void hipPerfSampleRate::float2_kernel(void * outBuffer, unsigned int inBufSize, + unsigned int writeIt, void **inBuffer, int grids, + int blocks, int threads_per_block, int numBufs) { + hipLaunchKernelGGL(sampleRate, dim3(grids, grids, grids), + dim3(blocks), 0, 0, reinterpret_cast(outBuffer), + inBufSize, writeIt, reinterpret_cast(inBuffer), numBufs); +} + +void hipPerfSampleRate::float4_kernel(void * outBuffer, unsigned int inBufSize, + unsigned int writeIt, void **inBuffer, int grids, + int blocks, int threads_per_block, int numBufs) { + hipLaunchKernelGGL(sampleRate, dim3(grids, grids, grids), + dim3(blocks), 0, 0, reinterpret_cast(outBuffer), + inBufSize, writeIt, reinterpret_cast(inBuffer), numBufs); +} + +void hipPerfSampleRate::run(unsigned int test) { + funPtr p[] = {&hipPerfSampleRate::float_kernel, + &hipPerfSampleRate::float2_kernel, + &hipPerfSampleRate::float4_kernel}; + + // We compute a square domain + width_ = sizes[test % NUM_SIZES]; + typeIdx_ = (test / NUM_SIZES) % NUM_TYPES; + bufSize_ = width_ * width_ * typeSizes[typeIdx_]; + numBufs_ = (1 << (test / (NUM_SIZES * NUM_TYPES))); + + void ** dPtr; + void * hOutPtr; + void * dOutPtr; + void * hInPtr[numBufs_]; + void * dInPtr[numBufs_]; + + outBufSize_ = + sizes[NUM_SIZES - 1] * sizes[NUM_SIZES - 1] * typeSizes[NUM_TYPES - 1]; + + // Allocate memory on the host and device + HIP_CHECK(hipHostMalloc(reinterpret_cast(&hOutPtr), outBufSize_, + hipHostMallocDefault)); + setData(reinterpret_cast(hOutPtr), 0xdeadbeef); + HIP_CHECK(hipMalloc(reinterpret_cast(&dOutPtr), outBufSize_)); + + // Allocate 2D array in Device + HIP_CHECK(hipMalloc(reinterpret_cast(&dPtr), + numBufs_* sizeof(void *))); + + for (uint i = 0; i < numBufs_; i++) { + HIP_CHECK(hipHostMalloc(reinterpret_cast(&hInPtr[i]), bufSize_, + hipHostMallocDefault)); + HIP_CHECK(hipMalloc(reinterpret_cast(&dInPtr[i]), bufSize_)); + setData(hInPtr[i], 0x3f800000); + } + + // Populate array of pointers with array addresses + HIP_CHECK(hipMemcpy(dPtr, dInPtr, numBufs_* sizeof(void *), + hipMemcpyHostToDevice)); + + // Copy memory from host to device + for (uint i = 0; i < numBufs_; i++) { + HIP_CHECK(hipMemcpy(dInPtr[i], hInPtr[i], bufSize_, hipMemcpyHostToDevice)); + } + + HIP_CHECK(hipMemcpy(dOutPtr, hOutPtr, outBufSize_, hipMemcpyHostToDevice)); + + // Prepare kernel launch parameters + // outBufSize_/sizeof(uint) - Grid size in 3D + int grids = 64; + int blocks = 64; + int threads_per_block = 1; + + unsigned int maxIter = MAX_ITERATIONS * (MAX_BUFS / numBufs_); + unsigned int sizeDW = width_ * width_; + unsigned int writeIt = 0; + + int idx = 0; + + if (!types[typeIdx_].compare("float")) { + idx = 0; + } else if (!types[typeIdx_].compare("float2")) { + idx = 1; + } else if (!types[typeIdx_].compare("float4")) { + idx = 2; + } + + // Time the kernel execution + auto all_start = std::chrono::steady_clock::now(); + for (uint i = 0; i < maxIter; i++) { + (this->*p[idx]) (reinterpret_cast(dOutPtr), sizeDW, writeIt, + dPtr, numBufs_, grids, blocks, threads_per_block); + } + + HIP_CHECK(hipDeviceSynchronize()); + auto all_end = std::chrono::steady_clock::now(); + std::chrono::duration all_kernel_time = all_end - all_start; + + double perf = (static_cast(outBufSize_ * numBufs_ * + maxIter * (1e-09))) / all_kernel_time.count(); + + INFO("Domain " << sizes[NUM_SIZES - 1] << "x"<< sizes[NUM_SIZES - 1] + << " bufs " << numBufs_ << " " << types[typeIdx_] << " " << width_ + << "x" <(numBufs_)) { + INFO("Data validation failed at "<< i << " Got "<< ptr[i] + << ", expected " << (float)numBufs_ << "\n"); + REQUIRE(false); + } + } +} + +/** +* Test Description +* ------------------------ +*  - Verify hipPerfSampleRate status. +* Test source +* ------------------------ +*  - perftests/memory/hipPerfSampleRate.cc +* Test requirements +* ------------------------ +*  - HIP_VERSION >= 5.6 +*/ + +TEST_CASE("Perf_hipPerfSampleRate_test") { + hipPerfSampleRate sampleTypes; + + REQUIRE(true == sampleTypes.open()); + + for (unsigned int testCase = 0; testCase < 216 ; testCase+=36) { + sampleTypes.run(testCase); + } +} diff --git a/catch/perftests/memory/hipPerfSharedMemReadSpeed.cc b/catch/perftests/memory/hipPerfSharedMemReadSpeed.cc new file mode 100644 index 0000000000..1d4b620c0e --- /dev/null +++ b/catch/perftests/memory/hipPerfSharedMemReadSpeed.cc @@ -0,0 +1,262 @@ +/* + 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 hipMemcpyKernel hipMemcpyKernel +* @{ +* @ingroup perfMemoryTest +* `hipMemcpy(void* dst, const void* src, size_t count, hipMemcpyKind kind)` - +* Copies data between host and device. +*/ + +#include + +#define sharedMemSize1 2048 +#define sharedMemSize2 256 + +__global__ void sharedMemReadSpeed1(float *outBuf, ulong N) { + size_t gid = (blockIdx.x * blockDim.x + threadIdx.x); + size_t lid = threadIdx.x; + __shared__ float local[sharedMemSize1]; + + float val1 = 0; + float val2 = 0; + float val3 = 0; + float val4 = 0; + + for (int i = 0; i < (sharedMemSize1 / 64); i++) { + local[lid + i * 64] = lid; + } + + __syncthreads(); + + val1 += local[lid]; + val2 += local[lid + 64]; + val3 += local[lid + 128]; + val4 += local[lid + 192]; + val1 += local[lid + 256]; + val2 += local[lid + 320]; + val3 += local[lid + 384]; + val4 += local[lid + 448]; + val1 += local[lid + 512]; + val2 += local[lid + 576]; + val3 += local[lid + 640]; + val4 += local[lid + 704]; + val1 += local[lid + 768]; + val2 += local[lid + 832]; + val3 += local[lid + 896]; + val4 += local[lid + 960]; + val1 += local[lid + 1024]; + val2 += local[lid + 1088]; + val3 += local[lid + 1152]; + val4 += local[lid + 1216]; + val1 += local[lid + 1280]; + val2 += local[lid + 1344]; + val3 += local[lid + 1408]; + val4 += local[lid + 1472]; + val1 += local[lid + 1536]; + val2 += local[lid + 1600]; + val3 += local[lid + 1664]; + val4 += local[lid + 1728]; + val1 += local[lid + 1792]; + val2 += local[lid + 1856]; + val3 += local[lid + 1920]; + val4 += local[lid + 1984]; + + if (gid < N) { + outBuf[gid] = val1 + val2 + val3 + val4; + } +} + +__global__ void sharedMemReadSpeed2(float *outBuf, ulong N) { + size_t gid = (blockIdx.x * blockDim.x + threadIdx.x); + size_t lid = threadIdx.x; + __shared__ float local[sharedMemSize2]; + + float val0 = 0.0f; + float val1 = 0.0f; + + for (int i = 0; i < (sharedMemSize2 / 64); i++) { + local[lid + i * 64] = lid; + } + + __syncthreads(); + +#pragma nounroll + for (uint i = 0; i < 32; i++) { + val0 += local[8 * i + 0]; + val1 += local[8 * i + 1]; + val0 += local[8 * i + 2]; + val1 += local[8 * i + 3]; + val0 += local[8 * i + 4]; + val1 += local[8 * i + 5]; + val0 += local[8 * i + 6]; + val1 += local[8 * i + 7]; + } + + if (gid < N) { + outBuf[gid] = val0 + val1; + } +} + +static bool hipPerfSharedMemReadSpeed_test() { + float *dDst; + float *hDst; + hipStream_t stream; + constexpr uint numSizes = 4; + constexpr uint Sizes[numSizes] = {262144, 1048576, 4194304, 16777216}; + uint numReads1 = 32; + uint numReads2 = 256; + uint sharedMemSizeBytes1 = sharedMemSize1 * sizeof(float); + uint sharedMemSizeBytes2 = sharedMemSize2 * sizeof(float); + int nIter = 1000; + const unsigned threadsPerBlock = 64; + + static int device = 0; + HIP_CHECK(hipSetDevice(device)); + hipDeviceProp_t props; + HIP_CHECK(hipGetDeviceProperties(&props, device)); + INFO("info: running on bus " << "0x" << props.pciBusID << " " << props.name + << " with " << props.multiProcessorCount << " CUs \n"); + + HIP_CHECK(hipStreamCreate(&stream)); + + for (int nTest = 0; nTest < numSizes; nTest++) { + uint nBytes = Sizes[nTest % numSizes]; + ulong N = nBytes / sizeof(float); + const unsigned blocks = N / threadsPerBlock; + + hDst = new float[nBytes]; + HIP_CHECK(hDst == 0 ? hipErrorOutOfMemory : hipSuccess); + memset(hDst, 0, nBytes); + + HIP_CHECK(hipMalloc(&dDst, nBytes)); + HIP_CHECK(hipMemcpy(dDst, hDst, nBytes, hipMemcpyHostToDevice)); + + hipLaunchKernelGGL(sharedMemReadSpeed1, dim3(blocks), + dim3(threadsPerBlock), 0, stream, dDst, N); + HIP_CHECK(hipMemcpy(hDst, dDst, nBytes, hipMemcpyDeviceToHost)); + HIP_CHECK(hipDeviceSynchronize()); + + int tmp = 0; + for (int i = 0; i < N; i++) { + if (i % threadsPerBlock == 0) { + tmp = 0; + } + if (hDst[i] != tmp) { + INFO("info: Data validation failed for warm up run! \n"); + INFO("info: expected " << tmp << " got " << hDst[i] << " \n"); + return false; + } + tmp += threadsPerBlock / 2; + } + + auto all_start = std::chrono::steady_clock::now(); + for (int i = 0; i < nIter; i++) { + hipLaunchKernelGGL(sharedMemReadSpeed1, dim3(blocks), + dim3(threadsPerBlock), 0, stream, dDst, N); + } + HIP_CHECK(hipDeviceSynchronize()); + + auto all_end = std::chrono::steady_clock::now(); + std::chrono::duration all_kernel_time = all_end - all_start; + + // read speed in GB/s + double perf = (static_cast(blocks * threadsPerBlock) + * (numReads1 * sizeof(float) + sharedMemSizeBytes1 / 64) + * nIter * (1e-09)) / all_kernel_time.count(); + + INFO("info: read speed = " << std::setw(8) << perf << " GB/s for " << + sharedMemSizeBytes1 / 1024 << " KB shared memory with " << + std::setw(8) << blocks * threadsPerBlock << " threads, " + << std::setw(4) << numReads1 << + " reads in sharedMemReadSpeed1 kernel \n"); + + delete[] hDst; + HIP_CHECK(hipFree(dDst)); + } + + for (int nTest = 0; nTest < numSizes; nTest++) { + uint nBytes = Sizes[nTest % numSizes]; + ulong N = nBytes / sizeof(float); + const unsigned blocks = N / threadsPerBlock; + + hDst = new float[nBytes]; + HIP_CHECK(hDst == 0 ? hipErrorOutOfMemory : hipSuccess); + memset(hDst, 0, nBytes); + + HIP_CHECK(hipMalloc(&dDst, nBytes)); + HIP_CHECK(hipMemcpy(dDst, hDst, nBytes, hipMemcpyHostToDevice)); + + hipLaunchKernelGGL(sharedMemReadSpeed2, dim3(blocks), + dim3(threadsPerBlock), 0, stream, dDst, N); + HIP_CHECK(hipMemcpy(hDst, dDst, nBytes, hipMemcpyDeviceToHost)); + HIP_CHECK(hipDeviceSynchronize()); + + auto all_start = std::chrono::steady_clock::now(); + for (int i = 0; i < nIter; i++) { + hipLaunchKernelGGL(sharedMemReadSpeed2, dim3(blocks), + dim3(threadsPerBlock), 0, stream, dDst, N); + } + HIP_CHECK(hipDeviceSynchronize()); + + auto all_end = std::chrono::steady_clock::now(); + std::chrono::duration all_kernel_time = all_end - all_start; + + // read speed in GB/s + double perf = (static_cast(blocks * threadsPerBlock) + * (numReads2 * sizeof(float) + sharedMemSizeBytes2 / 64) + * nIter * (1e-09)) / all_kernel_time.count(); + + INFO("info: read speed = " << std::setw(8) << perf << " GB/s for " + << sharedMemSizeBytes2 / 1024 << " KB shared memory with " + << std::setw(8) << blocks * threadsPerBlock << " threads, " + << std::setw(4) << numReads2 << + " reads in sharedMemReadSpeed2 kernel \n"); + + delete[] hDst; + HIP_CHECK(hipFree(dDst)); + } + HIP_CHECK(hipStreamDestroy(stream)); + return true; +} + +/** +* Test Description +* ------------------------ +*  - Verify hipPerfSharedMemReadSpeed status. +* Test source +* ------------------------ +*  - perftests/memory/hipPerfSharedMemReadSpeed.cc +* Test requirements +* ------------------------ +*  - HIP_VERSION >= 5.6 +*/ + +TEST_CASE("Perf_hipPerfSharedMemReadSpeed_test") { + int numDevices = 0; + HIP_CHECK(hipGetDeviceCount(&numDevices)); + + if (numDevices <= 0) { + SUCCEED("Skipped testcase hipPerfSharedMemReadSpeed as" + "there is no device to test.\n"); + } else { + REQUIRE(true == hipPerfSharedMemReadSpeed_test()); + } +} From ec88eca48475b74e8d61535cc74e4ad50c28bab6 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Mon, 14 Aug 2023 21:19:44 +0530 Subject: [PATCH 16/30] SWDEV-1 - Enable hiprtc test includepath and copy its dependent files to bin directory (#374) Change-Id: I7171bd343cdccc02f55bcb1b891f589c5fe2acaa --- catch/unit/rtc/CMakeLists.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/catch/unit/rtc/CMakeLists.txt b/catch/unit/rtc/CMakeLists.txt index 62fd20bf7e..9937df6c56 100644 --- a/catch/unit/rtc/CMakeLists.txt +++ b/catch/unit/rtc/CMakeLists.txt @@ -4,6 +4,7 @@ set(TEST_SRC warpsize.cc hipRtcFunctional.cc hipStreamCaptureRtc.cc + includepath.cc ) # AMD only tests @@ -14,6 +15,14 @@ set(AMD_TEST_SRC shfl.cc ) +add_custom_target(copyRtcHeaders ALL + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_SOURCE_DIR}/saxpy.h + ${CMAKE_CURRENT_BINARY_DIR}/saxpy.h + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_CURRENT_SOURCE_DIR}/headers + ${CMAKE_CURRENT_BINARY_DIR}/headers) + if(UNIX) set(AMD_TEST_SRC ${TEST_SRC} RtcFunctions.cpp @@ -33,3 +42,5 @@ elseif(HIP_PLATFORM MATCHES "amd") TEST_TARGET_NAME build_tests LINKER_LIBS hiprtc) endif() + +add_dependencies(build_tests copyRtcHeaders) From fced17ddce64cdf694e7582f02bb885073f9add7 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Mon, 14 Aug 2023 21:26:31 +0530 Subject: [PATCH 17/30] SWDEV-411680 - Skip if p2p access is not supported. (#377) Change-Id: Ib4d49f9cfc92ea05d799b4a7d5e688fe8790c77e --- catch/include/memcpy3d_tests_common.hh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/catch/include/memcpy3d_tests_common.hh b/catch/include/memcpy3d_tests_common.hh index c3c7028517..27b7c495df 100644 --- a/catch/include/memcpy3d_tests_common.hh +++ b/catch/include/memcpy3d_tests_common.hh @@ -180,8 +180,10 @@ void Memcpy3DDeviceToDeviceShell(F memcpy_func, const hipStream_t kernel_stream int can_access_peer = 0; HIP_CHECK(hipDeviceCanAccessPeer(&can_access_peer, src_device, dst_device)); if (!can_access_peer) { - INFO("Peer access cannot be enabled between devices " << src_device << " " << dst_device); - REQUIRE(can_access_peer); + std::string msg = "Skipped as peer access cannot be enabled between devices " + + std::to_string(src_device) + " " + std::to_string(dst_device); + HipTest::HIP_SKIP_TEST(msg.c_str()); + return; } HIP_CHECK(hipDeviceEnablePeerAccess(dst_device, 0)); } From 30fcf2f17ce79dab5eae1bb6badc1a65d200a7ad Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Mon, 14 Aug 2023 21:26:49 +0530 Subject: [PATCH 18/30] SWDEV-402093 - Updated README to use AMDGPU_TARGETS=native to enable compiler autodetection (#378) Change-Id: I33a71d12b5b883eacac706725322bc13e0d57852 --- samples/2_Cookbook/18_cmake_hip_device/README.md | 6 +++++- samples/2_Cookbook/19_cmake_lang/README.md | 5 +++++ samples/2_Cookbook/21_cmake_hip_cxx_clang/README.md | 6 +++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/samples/2_Cookbook/18_cmake_hip_device/README.md b/samples/2_Cookbook/18_cmake_hip_device/README.md index 5c4bb488d9..c65418017f 100644 --- a/samples/2_Cookbook/18_cmake_hip_device/README.md +++ b/samples/2_Cookbook/18_cmake_hip_device/README.md @@ -12,7 +12,11 @@ Note, users may need to add ADMGPU support as command line option, if test faile ``` CXX="$(hipconfig -l)"/clang++ cmake -DCMAKE_PREFIX_PATH=/opt/rocm -DAMDGPU_TARGETS="gfx1102" .. ``` - +To enable compiler auto detection of gpu users may need to add ADMGPU support as command line option, +if test failed to run, for example, +``` +CXX="$(hipconfig -l)"/clang++ cmake -DCMAKE_PREFIX_PATH=/opt/rocm -DAMDGPU_TARGETS=native .. +``` II. Test ``` diff --git a/samples/2_Cookbook/19_cmake_lang/README.md b/samples/2_Cookbook/19_cmake_lang/README.md index 284bec8655..c034c40ac3 100644 --- a/samples/2_Cookbook/19_cmake_lang/README.md +++ b/samples/2_Cookbook/19_cmake_lang/README.md @@ -19,6 +19,11 @@ Note, users may need to add AMD GPU support, if test failed, for example, ``` CXX="$(hipconfig -l)"/clang++ FC=$(which gfortran) cmake -DCMAKE_PREFIX_PATH=/opt/rocm -DAMDGPU_TARGETS="gfx1102" .. ``` +To enable compiler auto detection of gpu users may need to add ADMGPU support as command line option, +if test failed to run, for example, +``` +CXX="$(hipconfig -l)"/clang++ FC=$(which gfortran) cmake -DCMAKE_PREFIX_PATH=/opt/rocm -DAMDGPU_TARGETS=native .. +``` III. Test ``` ./test_fortran diff --git a/samples/2_Cookbook/21_cmake_hip_cxx_clang/README.md b/samples/2_Cookbook/21_cmake_hip_cxx_clang/README.md index a7d362a990..9ee4ec1c95 100644 --- a/samples/2_Cookbook/21_cmake_hip_cxx_clang/README.md +++ b/samples/2_Cookbook/21_cmake_hip_cxx_clang/README.md @@ -7,7 +7,11 @@ rm -rf *; CXX="$(hipconfig -l)"/amdclang++ cmake -DCMAKE_PREFIX_PATH=/opt/rocm .. make ``` - +To enable compiler auto detection of gpu users may need to add ADMGPU support as command line option, +if test failed to run, for example, +``` +CXX="$(hipconfig -l)"/amdclang++ cmake -DCMAKE_PREFIX_PATH=/opt/rocm -DAMDGPU_TARGETS=native .. +``` II. Test ``` From 87511a5ca0193cff49ff1209ff7397e255cb232c Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Mon, 14 Aug 2023 21:30:00 +0530 Subject: [PATCH 19/30] SWDEV-411064 - Remove asm tests since we do not encourage users to use asm in their code (#382) Change-Id: If328fb3cd953e3921a010d80a8c4d1abf1c9058c --- catch/unit/kernel/CMakeLists.txt | 10 -- catch/unit/kernel/inline_asm_vadd.cc | 136 --------------------------- catch/unit/kernel/inline_asm_vmac.cc | 128 ------------------------- 3 files changed, 274 deletions(-) delete mode 100644 catch/unit/kernel/inline_asm_vadd.cc delete mode 100644 catch/unit/kernel/inline_asm_vmac.cc diff --git a/catch/unit/kernel/CMakeLists.txt b/catch/unit/kernel/CMakeLists.txt index d8a07b8638..2e7c0aecf2 100644 --- a/catch/unit/kernel/CMakeLists.txt +++ b/catch/unit/kernel/CMakeLists.txt @@ -34,21 +34,11 @@ set(TEST_SRC 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/catch/unit/kernel/inline_asm_vadd.cc b/catch/unit/kernel/inline_asm_vadd.cc deleted file mode 100644 index 29a4d8fe29..0000000000 --- a/catch/unit/kernel/inline_asm_vadd.cc +++ /dev/null @@ -1,136 +0,0 @@ -/* -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/catch/unit/kernel/inline_asm_vmac.cc b/catch/unit/kernel/inline_asm_vmac.cc deleted file mode 100644 index e9fbebda37..0000000000 --- a/catch/unit/kernel/inline_asm_vmac.cc +++ /dev/null @@ -1,128 +0,0 @@ -/* -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); -} From 09861ff867a458362e8c83e0b210294443d67f2c Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Mon, 14 Aug 2023 21:30:15 +0530 Subject: [PATCH 20/30] SWDEV-412666 - Re-enable lines of hipMemcpy3D test that was failing with previous version of llvm (#383) Change-Id: I6834cd3c003a1b3c1d60dfc2f7d14657248d2ea9 --- catch/unit/memory/hipMemcpy3D.cc | 8 ++++---- catch/unit/memory/hipMemcpy3DAsync.cc | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/catch/unit/memory/hipMemcpy3D.cc b/catch/unit/memory/hipMemcpy3D.cc index 79b9d0f90f..026be6c5d6 100644 --- a/catch/unit/memory/hipMemcpy3D.cc +++ b/catch/unit/memory/hipMemcpy3D.cc @@ -33,7 +33,7 @@ THE SOFTWARE. TEST_CASE("Unit_hipMemcpy3D_Positive_Basic") { constexpr bool async = false; - //SWDEV-409754 SECTION("Device to Host") { Memcpy3DDeviceToHostShell(Memcpy3DWrapper<>); } + SECTION("Device to Host") { Memcpy3DDeviceToHostShell(Memcpy3DWrapper<>); } SECTION("Device to Device") { SECTION("Peer access disabled") { @@ -42,9 +42,9 @@ TEST_CASE("Unit_hipMemcpy3D_Positive_Basic") { SECTION("Peer access enabled") { Memcpy3DDeviceToDeviceShell(Memcpy3DWrapper<>); } } - //SWDEV-409754 SECTION("Host to Device") { Memcpy3DHostToDeviceShell(Memcpy3DWrapper<>); } + SECTION("Host to Device") { Memcpy3DHostToDeviceShell(Memcpy3DWrapper<>); } - //SWDEV-409754 SECTION("Host to Host") { Memcpy3DHostToHostShell(Memcpy3DWrapper<>); } + SECTION("Host to Host") { Memcpy3DHostToHostShell(Memcpy3DWrapper<>); } } TEST_CASE("Unit_hipMemcpy3D_Positive_Synchronization_Behavior") { @@ -76,7 +76,7 @@ TEST_CASE("Unit_hipMemcpy3D_Positive_Parameters") { TEST_CASE("Unit_hipMemcpy3D_Positive_Array") { constexpr bool async = false; - //SWDEV-409754 SECTION("Array from/to Host") { Memcpy3DArrayHostShell(Memcpy3DWrapper); } + SECTION("Array from/to Host") { Memcpy3DArrayHostShell(Memcpy3DWrapper); } #if HT_NVIDIA // Disabled on AMD due to defect - EXSWHTEC-238 SECTION("Array from/to Device") { Memcpy3DArrayDeviceShell(Memcpy3DWrapper); } #endif diff --git a/catch/unit/memory/hipMemcpy3DAsync.cc b/catch/unit/memory/hipMemcpy3DAsync.cc index d346bdcac5..93baeb42d2 100644 --- a/catch/unit/memory/hipMemcpy3DAsync.cc +++ b/catch/unit/memory/hipMemcpy3DAsync.cc @@ -50,7 +50,7 @@ TEST_CASE("Unit_hipMemcpy3DAsync_Positive_Basic") { SECTION("Host to Device") { Memcpy3DHostToDeviceShell(Memcpy3DWrapper, stream); } - //SWDEV-409754 SECTION("Host to Host") { Memcpy3DHostToHostShell(Memcpy3DWrapper, stream); } + SECTION("Host to Host") { Memcpy3DHostToHostShell(Memcpy3DWrapper, stream); } } TEST_CASE("Unit_hipMemcpy3DAsync_Positive_Synchronization_Behavior") { @@ -84,7 +84,7 @@ TEST_CASE("Unit_hipMemcpy3DAsync_Positive_Parameters") { TEST_CASE("Unit_hipMemcpy3DAsync_Positive_Array") { constexpr bool async = true; - //SWDEV-409754 SECTION("Array from/to Host") { Memcpy3DArrayHostShell(Memcpy3DWrapper); } + SECTION("Array from/to Host") { Memcpy3DArrayHostShell(Memcpy3DWrapper); } #if HT_NVIDIA // Disabled on AMD due to defect - EXSWHTEC-238 SECTION("Array from/to Device") { Memcpy3DArrayDeviceShell(Memcpy3DWrapper); } #endif From 49d3ea994551798fe4940d4cedce76f829aca216 Mon Sep 17 00:00:00 2001 From: ROCm CI Service Account <66695075+rocm-ci@users.noreply.github.com> Date: Mon, 14 Aug 2023 21:30:34 +0530 Subject: [PATCH 21/30] SWDEV-397570 - Adding PASSED string on cases where tests are skipped. (#385) Change-Id: I2bbe5cfb9eff75b817f3e77aaeeecc5d0c411dbf --- samples/2_Cookbook/11_texture_driver/texture2dDrv.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/2_Cookbook/11_texture_driver/texture2dDrv.cpp b/samples/2_Cookbook/11_texture_driver/texture2dDrv.cpp index e30c1ba911..120006b140 100644 --- a/samples/2_Cookbook/11_texture_driver/texture2dDrv.cpp +++ b/samples/2_Cookbook/11_texture_driver/texture2dDrv.cpp @@ -231,6 +231,7 @@ inline bool isImageSupported() { int main(int argc, char** argv) { if (!isImageSupported()) { printf("Texture is not support on the device. Skipped.\n"); + printf("texture2dDrv %s ...\n", "PASSED"); return 0; } checkHipErrors(hipInit(0)); From 69bce6be086c94607cbae94e809c57167d372f9d Mon Sep 17 00:00:00 2001 From: Ioannis Assiouras <38722728+iassiour@users.noreply.github.com> Date: Mon, 14 Aug 2023 17:01:03 +0100 Subject: [PATCH 22/30] SWDEV-411880,SWDEV-411881 - Enable deviceAllocation[Malloc/New] tests (#388) --- catch/hipTestMain/config/config_amd_linux_common.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/catch/hipTestMain/config/config_amd_linux_common.json b/catch/hipTestMain/config/config_amd_linux_common.json index 39c403ef89..e7861dd7a5 100644 --- a/catch/hipTestMain/config/config_amd_linux_common.json +++ b/catch/hipTestMain/config/config_amd_linux_common.json @@ -107,9 +107,6 @@ "Unit_hipMemcpyDtoHAsync_Negative_Parameters", "Unit_hipMemcpyHtoDAsync_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", "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/327 ===", "Unit_hiprtcGpuRdcComplrOptnTst", From a8640d8c6285e8b92be110cf80c9b6ee20988dbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mirza=20Halil=C4=8Devi=C4=87?= <109971222+mirza-halilcevic@users.noreply.github.com> Date: Mon, 14 Aug 2023 18:01:50 +0200 Subject: [PATCH 23/30] EXSWHTEC-275 - Implement tests for atomic CAS operations. (#197) --- catch/unit/atomics/CMakeLists.txt | 42 ++ catch/unit/atomics/arithmetic_common.hh | 449 ++++++++++++++++++ catch/unit/atomics/atomicCAS.cc | 172 +++++++ .../atomics/atomicCAS_negative_kernels.cc | 62 +++ .../atomics/atomicCAS_negative_kernels_rtc.hh | 273 +++++++++++ catch/unit/atomics/atomicCAS_system.cc | 185 ++++++++ 6 files changed, 1183 insertions(+) create mode 100644 catch/unit/atomics/CMakeLists.txt create mode 100644 catch/unit/atomics/arithmetic_common.hh create mode 100644 catch/unit/atomics/atomicCAS.cc create mode 100644 catch/unit/atomics/atomicCAS_negative_kernels.cc create mode 100644 catch/unit/atomics/atomicCAS_negative_kernels_rtc.hh create mode 100644 catch/unit/atomics/atomicCAS_system.cc diff --git a/catch/unit/atomics/CMakeLists.txt b/catch/unit/atomics/CMakeLists.txt new file mode 100644 index 0000000000..fc30955d5a --- /dev/null +++ b/catch/unit/atomics/CMakeLists.txt @@ -0,0 +1,42 @@ +# 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. + +set(TEST_SRC + atomicCAS.cc + atomicCAS_system.cc +) + +if(HIP_PLATFORM MATCHES "nvidia") + set_source_files_properties(atomicCAS_system.cc PROPERTIES COMPILE_FLAGS "-rdc=true -gencode arch=compute_60,code=sm_60 -gencode arch=compute_70,code=sm_70 -gencode arch=compute_80,code=sm_80") + hip_add_exe_to_target(NAME AtomicsTest + TEST_SRC ${TEST_SRC} + TEST_TARGET_NAME build_tests + LINKER_LIBS "nvrtc -rdc=true -gencode arch=compute_60,code=sm_60 -gencode arch=compute_70,code=sm_70 -gencode arch=compute_80,code=sm_80") +elseif(HIP_PLATFORM MATCHES "amd") + hip_add_exe_to_target(NAME AtomicsTest + TEST_SRC ${TEST_SRC} + TEST_TARGET_NAME build_tests + LINKER_LIBS hiprtc) +endif() + +add_test(NAME Unit_atomicCAS_Negative_Parameters + COMMAND python3 ${CMAKE_CURRENT_SOURCE_DIR}/../compileAndCaptureOutput.py + ${CMAKE_CURRENT_SOURCE_DIR} ${HIP_PLATFORM} ${HIP_PATH} + atomicCAS_negative_kernels.cc 48) diff --git a/catch/unit/atomics/arithmetic_common.hh b/catch/unit/atomics/arithmetic_common.hh new file mode 100644 index 0000000000..384665b502 --- /dev/null +++ b/catch/unit/atomics/arithmetic_common.hh @@ -0,0 +1,449 @@ +/* +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. +*/ + +#pragma once + +#include +#include +#include +#include + +namespace cg = cooperative_groups; + +enum class AtomicOperation { + kAdd = 0, + kAddSystem, + kSub, + kSubSystem, + kInc, + kDec, + kUnsafeAdd, + kSafeAdd, + kCASAdd, + kCASAddSystem +}; + +constexpr auto kIntegerTestValue = 7; +constexpr auto kFloatingPointTestValue = 3.125; +constexpr auto kIncDecWraparoundValue = 1023; + +template +__host__ __device__ TestType GetTestValue() { + if constexpr (operation == AtomicOperation::kInc || operation == AtomicOperation::kDec) { + return kIncDecWraparoundValue; + } + + return std::is_floating_point_v ? kFloatingPointTestValue : kIntegerTestValue; +} + +template __device__ TestType CASAtomicAdd(TestType* address, TestType val) { + TestType old = *address, assumed; + + do { + assumed = old; + old = atomicCAS(address, assumed, val + assumed); + } while (assumed != old); + + return old; +} + +template +__device__ TestType CASAtomicAddSystem(TestType* address, TestType val) { + TestType old = *address, assumed; + + do { + assumed = old; + old = atomicCAS_system(address, assumed, val + assumed); + } while (assumed != old); + + return old; +} + +template +__device__ TestType PerformAtomicOperation(TestType* const mem) { + const auto val = GetTestValue(); + + if constexpr (operation == AtomicOperation::kAdd) { + return atomicAdd(mem, val); + } else if constexpr (operation == AtomicOperation::kAddSystem) { + return atomicAdd_system(mem, val); + } else if constexpr (operation == AtomicOperation::kSub) { + return atomicSub(mem, val); + } else if constexpr (operation == AtomicOperation::kSubSystem) { + return atomicSub_system(mem, val); + } else if constexpr (operation == AtomicOperation::kInc) { + return atomicInc(mem, val); + } else if constexpr (operation == AtomicOperation::kDec) { + return atomicDec(mem, val); + } else if constexpr (operation == AtomicOperation::kUnsafeAdd) { + return unsafeAtomicAdd(mem, val); + } else if constexpr (operation == AtomicOperation::kSafeAdd) { + return safeAtomicAdd(mem, val); + } else if constexpr (operation == AtomicOperation::kCASAdd) { + return CASAtomicAdd(mem, val); + } else if constexpr (operation == AtomicOperation::kCASAddSystem) { + return CASAtomicAddSystem(mem, val); + } +} + +template +__global__ void TestKernel(TestType* const global_mem, TestType* const old_vals) { + __shared__ TestType shared_mem; + + const auto tid = cg::this_grid().thread_rank(); + + TestType* const mem = use_shared_mem ? &shared_mem : global_mem; + + if constexpr (use_shared_mem) { + if (tid == 0) mem[0] = global_mem[0]; + __syncthreads(); + } + + old_vals[tid] = PerformAtomicOperation(mem); + + if constexpr (use_shared_mem) { + __syncthreads(); + if (tid == 0) global_mem[0] = mem[0]; + } +} + +template +__host__ __device__ TestType* PitchedOffset(TestType* const ptr, const unsigned int pitch, + const unsigned int idx) { + const auto byte_ptr = reinterpret_cast(ptr); + return reinterpret_cast(byte_ptr + idx * pitch); +} + +template +__global__ void TestKernel(TestType* const global_mem, TestType* const old_vals, + const unsigned int width, const unsigned pitch) { + extern __shared__ uint8_t shared_mem[]; + + const auto tid = cg::this_grid().thread_rank(); + + TestType* const mem = use_shared_mem ? reinterpret_cast(shared_mem) : global_mem; + + if constexpr (use_shared_mem) { + if (tid < width) { + const auto target = PitchedOffset(mem, pitch, tid); + *target = *PitchedOffset(global_mem, pitch, tid); + }; + __syncthreads(); + } + + old_vals[tid] = + PerformAtomicOperation(PitchedOffset(mem, pitch, tid % width)); + + if constexpr (use_shared_mem) { + __syncthreads(); + if (tid < width) { + const auto target = PitchedOffset(global_mem, pitch, tid); + *target = *PitchedOffset(mem, pitch, tid); + }; + } +} + +struct TestParams { + auto ThreadCount() const { + return blocks.x * blocks.y * blocks.z * threads.x * threads.y * threads.z; + } + + auto HostIterationsPerThread() const { + return std::max(num_devices * kernel_count * ThreadCount() / 20, width); + } + + dim3 blocks; + dim3 threads; + unsigned int num_devices = 1u; + unsigned int kernel_count = 1u; + unsigned int width = 1u; + unsigned int pitch = 0u; + unsigned int host_thread_count = 0u; + LinearAllocs alloc_type; +}; + +template +std::tuple, std::vector> TestKernelHostRef(const TestParams& p) { + const auto val = GetTestValue(); + + const auto total_thread_count = p.num_devices * p.kernel_count * p.ThreadCount() + + p.host_thread_count * p.HostIterationsPerThread(); + + std::vector res_vals(p.width); + std::vector old_vals; + old_vals.reserve(total_thread_count); + + auto perform_op = [&](unsigned id) { + auto& res = res_vals[id % p.width]; + old_vals.push_back(res); + + if constexpr (operation == AtomicOperation::kAdd || operation == AtomicOperation::kAddSystem || + operation == AtomicOperation::kUnsafeAdd || + operation == AtomicOperation::kSafeAdd || operation == AtomicOperation::kCASAdd || + operation == AtomicOperation::kCASAddSystem) { + res = res + val; + } else if constexpr (operation == AtomicOperation::kSub || + operation == AtomicOperation::kSubSystem) { + res = res - val; + } else if constexpr (operation == AtomicOperation::kInc) { + res = (res >= val) ? 0 : res + 1; + } else if constexpr (operation == AtomicOperation::kDec) { + res = ((res == 0) || (res > val)) ? val : res - 1; + } + }; + + for (auto i = 0u; i < p.num_devices; ++i) { + for (auto j = 0u; j < p.kernel_count; ++j) { + for (auto tid = 0u; tid < p.ThreadCount(); ++tid) { + perform_op(tid); + } + } + } + + for (auto i = 0u; i < p.host_thread_count; ++i) { + for (auto j = 0u; j < p.HostIterationsPerThread(); ++j) { + perform_op(j); + } + } + + return {res_vals, old_vals}; +} + +template +void Verify(const TestParams& p, std::vector& res_vals, std::vector& old_vals) { + auto [expected_res_vals, expected_old_vals] = TestKernelHostRef(p); + + for (auto i = 0u; i < res_vals.size(); ++i) { + INFO("Results index: " << i); + REQUIRE(expected_res_vals[i] == res_vals[i]); + } + + std::sort(begin(old_vals), end(old_vals)); + std::sort(begin(expected_old_vals), end(expected_old_vals)); + for (auto i = 0u; i < old_vals.size(); ++i) { + INFO("Old values index: " << i); + REQUIRE(expected_old_vals[i] == old_vals[i]); + } +} + +template +void LaunchKernel(const TestParams& p, hipStream_t stream, TestType* const mem_ptr, + TestType* const old_vals) { + const auto shared_mem_size = use_shared_mem ? p.width * p.pitch : 0u; + if (p.width == 1 && p.pitch == sizeof(TestType)) + TestKernel + <<>>(mem_ptr, old_vals); + else + TestKernel + <<>>(mem_ptr, old_vals, p.width, p.pitch); +} + +template +void HostAtomicOperation(const unsigned int iterations, TestType* mem, TestType* const old_vals, + const unsigned int width, const unsigned pitch, TestType base_val) { + const auto val = GetTestValue(); + + for (auto i = 0u; i < iterations; ++i) { + if constexpr (operation == AtomicOperation::kAddSystem || + operation == AtomicOperation::kCASAddSystem) { + old_vals[i] = __atomic_fetch_add(PitchedOffset(mem, pitch, i % width), val, __ATOMIC_RELAXED); + } else if constexpr (operation == AtomicOperation::kSubSystem) { + old_vals[i] = __atomic_fetch_sub(PitchedOffset(mem, pitch, i % width), val, __ATOMIC_RELAXED); + } + } +} + +template +void PerformHostAtomicOperation(const TestParams& p, TestType* mem, TestType* const old_vals) { + if (p.host_thread_count == 0) { + return; + } + + const auto host_base_val = p.num_devices * p.kernel_count * p.ThreadCount(); + + std::vector threads; + for (auto i = 0u; i < p.host_thread_count; ++i) { + const auto iterations = p.HostIterationsPerThread(); + const auto thread_base_val = host_base_val + i * iterations; + threads.push_back(std::thread(HostAtomicOperation, iterations, mem, + old_vals + thread_base_val, p.width, p.pitch, thread_base_val)); + } + + for (auto& th : threads) { + th.join(); + } +} + +template +void TestCore(const TestParams& p) { + const unsigned int flags = + p.alloc_type == LinearAllocs::mallocAndRegister ? hipHostRegisterMapped : 0u; + + const auto old_vals_alloc_size = p.kernel_count * p.ThreadCount() * sizeof(TestType); + std::vector> old_vals_devs; + std::vector streams; + for (auto i = 0; i < p.num_devices; ++i) { + HIP_CHECK(hipSetDevice(i)); + old_vals_devs.emplace_back(LinearAllocs::hipMalloc, old_vals_alloc_size); + for (auto j = 0; j < p.kernel_count; ++j) { + streams.emplace_back(Streams::created); + } + } + + const auto mem_alloc_size = p.width * p.pitch; + LinearAllocGuard mem_dev(p.alloc_type, mem_alloc_size, flags); + + std::vector old_vals(p.num_devices * p.kernel_count * p.ThreadCount() + + p.host_thread_count * p.HostIterationsPerThread()); + std::vector res_vals(p.width); + + TestType* const mem_ptr = + p.alloc_type == LinearAllocs::hipMalloc ? mem_dev.ptr() : mem_dev.host_ptr(); + + HIP_CHECK(hipMemset(mem_ptr, 0, mem_alloc_size)); + + for (auto i = 0u; i < p.num_devices; ++i) { + for (auto j = 0u; j < p.kernel_count; ++j) { + const auto& stream = streams[i * p.kernel_count + j].stream(); + const auto old_vals = old_vals_devs[i].ptr() + j * p.ThreadCount(); + LaunchKernel(p, stream, mem_dev.ptr(), old_vals); + } + } + + PerformHostAtomicOperation(p, mem_dev.host_ptr(), old_vals.data()); + + for (auto i = 0u; i < p.num_devices; ++i) { + const auto device_offset = i * p.kernel_count * p.ThreadCount(); + HIP_CHECK(hipMemcpy(old_vals.data() + device_offset, old_vals_devs[i].ptr(), + old_vals_alloc_size, hipMemcpyDeviceToHost)); + } + HIP_CHECK(hipMemcpy2D(res_vals.data(), sizeof(TestType), mem_ptr, p.pitch, sizeof(TestType), + p.width, hipMemcpyDeviceToHost)); + + Verify(p, res_vals, old_vals); +} + +inline dim3 GenerateThreadDimensions() { return GENERATE(dim3(16), dim3(1024)); } + +inline dim3 GenerateBlockDimensions() { + int sm_count = 0; + HIP_CHECK(hipDeviceGetAttribute(&sm_count, hipDeviceAttributeMultiprocessorCount, 0)); + return GENERATE_COPY(dim3(sm_count), dim3(sm_count + sm_count / 2)); +} + +template +void SingleDeviceSingleKernelTest(const unsigned int width, const unsigned int pitch) { + TestParams params; + params.num_devices = 1; + params.kernel_count = 1; + params.threads = GenerateThreadDimensions(); + params.width = width; + params.pitch = pitch; + + SECTION("Global memory") { + params.blocks = GenerateBlockDimensions(); + using LA = LinearAllocs; + for (const auto alloc_type : + {LA::hipMalloc, LA::hipHostMalloc, LA::hipMallocManaged, LA::mallocAndRegister}) { + params.alloc_type = alloc_type; + DYNAMIC_SECTION("Allocation type: " << to_string(alloc_type)) { + TestCore(params); + } + } + } + + SECTION("Shared memory") { + params.blocks = dim3(1); + params.alloc_type = LinearAllocs::hipMalloc; + TestCore(params); + } +} + +template +void SingleDeviceMultipleKernelTest(const unsigned int kernel_count, const unsigned int width, + const unsigned int pitch) { + int concurrent_kernels = 0; + HIP_CHECK(hipDeviceGetAttribute(&concurrent_kernels, hipDeviceAttributeConcurrentKernels, 0)); + if (!concurrent_kernels) { + HipTest::HIP_SKIP_TEST("Test requires support for concurrent kernel execution"); + return; + } + + TestParams params; + params.num_devices = 1; + params.kernel_count = kernel_count; + params.blocks = GenerateBlockDimensions(); + params.threads = GenerateThreadDimensions(); + params.width = width; + params.pitch = pitch; + + using LA = LinearAllocs; + for (const auto alloc_type : + {LA::hipMalloc, LA::hipHostMalloc, LA::hipMallocManaged, LA::mallocAndRegister}) { + params.alloc_type = alloc_type; + DYNAMIC_SECTION("Allocation type: " << to_string(alloc_type)) { + TestCore(params); + } + } +} + +template +void MultipleDeviceMultipleKernelAndHostTest(const unsigned int num_devices, + const unsigned int kernel_count, + const unsigned int width, const unsigned int pitch, + const unsigned int host_thread_count = 0u) { + if (num_devices > 1) { + if (HipTest::getDeviceCount() < num_devices) { + std::string msg = std::to_string(num_devices) + " devices are required"; + HipTest::HIP_SKIP_TEST(msg.c_str()); + return; + } + } + + if (kernel_count > 1) { + for (auto i = 0u; i < num_devices; ++i) { + int concurrent_kernels = 0; + HIP_CHECK(hipDeviceGetAttribute(&concurrent_kernels, hipDeviceAttributeConcurrentKernels, i)); + if (!concurrent_kernels) { + HipTest::HIP_SKIP_TEST("Test requires support for concurrent kernel execution"); + return; + } + } + } + + TestParams params; + params.num_devices = num_devices; + params.kernel_count = kernel_count; + params.blocks = GenerateBlockDimensions(); + params.threads = GenerateThreadDimensions(); + params.width = width; + params.pitch = pitch; + params.host_thread_count = host_thread_count; + + using LA = LinearAllocs; + for (const auto alloc_type : {LA::hipHostMalloc, LA::hipMallocManaged, LA::mallocAndRegister}) { + params.alloc_type = alloc_type; + DYNAMIC_SECTION("Allocation type: " << to_string(alloc_type)) { + TestCore(params); + } + } +} \ No newline at end of file diff --git a/catch/unit/atomics/atomicCAS.cc b/catch/unit/atomics/atomicCAS.cc new file mode 100644 index 0000000000..3be684306d --- /dev/null +++ b/catch/unit/atomics/atomicCAS.cc @@ -0,0 +1,172 @@ +/* +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 "arithmetic_common.hh" +#include "atomicCAS_negative_kernels_rtc.hh" + +#include + +/** + * @addtogroup atomicCAS atomicCAS + * @{ + * @ingroup AtomicsTest + */ + +#ifdef HT_NVIDIA +#define TYPES +#else +#define TYPES , float, double +#endif + +/** + * Test Description + * ------------------------ + * - Executes a single kernel on a single device wherein all threads will perform an atomic + * addition, implemented using an atomic CAS operation, on a target memory location. Each thread + * will add the same value to the memory location, storing the return value into a separate output + * array slot corresponding to it. Once complete, the output array and target memory is validated to + * contain all the expected values. Several memory access patterns are tested: + * -# All threads exchange to a single, compile time deducible, memory location + * -# Each thread targets an array containing warp_size elements, using tid % warp_size + * for indexing + * -# Same as the above, but the elements are spread out by L1 cache line size bytes. + * + * - The test is run for: + * - All overloads of atomicCAS + * - hipMalloc, hipMallocManaged, hipHostMalloc and hipHostRegister allocated memory + * - Shared memory + * - Several grid and block dimension combinations (only one block is used for shared memory). + * Test source + * ------------------------ + * - unit/atomics/atomicCAS.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEMPLATE_TEST_CASE("Unit_atomicCAS_Positive", "", int, unsigned int, unsigned long long TYPES) { + int warp_size = 0; + HIP_CHECK(hipDeviceGetAttribute(&warp_size, hipDeviceAttributeWarpSize, 0)); + const auto cache_line_size = 128u; + + for (auto current = 0; current < cmd_options.iterations; ++current) { + DYNAMIC_SECTION("Same address " << current) { + SingleDeviceSingleKernelTest(1, sizeof(TestType)); + } + + DYNAMIC_SECTION("Adjacent addresses " << current) { + SingleDeviceSingleKernelTest(warp_size, sizeof(TestType)); + } + + DYNAMIC_SECTION("Scattered addresses " << current) { + SingleDeviceSingleKernelTest(warp_size, cache_line_size); + } + } +} + +/** + * Test Description + * ------------------------ + * - Executes a kernel two times concurrently on a single device wherein all threads will perform + * an atomic addition, implemented using an atomic CAS operation, on a target memory location. Each + * thread will add the same value to the memory location, storing the return value into a separate + * output array slot corresponding to it. Once complete, the output array and target memory is + * validated to contain all the expected values. Several memory access patterns are tested: + * -# All threads exchange to a single, compile time deducible, memory location + * -# Each thread targets an array containing warp_size elements, using tid % warp_size + * for indexing + * -# Same as the above, but the elements are spread out by L1 cache line size bytes. + * + * - The test is run for: + * - All overloads of atomicCAS + * - hipMalloc, hipMallocManaged, hipHostMalloc and hipHostRegister allocated memory + * - Several grid and block dimension combinations. + * Test source + * ------------------------ + * - unit/atomics/atomicCAS.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEMPLATE_TEST_CASE("Unit_atomicCAS_Positive_Multi_Kernel", "", int, unsigned int, + unsigned long long TYPES) { + int warp_size = 0; + HIP_CHECK(hipDeviceGetAttribute(&warp_size, hipDeviceAttributeWarpSize, 0)); + const auto cache_line_size = 128u; + + for (auto current = 0; current < cmd_options.iterations; ++current) { + DYNAMIC_SECTION("Same address " << current) { + SingleDeviceMultipleKernelTest(2, 1, sizeof(TestType)); + } + + DYNAMIC_SECTION("Adjacent addresses " << current) { + SingleDeviceMultipleKernelTest(2, warp_size, + sizeof(TestType)); + } + + DYNAMIC_SECTION("Scattered addresses " << current) { + SingleDeviceMultipleKernelTest(2, warp_size, + cache_line_size); + } + } +} + +/** + * Test Description + * ------------------------ + * - RTCs kernels that pass combinations of arguments of invalid types for all overloads of + * atomicCAS. + * Test source + * ------------------------ + * - unit/atomics/atomicCAS.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_atomicCAS_Negative_Parameters_RTC") { + hiprtcProgram program{}; + + const auto program_source = GENERATE(kAtomicCAS_int, kAtomicCAS_uint, kAtomicCAS_ulong, + kAtomicCAS_ulonglong, kAtomicCAS_float, kAtomicCAS_double); + HIPRTC_CHECK( + hiprtcCreateProgram(&program, program_source, "atomicCAS_negative.cc", 0, nullptr, nullptr)); + hiprtcResult result{hiprtcCompileProgram(program, 0, nullptr)}; + + // Get the compile log and count compiler error messages + size_t log_size{}; + HIPRTC_CHECK(hiprtcGetProgramLogSize(program, &log_size)); + std::string log(log_size, ' '); + HIPRTC_CHECK(hiprtcGetProgramLog(program, log.data())); + int error_count{0}; + + int expected_error_count{8}; + std::string error_message{"error:"}; + + size_t n_pos = log.find(error_message, 0); + while (n_pos != std::string::npos) { + ++error_count; + n_pos = log.find(error_message, n_pos + 1); + } + + HIPRTC_CHECK(hiprtcDestroyProgram(&program)); + HIPRTC_CHECK_ERROR(result, HIPRTC_ERROR_COMPILATION); + REQUIRE(error_count == expected_error_count); +} diff --git a/catch/unit/atomics/atomicCAS_negative_kernels.cc b/catch/unit/atomics/atomicCAS_negative_kernels.cc new file mode 100644 index 0000000000..b0390bb3fa --- /dev/null +++ b/catch/unit/atomics/atomicCAS_negative_kernels.cc @@ -0,0 +1,62 @@ +/* +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 + +class Dummy { + public: + __device__ Dummy() {} + __device__ ~Dummy() {} +}; + +#define ATOMIC_CAS_NEGATIVE_KERNEL(type_name) \ + __global__ void atomicCAS_v1(type_name* address, type_name* result) { \ + *result = atomicCAS(&address, 12, 13); \ + } \ + __global__ void atomicCAS_v2(type_name* address, type_name* result) { \ + *result = atomicCAS(address, address, 13); \ + } \ + __global__ void atomicCAS_v3(type_name* address, type_name* result) { \ + *result = atomicCAS(address, 12, address); \ + } \ + __global__ void atomicCAS_v4(Dummy* address, type_name* result) { \ + *result = atomicCAS(address, 12, 13); \ + } \ + __global__ void atomicCAS_v5(char* address, type_name* result) { \ + *result = atomicCAS(address, 12, 13); \ + } \ + __global__ void atomicCAS_v6(short* address, type_name* result) { \ + *result = atomicCAS(address, 12, 13); \ + } \ + __global__ void atomicCAS_v7(long* address, type_name* result) { \ + *result = atomicCAS(address, 12, 13); \ + } \ + __global__ void atomicCAS_v8(long long* address, type_name* result) { \ + *result = atomicCAS(address, 12, 13); \ + } + +ATOMIC_CAS_NEGATIVE_KERNEL(int) +ATOMIC_CAS_NEGATIVE_KERNEL(unsigned int) +ATOMIC_CAS_NEGATIVE_KERNEL(unsigned long) +ATOMIC_CAS_NEGATIVE_KERNEL(unsigned long long) +ATOMIC_CAS_NEGATIVE_KERNEL(float) +ATOMIC_CAS_NEGATIVE_KERNEL(double) diff --git a/catch/unit/atomics/atomicCAS_negative_kernels_rtc.hh b/catch/unit/atomics/atomicCAS_negative_kernels_rtc.hh new file mode 100644 index 0000000000..952c4892fb --- /dev/null +++ b/catch/unit/atomics/atomicCAS_negative_kernels_rtc.hh @@ -0,0 +1,273 @@ +/* +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. +*/ + +#pragma once + +/* +Negative kernels used for the atomics negative Test Cases that are using RTC. +*/ + +static constexpr auto kAtomicCAS_int{ + R"( + class Dummy { + public: + __device__ Dummy() {} + __device__ ~Dummy() {} + }; + + __global__ void atomicCAS_int_v1(int* address, int* result) { + *result = atomicCAS(&address, 12, 13); + } + + __global__ void atomicCAS_int_v2(int* address, int* result) { + *result = atomicCAS(address, address, 13); + } + + __global__ void atomicCAS_int_v3(int* address, int* result) { + *result = atomicCAS(address, 12, address); + } + + __global__ void atomicCAS_int_v4(Dummy* address, int* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_int_v5(char* address, int* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_int_v6(short* address, int* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_int_v7(long* address, int* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_int_v8(long long* address, int* result) { + *result = atomicCAS(address, 12, 13); + } + )"}; + +static constexpr auto kAtomicCAS_uint{ + R"( + class Dummy { + public: + __device__ Dummy() {} + __device__ ~Dummy() {} + }; + + __global__ void atomicCAS_uint_v1(unsigned int* address, unsigned int* result) { + *result = atomicCAS(&address, 12, 13); + } + + __global__ void atomicCAS_uint_v2(unsigned int* address, unsigned int* result) { + *result = atomicCAS(address, address, 13); + } + + __global__ void atomicCAS_uint_v3(unsigned int* address, unsigned int* result) { + *result = atomicCAS(address, 12, address); + } + + __global__ void atomicCAS_uint_v4(Dummy* address, unsigned int* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_uint_v5(char* address, unsigned int* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_uint_v6(short* address, unsigned int* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_uint_v7(long* address, unsigned int* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_uint_v8(long long* address, unsigned int* result) { + *result = atomicCAS(address, 12, 13); + } + )"}; + +static constexpr auto kAtomicCAS_ulong{ + R"( + class Dummy { + public: + __device__ Dummy() {} + __device__ ~Dummy() {} + }; + + __global__ void atomicCAS_ulong_v1(unsigned long* address, unsigned long* result) { + *result = atomicCAS(&address, 12, 13); + } + + __global__ void atomicCAS_ulong_v2(unsigned long* address, unsigned long* result) { + *result = atomicCAS(address, address, 13); + } + + __global__ void atomicCAS_ulong_v3(unsigned long* address, unsigned long* result) { + *result = atomicCAS(address, 12, address); + } + + __global__ void atomicCAS_ulong_v4(Dummy* address, unsigned long* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_ulong_v5(char* address, unsigned long* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_ulong_v6(short* address, unsigned long* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_ulong_v7(long* address, unsigned long* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_ulong_v8(long long* address, unsigned long* result) { + *result = atomicCAS(address, 12, 13); + } + )"}; + +static constexpr auto kAtomicCAS_ulonglong{ + R"( + class Dummy { + public: + __device__ Dummy() {} + __device__ ~Dummy() {} + }; + + __global__ void atomicCAS_ulonglong_v1(unsigned long long* address, unsigned long long* result) { + *result = atomicCAS(&address, 12, 13); + } + + __global__ void atomicCAS_ulonglong_v2(unsigned long long* address, unsigned long long* result) { + *result = atomicCAS(address, address, 13); + } + + __global__ void atomicCAS_ulonglong_v3(unsigned long long* address, unsigned long long* result) { + *result = atomicCAS(address, 12, address); + } + + __global__ void atomicCAS_ulonglong_v4(Dummy* address, unsigned long long* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_ulonglong_v5(char* address, unsigned long long* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_ulonglong_v6(short* address, unsigned long long* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_ulonglong_v7(long* address, unsigned long long* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_ulonglong_v8(long long* address, unsigned long long* result) { + *result = atomicCAS(address, 12, 13); + } + )"}; + +static constexpr auto kAtomicCAS_float{ + R"( + class Dummy { + public: + __device__ Dummy() {} + __device__ ~Dummy() {} + }; + + __global__ void atomicCAS_float_v1(float* address, float* result) { + *result = atomicCAS(&address, 12, 13); + } + + __global__ void atomicCAS_float_v2(float* address, float* result) { + *result = atomicCAS(address, address, 13); + } + + __global__ void atomicCAS_float_v3(float* address, float* result) { + *result = atomicCAS(address, 12, address); + } + + __global__ void atomicCAS_float_v4(Dummy* address, float* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_float_v5(char* address, float* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_float_v6(short* address, float* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_float_v7(long* address, float* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_float_v8(long long* address, float* result) { + *result = atomicCAS(address, 12, 13); + } + )"}; + +static constexpr auto kAtomicCAS_double{ + R"( + class Dummy { + public: + __device__ Dummy() {} + __device__ ~Dummy() {} + }; + + __global__ void atomicCAS_double_v1(double* address, double* result) { + *result = atomicCAS(&address, 12, 13); + } + + __global__ void atomicCAS_double_v2(double* address, double* result) { + *result = atomicCAS(address, address, 13); + } + + __global__ void atomicCAS_double_v3(double* address, double* result) { + *result = atomicCAS(address, 12, address); + } + + __global__ void atomicCAS_double_v4(Dummy* address, double* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_double_v5(char* address, double* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_double_v6(short* address, double* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_double_v7(long* address, double* result) { + *result = atomicCAS(address, 12, 13); + } + + __global__ void atomicCAS_double_v8(long long* address, double* result) { + *result = atomicCAS(address, 12, 13); + } + )"}; diff --git a/catch/unit/atomics/atomicCAS_system.cc b/catch/unit/atomics/atomicCAS_system.cc new file mode 100644 index 0000000000..8f2dd8306b --- /dev/null +++ b/catch/unit/atomics/atomicCAS_system.cc @@ -0,0 +1,185 @@ +/* +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 "arithmetic_common.hh" + +#include + +/** + * @addtogroup atomicCAS_system atomicCAS_system + * @{ + * @ingroup AtomicsTest + */ + +#ifdef HT_NVIDIA +#define TYPES +#else +#define TYPES , float, double +#endif + +/** + * Test Description + * ------------------------ + * - Executes a kernel two times concurrently on a two devices wherein all threads will perform + * an atomic addition, implemented using an atomic CAS operation, on a target memory location. Each + * thread will add the same value to the memory location, storing the return value into a separate + * output array slot corresponding to it. Once complete, the output array and target memory is + * validated to contain all the expected values. Several memory access patterns are tested: + * -# All threads exchange to a single, compile time deducible, memory location + * -# Each thread targets an array containing warp_size elements, using tid % warp_size + * for indexing + * -# Same as the above, but the elements are spread out by L1 cache line size bytes. + * + * - The test is run for: + * - All overloads of atomicCAS_system + * - hipMalloc, hipMallocManaged, hipHostMalloc and hipHostRegister allocated memory + * - Several grid and block dimension combinations. + * Test source + * ------------------------ + * - unit/atomics/atomicCAS_system.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEMPLATE_TEST_CASE("Unit_atomicCAS_system_Positive_Peer_GPUs", "", int, unsigned int, + unsigned long long TYPES) { + int warp_size = 0; + HIP_CHECK(hipDeviceGetAttribute(&warp_size, hipDeviceAttributeWarpSize, 0)); + const auto cache_line_size = 128u; + + for (auto current = 0; current < cmd_options.iterations; ++current) { + DYNAMIC_SECTION("Same address " << current) { + MultipleDeviceMultipleKernelAndHostTest( + 2, 2, 1, sizeof(TestType)); + } + + DYNAMIC_SECTION("Adjacent addresses " << current) { + MultipleDeviceMultipleKernelAndHostTest( + 2, 2, warp_size, sizeof(TestType)); + } + + DYNAMIC_SECTION("Scattered addresses " << current) { + MultipleDeviceMultipleKernelAndHostTest( + 2, 2, warp_size, cache_line_size); + } + } +} + +/** + * Test Description + * ------------------------ + * - Executes a kernel on a single device wherein all threads will perform + * an atomic addition, implemented using an atomic CAS operation, on a target memory location. + * Each thread will add the same value to the memory location, storing the return value into a + * separate output array slot corresponding to it. While the kernel is running, the host + * performs atomic additions, in 4 threads, on the same memory location(s). Once complete, the + * output array and target memory is validated to contain all the expected values. Several + * memory access patterns are tested: + * -# All threads exchange to a single, compile time deducible, memory location + * -# Each thread targets an array containing warp_size elements, using tid % warp_size + * for indexing + * -# Same as the above, but the elements are spread out by L1 cache line size bytes. + * + * - The test is run for: + * - All overloads of atomicCAS_system + * - hipMalloc, hipMallocManaged, hipHostMalloc and hipHostRegister allocated memory + * - Several grid and block dimension combinations. + * Test source + * ------------------------ + * - unit/atomics/atomicCAS_system.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEMPLATE_TEST_CASE("Unit_atomicCAS_system_Positive_Host_And_GPU", "", int, unsigned int, + unsigned long long TYPES) { + int warp_size = 0; + HIP_CHECK(hipDeviceGetAttribute(&warp_size, hipDeviceAttributeWarpSize, 0)); + const auto cache_line_size = 128u; + + for (auto current = 0; current < cmd_options.iterations; ++current) { + DYNAMIC_SECTION("Same address " << current) { + MultipleDeviceMultipleKernelAndHostTest( + 1, 1, 1, sizeof(TestType), 4); + } + + DYNAMIC_SECTION("Adjacent addresses " << current) { + MultipleDeviceMultipleKernelAndHostTest( + 1, 1, warp_size, sizeof(TestType), 4); + } + + DYNAMIC_SECTION("Scattered addresses " << current) { + MultipleDeviceMultipleKernelAndHostTest( + 1, 1, warp_size, cache_line_size, 4); + } + } +} + +/** + * Test Description + * ------------------------ + * - Executes a kernel two times on two devices wherein all threads will perform + * an atomic addition, implemented using an atomic CAS operation, on a target memory location. + * Each thread will add the same value to the memory location, storing the return value into a + * separate output array slot corresponding to it. While the kernel is running, the host + * performs atomic additions, in 4 threads, on the same memory location(s). Once complete, the + * output array and target memory is validated to contain all the expected values. Several + * memory access patterns are tested: + * -# All threads exchange to a single, compile time deducible, memory location + * -# Each thread targets an array containing warp_size elements, using tid % warp_size + * for indexing + * -# Same as the above, but the elements are spread out by L1 cache line size bytes. + * + * - The test is run for: + * - All overloads of atomicCAS_system + * - hipMalloc, hipMallocManaged, hipHostMalloc and hipHostRegister allocated memory + * - Several grid and block dimension combinations. + * Test source + * ------------------------ + * - unit/atomics/atomicCAS_system.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEMPLATE_TEST_CASE("Unit_atomicCAS_system_Positive_Host_And_Peer_GPUs", "", int, unsigned int, + unsigned long long TYPES) { + int warp_size = 0; + HIP_CHECK(hipDeviceGetAttribute(&warp_size, hipDeviceAttributeWarpSize, 0)); + const auto cache_line_size = 128u; + + for (auto current = 0; current < cmd_options.iterations; ++current) { + DYNAMIC_SECTION("Same address " << current) { + MultipleDeviceMultipleKernelAndHostTest( + 2, 2, 1, sizeof(TestType), 4); + } + + DYNAMIC_SECTION("Adjacent addresses " << current) { + MultipleDeviceMultipleKernelAndHostTest( + 2, 2, warp_size, sizeof(TestType), 4); + } + + DYNAMIC_SECTION("Scattered addresses " << current) { + MultipleDeviceMultipleKernelAndHostTest( + 2, 2, warp_size, cache_line_size, 4); + } + } +} From 605d5eee5d49851ad520c1788050c008d6f5c1d0 Mon Sep 17 00:00:00 2001 From: Satyanvesh Dittakavi <53337087+satyanveshd@users.noreply.github.com> Date: Sat, 19 Aug 2023 21:38:59 +0530 Subject: [PATCH 24/30] Fix issues related to -Werror in hip tests (#396) * Fix issues related to -Werror * Correct the skipped tests --- .../config/config_amd_linux_MI2xx.json | 20 ++++++----- .../config/config_amd_linux_common.json | 20 ++++++----- .../config/config_amd_windows_MI2xx.json | 20 ++++++----- .../config/config_amd_windows_common.json | 20 ++++++----- catch/unit/deviceLib/hipTestDeviceDouble.cc | 1 - catch/unit/deviceLib/hipTestDeviceLimit.cc | 2 +- catch/unit/deviceLib/hipTestDeviceSymbol.cc | 1 - catch/unit/deviceLib/hipTestDotFunctions.cc | 6 ++-- catch/unit/deviceLib/hipTestHalf.cc | 3 ++ catch/unit/deviceLib/hipTestHost.cc | 6 ---- catch/unit/deviceLib/hipTestNativeHalf.cc | 2 -- .../unit/graph/hipGraphAddNodeBeginCapture.cc | 1 + catch/unit/kernel/hipDynamicShared.cc | 3 ++ catch/unit/kernel/hipEmptyKernel.cc | 2 ++ catch/unit/kernel/hipLanguageExtensions.cc | 4 ++- catch/unit/kernel/hipLaunchParm.cc | 5 +++ catch/unit/rtc/CMakeLists.txt | 3 +- catch/unit/rtc/RtcFunctions.cpp | 33 +++++++++---------- catch/unit/rtc/RtcUtility.cpp | 3 +- catch/unit/rtc/headers/printf_common.h | 5 ++- catch/unit/rtc/includepath.cc | 8 ++--- catch/unit/texture/hipTextureObjectTests.cc | 2 +- 22 files changed, 93 insertions(+), 77 deletions(-) diff --git a/catch/hipTestMain/config/config_amd_linux_MI2xx.json b/catch/hipTestMain/config/config_amd_linux_MI2xx.json index 74b6c2bf4a..20da9c8d66 100644 --- a/catch/hipTestMain/config/config_amd_linux_MI2xx.json +++ b/catch/hipTestMain/config/config_amd_linux_MI2xx.json @@ -19,15 +19,17 @@ "Unit_hipDestroyExternalSemaphore_Vulkan_Negative_Parameters", "Unit_Grid_Group_Sync_Positive_Basic", "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", - "Unit_hiprtc_saxpy.Unit_hiprtc_saxpy", - "Unit_hiprtc_warpsize.Unit_hiprtc_warpsize", - "Unit_hiprtc_functional.Unit_hiprtc_functional", - "Unit_hipStreamCaptureRtc.Unit_hipStreamCaptureRtc", - "Unit_hiprtc_cpp17.Unit_hiprtc_cpp17", - "Unit_hiprtc_namehandling.Unit_hiprtc_namehandling", - "Unit_hiprtc_getloweredname.Unit_hiprtc_getloweredname", - "Unit_hiprtc_test_hip_bfloat16.Unit_hiprtc_test_hip_bfloat16", - "Unit_RTC_LinkerAPI.Unit_RTC_LinkerAPI" + "Unit_hiprtc_saxpy", + "Unit_hiprtc_warpsize", + "Unit_hiprtc_functional", + "Unit_hipStreamCaptureRtc", + "Unit_hiprtc_cpp17", + "Unit_hiprtc_namehandling", + "Unit_hiprtc_getloweredname", + "Unit_hiprtc_test_hip_bfloat16", + "Unit_RTC_LinkerAPI", + "Unit_hiprtc_half_shuffle", + "Unit_hiprtc_includepath" ] } diff --git a/catch/hipTestMain/config/config_amd_linux_common.json b/catch/hipTestMain/config/config_amd_linux_common.json index e7861dd7a5..7068f83d1e 100644 --- a/catch/hipTestMain/config/config_amd_linux_common.json +++ b/catch/hipTestMain/config/config_amd_linux_common.json @@ -120,14 +120,16 @@ "Unit_hipStreamCreateWithPriority_ValidateWithEvents", "Unit_hipEventIpc", "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", - "Unit_hiprtc_saxpy.Unit_hiprtc_saxpy", - "Unit_hiprtc_warpsize.Unit_hiprtc_warpsize", - "Unit_hiprtc_functional.Unit_hiprtc_functional", - "Unit_hipStreamCaptureRtc.Unit_hipStreamCaptureRtc", - "Unit_hiprtc_cpp17.Unit_hiprtc_cpp17", - "Unit_hiprtc_namehandling.Unit_hiprtc_namehandling", - "Unit_hiprtc_getloweredname.Unit_hiprtc_getloweredname", - "Unit_hiprtc_test_hip_bfloat16.Unit_hiprtc_test_hip_bfloat16", - "Unit_RTC_LinkerAPI.Unit_RTC_LinkerAPI" + "Unit_hiprtc_saxpy", + "Unit_hiprtc_warpsize", + "Unit_hiprtc_functional", + "Unit_hipStreamCaptureRtc", + "Unit_hiprtc_cpp17", + "Unit_hiprtc_namehandling", + "Unit_hiprtc_getloweredname", + "Unit_hiprtc_test_hip_bfloat16", + "Unit_RTC_LinkerAPI", + "Unit_hiprtc_half_shuffle", + "Unit_hiprtc_includepath" ] } diff --git a/catch/hipTestMain/config/config_amd_windows_MI2xx.json b/catch/hipTestMain/config/config_amd_windows_MI2xx.json index 27ab1dd12b..8bb1400846 100644 --- a/catch/hipTestMain/config/config_amd_windows_MI2xx.json +++ b/catch/hipTestMain/config/config_amd_windows_MI2xx.json @@ -107,14 +107,16 @@ "Unit_hipStreamCreateWithPriority_MulthreadNonblockingflag", "Unit_hipDeviceGetUuid_Positive", "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", - "Unit_hiprtc_saxpy.Unit_hiprtc_saxpy", - "Unit_hiprtc_warpsize.Unit_hiprtc_warpsize", - "Unit_hiprtc_functional.Unit_hiprtc_functional", - "Unit_hipStreamCaptureRtc.Unit_hipStreamCaptureRtc", - "Unit_hiprtc_cpp17.Unit_hiprtc_cpp17", - "Unit_hiprtc_namehandling.Unit_hiprtc_namehandling", - "Unit_hiprtc_getloweredname.Unit_hiprtc_getloweredname", - "Unit_hiprtc_test_hip_bfloat16.Unit_hiprtc_test_hip_bfloat16", - "Unit_RTC_LinkerAPI.Unit_RTC_LinkerAPI" + "Unit_hiprtc_saxpy", + "Unit_hiprtc_warpsize", + "Unit_hiprtc_functional", + "Unit_hipStreamCaptureRtc", + "Unit_hiprtc_cpp17", + "Unit_hiprtc_namehandling", + "Unit_hiprtc_getloweredname", + "Unit_hiprtc_test_hip_bfloat16", + "Unit_RTC_LinkerAPI", + "Unit_hiprtc_half_shuffle", + "Unit_hiprtc_includepath" ] } diff --git a/catch/hipTestMain/config/config_amd_windows_common.json b/catch/hipTestMain/config/config_amd_windows_common.json index 398630a2fa..be73937091 100644 --- a/catch/hipTestMain/config/config_amd_windows_common.json +++ b/catch/hipTestMain/config/config_amd_windows_common.json @@ -226,14 +226,16 @@ "Unit_hipTextureMipmapRef2D_Positive_Check", "Unit_hipTextureMipmapRef2D_Negative_Parameters", "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", - "Unit_hiprtc_saxpy.Unit_hiprtc_saxpy", - "Unit_hiprtc_warpsize.Unit_hiprtc_warpsize", - "Unit_hiprtc_functional.Unit_hiprtc_functional", - "Unit_hipStreamCaptureRtc.Unit_hipStreamCaptureRtc", - "Unit_hiprtc_cpp17.Unit_hiprtc_cpp17", - "Unit_hiprtc_namehandling.Unit_hiprtc_namehandling", - "Unit_hiprtc_getloweredname.Unit_hiprtc_getloweredname", - "Unit_hiprtc_test_hip_bfloat16.Unit_hiprtc_test_hip_bfloat16", - "Unit_RTC_LinkerAPI.Unit_RTC_LinkerAPI" + "Unit_hiprtc_saxpy", + "Unit_hiprtc_warpsize", + "Unit_hiprtc_functional", + "Unit_hipStreamCaptureRtc", + "Unit_hiprtc_cpp17", + "Unit_hiprtc_namehandling", + "Unit_hiprtc_getloweredname", + "Unit_hiprtc_test_hip_bfloat16", + "Unit_RTC_LinkerAPI", + "Unit_hiprtc_half_shuffle", + "Unit_hiprtc_includepath" ] } diff --git a/catch/unit/deviceLib/hipTestDeviceDouble.cc b/catch/unit/deviceLib/hipTestDeviceDouble.cc index 865d54e9bd..40af03df98 100644 --- a/catch/unit/deviceLib/hipTestDeviceDouble.cc +++ b/catch/unit/deviceLib/hipTestDeviceDouble.cc @@ -181,7 +181,6 @@ bool run_llrint() { int passed = 0; for (int i = 0; i < 512; i++) { int x = round(A[i]); - int64_t y = x; if (B[i] == x) { passed = 1; } diff --git a/catch/unit/deviceLib/hipTestDeviceLimit.cc b/catch/unit/deviceLib/hipTestDeviceLimit.cc index d085efde34..92bf7a72e4 100644 --- a/catch/unit/deviceLib/hipTestDeviceLimit.cc +++ b/catch/unit/deviceLib/hipTestDeviceLimit.cc @@ -20,5 +20,5 @@ THE SOFTWARE. TEST_CASE("Unit_hipTestDeviceLimit_Basic") { size_t heap; HIP_CHECK(hipDeviceGetLimit(&heap, hipLimitMallocHeapSize)); - REQUIRE(heap != NULL); + REQUIRE(heap != 0); } diff --git a/catch/unit/deviceLib/hipTestDeviceSymbol.cc b/catch/unit/deviceLib/hipTestDeviceSymbol.cc index 3a2a103906..795309045c 100644 --- a/catch/unit/deviceLib/hipTestDeviceSymbol.cc +++ b/catch/unit/deviceLib/hipTestDeviceSymbol.cc @@ -180,7 +180,6 @@ TEST_CASE("Unit_hipGetSymbolAddressAndSize_Validation") { bool* checkOkD{nullptr}; bool checkOk = false; size_t symbolSize{}; - int* symbolArrAddress{}; float* symbolVarAddress{}; SECTION("Validate symbol size/address of static const variable") { diff --git a/catch/unit/deviceLib/hipTestDotFunctions.cc b/catch/unit/deviceLib/hipTestDotFunctions.cc index 43f0492da5..4161a342b7 100644 --- a/catch/unit/deviceLib/hipTestDotFunctions.cc +++ b/catch/unit/deviceLib/hipTestDotFunctions.cc @@ -45,10 +45,10 @@ __global__ static void DotFunctions(bool* result) { TEST_CASE("Unit_hipTestDotFunctions") { bool* result{nullptr}; - hipHostMalloc(&result, 1); + HIP_CHECK(hipHostMalloc(&result, 1)); result[0] = true; hipLaunchKernelGGL(DotFunctions, dim3(1, 1, 1), dim3(1, 1, 1), 0, 0, result); - hipDeviceSynchronize(); + HIP_CHECK(hipDeviceSynchronize()); REQUIRE(result[0] == true); - hipHostFree(result); + HIP_CHECK(hipHostFree(result)); } diff --git a/catch/unit/deviceLib/hipTestHalf.cc b/catch/unit/deviceLib/hipTestHalf.cc index 936625ef56..e3bb216714 100644 --- a/catch/unit/deviceLib/hipTestHalf.cc +++ b/catch/unit/deviceLib/hipTestHalf.cc @@ -19,6 +19,9 @@ THE SOFTWARE. #include #include +#pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wunused-parameter" + __device__ void test_convert() { __half x; float y = static_cast(x); diff --git a/catch/unit/deviceLib/hipTestHost.cc b/catch/unit/deviceLib/hipTestHost.cc index e1e77ff9e3..24c2025f2c 100644 --- a/catch/unit/deviceLib/hipTestHost.cc +++ b/catch/unit/deviceLib/hipTestHost.cc @@ -147,9 +147,6 @@ __device__ bool check_modf() { __device__ bool check_nextafterf() { uint32_t len = 4; float Val[] = {0, -0.5, 0.9, -0.2}; - float iPtr[] = {0, 0, 0, 0}; - float frac[] = {0, -0.5, 0.9, -0.2}; - float Out[] = {1, 1, 1, 1}; for (int i = 0; i < len; i++) { if (nextafterf(Val[i], 1) - Val[i] > 0.0001) { return false; @@ -161,9 +158,6 @@ __device__ bool check_nextafterf() { __device__ bool check_nextafter() { uint32_t len = 4; double Val[] = {0, -0.5, 0.9, -0.2}; - double iPtr[] = {0, 0, 0, 0}; - double frac[] = {0, -0.5, 0.9, -0.2}; - double Out[] = {1, 1, 1, 1}; for (int i = 0; i < len; i++) { if (nextafter(Val[i], 1) - Val[i] > 0.0001) { return false; diff --git a/catch/unit/deviceLib/hipTestNativeHalf.cc b/catch/unit/deviceLib/hipTestNativeHalf.cc index 521b09bca0..44b6d729b6 100644 --- a/catch/unit/deviceLib/hipTestNativeHalf.cc +++ b/catch/unit/deviceLib/hipTestNativeHalf.cc @@ -144,8 +144,6 @@ void __half2Test(bool* result, __half2 a) { // Dot Functions result[0] &= amd_mixed_dot(a, a, 1, 1) && result[0]; - half X = a.x; - half Y = a.y; } TEST_CASE("Unit_hipTestNativeHalf") { diff --git a/catch/unit/graph/hipGraphAddNodeBeginCapture.cc b/catch/unit/graph/hipGraphAddNodeBeginCapture.cc index 80bf52371a..59138742f8 100644 --- a/catch/unit/graph/hipGraphAddNodeBeginCapture.cc +++ b/catch/unit/graph/hipGraphAddNodeBeginCapture.cc @@ -21,6 +21,7 @@ THE SOFTWARE. #include #include +#pragma clang diagnostic ignored "-Wunused-parameter" #define SIZE (1024 * 1024) static size_t Nbytes = SIZE * sizeof(int); diff --git a/catch/unit/kernel/hipDynamicShared.cc b/catch/unit/kernel/hipDynamicShared.cc index 168d979d14..c8593b0939 100644 --- a/catch/unit/kernel/hipDynamicShared.cc +++ b/catch/unit/kernel/hipDynamicShared.cc @@ -21,6 +21,9 @@ THE SOFTWARE. #include #include #include + +#pragma clang diagnostic ignored "-Wunused-parameter" + unsigned threadsPerBlock = 256; template diff --git a/catch/unit/kernel/hipEmptyKernel.cc b/catch/unit/kernel/hipEmptyKernel.cc index 484a77e0a6..9262397416 100644 --- a/catch/unit/kernel/hipEmptyKernel.cc +++ b/catch/unit/kernel/hipEmptyKernel.cc @@ -22,6 +22,8 @@ THE SOFTWARE. #include #include +#pragma clang diagnostic ignored "-Wunused-parameter" + __global__ void Empty(int param) {} /** diff --git a/catch/unit/kernel/hipLanguageExtensions.cc b/catch/unit/kernel/hipLanguageExtensions.cc index 5e601d35cf..446c91a213 100644 --- a/catch/unit/kernel/hipLanguageExtensions.cc +++ b/catch/unit/kernel/hipLanguageExtensions.cc @@ -23,6 +23,9 @@ THE SOFTWARE. #include #include +#pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wuninitialized" + // Simple tests for variable type qualifiers: __device__ int deviceVar; @@ -62,7 +65,6 @@ __global__ void vectorADD(T __restrict__* A_d, T* B_d, T* C_d, size_t N) { int a = __shfl_up(x, 1); #endif float x = 1.0; - float z = sin(x); #ifdef NOT_YET float fastZ = __sin(x); #endif diff --git a/catch/unit/kernel/hipLaunchParm.cc b/catch/unit/kernel/hipLaunchParm.cc index f033829f6e..9ae028cac7 100644 --- a/catch/unit/kernel/hipLaunchParm.cc +++ b/catch/unit/kernel/hipLaunchParm.cc @@ -23,6 +23,11 @@ THE SOFTWARE. #include #include +#pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wunused-parameter" +#pragma clang diagnostic ignored "-Wunused-result" +#pragma clang diagnostic ignored "-Wuninitialized" + // Memory alignment is broken // Update: with latest changes the aligment is working fine, hence enabled #define ENABLE_ALIGNMENT_TEST_SMALL_BAR 1 diff --git a/catch/unit/rtc/CMakeLists.txt b/catch/unit/rtc/CMakeLists.txt index 9937df6c56..2653d15237 100644 --- a/catch/unit/rtc/CMakeLists.txt +++ b/catch/unit/rtc/CMakeLists.txt @@ -26,8 +26,7 @@ add_custom_target(copyRtcHeaders ALL if(UNIX) set(AMD_TEST_SRC ${TEST_SRC} RtcFunctions.cpp - RtcUtility.cpp - hiprtcComplrOptnTesting.cc) + RtcUtility.cpp) endif() if(HIP_PLATFORM MATCHES "nvidia") diff --git a/catch/unit/rtc/RtcFunctions.cpp b/catch/unit/rtc/RtcFunctions.cpp index e73e195c07..1d37356540 100644 --- a/catch/unit/rtc/RtcFunctions.cpp +++ b/catch/unit/rtc/RtcFunctions.cpp @@ -36,6 +36,9 @@ validation. For PASS senario the function returns 1 or 0 otherwise. #include #include "headers/printf_common.h" +#pragma clang diagnostic ignored "-Wunused-parameter" +#pragma clang diagnostic ignored "-Wunused-variable" + bool check_architecture(const char** Combination_CO, int Combination_CO_size, int max_thread_pos, int fast_math_present) { @@ -305,7 +308,6 @@ bool check_denormals_enabled(const char** Combination_CO, for (auto& indx : double_vec_expected) { Expected_Results_int.push_back(static_cast(indx)); } - int pass_count = 0; int test_case, res_inc; for (test_case = 0, res_inc = 0; test_case < Input_Vals_int.size() && res_inc < Expected_Results_int.size(); test_case+=2, res_inc++) { @@ -378,8 +380,8 @@ bool check_denormals_enabled(const char** Combination_CO, hipFunction_t function; HIP_CHECK(hipModuleLoadData(&module, codec.data())); HIP_CHECK(hipModuleGetFunction(&function, module, kername)); - hipError_t status = hipModuleLaunchKernel(function, 1, 1, 1, 1, 1, 1, 0, 0, - nullptr, kernel_parameter); + HIP_CHECK(hipModuleLaunchKernel(function, 1, 1, 1, 1, 1, 1, 0, 0, + nullptr, kernel_parameter)); HIP_CHECK(hipMemcpy(result_h, result_d, sizeof(double), hipMemcpyDeviceToHost)); HIP_CHECK(hipDeviceSynchronize()); @@ -427,7 +429,6 @@ bool check_denormals_disabled(const char** Combination_CO, "Expected_Results_for_no", block_name); const char* kername = kernel_name.c_str(); const char* compiler_option = retrieved_CO.c_str(); - int CO_size = 1; std::vector double_vec_input; for (auto& indx : Input_Vals) { double_vec_input.push_back(indx.get()); @@ -444,7 +445,6 @@ bool check_denormals_disabled(const char** Combination_CO, for (auto& indx : double_vec_expected_for_no) { Expected_Results_for_no_int.push_back(static_cast(indx)); } - int pass_count = 0; int test_case, res_inc; for (test_case = 0, res_inc = 0; test_case < Input_Vals_int.size() && res_inc < Expected_Results_for_no_int.size(); test_case+=2, res_inc++) { @@ -517,8 +517,8 @@ bool check_denormals_disabled(const char** Combination_CO, hipFunction_t function; HIP_CHECK(hipModuleLoadData(&module, codec.data())); HIP_CHECK(hipModuleGetFunction(&function, module, kername)); - hipError_t status = hipModuleLaunchKernel(function, 1, 1, 1, 1, 1, 1, 0, 0, - nullptr, kernel_parameter); + HIP_CHECK(hipModuleLaunchKernel(function, 1, 1, 1, 1, 1, 1, 0, 0, + nullptr, kernel_parameter)); HIP_CHECK(hipMemcpy(result_h, result_d, sizeof(double), hipMemcpyDeviceToHost)); HIP_CHECK(hipDeviceSynchronize()); @@ -566,7 +566,7 @@ bool check_ffp_contract_off(const char** Combination_CO, for (auto& indx : retrieved_CO) { CO_vec.push_back(indx.get()); } - int CO_IRadded_size = 3, a = 0; + int CO_IRadded_size = 3; const char** CO_IRadded = new const char*[3]; std::string hold = CO_vec[0]; CO_IRadded[0] = hold.c_str(); @@ -626,7 +626,7 @@ bool check_ffp_contract_on(const char** Combination_CO, for (auto& indx : retrieved_CO) { CO_vec.push_back(indx.get()); } - int CO_IRadded_size = 3, a = 0; + int CO_IRadded_size = 3; const char** CO_IRadded = new const char*[3]; std::string hold = CO_vec[1]; CO_IRadded[0] = hold.c_str(); @@ -700,7 +700,7 @@ bool check_ffp_contract_fast(const char** Combination_CO, for (auto& indx : retrieved_CO) { CO_vec.push_back(indx.get()); } - int CO_IRadded_size = 3, a = 0; + int CO_IRadded_size = 3; const char** CO_IRadded = new const char*[3]; std::string hold = CO_vec[2]; CO_IRadded[0] = hold.c_str(); @@ -769,7 +769,7 @@ bool check_fast_math_enabled(const char** Combination_CO, } return 0; } - int CO_IRadded_size = 3, a = 0; + int CO_IRadded_size = 3; const char** CO_IRadded = new const char*[3]; CO_IRadded[0] = retrieved_CO.c_str(); CO_IRadded[1] = "-mllvm"; @@ -821,7 +821,7 @@ bool check_fast_math_disabled(const char** Combination_CO, } return 0; } - int CO_IRadded_size = 3, a = 0; + int CO_IRadded_size = 3; const char** CO_IRadded = new const char*[3]; CO_IRadded[0] = retrieved_CO.c_str(); CO_IRadded[1] = "-mllvm"; @@ -873,13 +873,13 @@ bool check_slp_vectorize_enabled(const char** Combination_CO, } std::string kernel_name = get_string_parameters("kernel_name", block_name); const char* kername = kernel_name.c_str(); - int CO_IRadded_size = 3, a = 0; + int CO_IRadded_size = 3; const char** CO_IRadded = new const char*[3]; CO_IRadded[0] = retrieved_CO.c_str(); CO_IRadded[1] = "-mllvm"; CO_IRadded[2] = "-print-after=constmerge"; __half2 *a_d, *x_d, *y_d; - __half2 a_h, x_h, *y_h; + __half2 a_h, x_h; a_h.data.x = 1.5; x_h.data.y = 3.0; CaptureStream capture(stderr); @@ -1035,13 +1035,13 @@ bool check_slp_vectorize_disabled(const char** Combination_CO, } std::string kernel_name = get_string_parameters("kernel_name", block_name); const char* kername = kernel_name.c_str(); - int CO_IRadded_size = 3, a = 0; + int CO_IRadded_size = 3; const char** CO_IRadded = new const char*[3]; CO_IRadded[0] = retrieved_CO.c_str(); CO_IRadded[1] = "-mllvm"; CO_IRadded[2] = "-print-after=constmerge"; __half2 *a_d, *x_d, *y_d; - __half2 a_h, x_h, *y_h; + __half2 a_h, x_h; a_h.data.x = 1.5; x_h.data.y = 3.0; CaptureStream capture(stderr); @@ -1451,7 +1451,6 @@ bool check_header_dir(const char** Combination_CO, var_hdr_lst[i] = Headers_list[i]; hder_lst[i] = var_hdr_lst[i].c_str(); } - int pass_count = 0; for (int senario = 0; senario< Input_Thrd_Vals_int.size(); senario++) { hiprtcProgram prog; HIPRTC_CHECK(hiprtcCreateProgram(&prog, header_dir_string, diff --git a/catch/unit/rtc/RtcUtility.cpp b/catch/unit/rtc/RtcUtility.cpp index 2463a73fd1..e0093ffcaf 100644 --- a/catch/unit/rtc/RtcUtility.cpp +++ b/catch/unit/rtc/RtcUtility.cpp @@ -61,6 +61,8 @@ parameters of the respective block name. #include #include "headers/printf_common.h" +#pragma clang diagnostic ignored "-Wunused-but-set-variable" + std::vector get_combi_string_vec() { picojson::array combi_string = get_array_parameters("Combi_CO", "all_compier_options"); @@ -91,7 +93,6 @@ int split_comb_string(std::string option) { int calling_combination_function(std::vector combi_vec_list) { int combi_size = combi_vec_list.size(); int fast_math_present = -1, undef_present = 0; - int a = 0; int max_thread_position; std::string hold_CO[combi_size]; const char** Combination_CO = new const char*[combi_size]; diff --git a/catch/unit/rtc/headers/printf_common.h b/catch/unit/rtc/headers/printf_common.h index bd17d24f33..b42110bab8 100644 --- a/catch/unit/rtc/headers/printf_common.h +++ b/catch/unit/rtc/headers/printf_common.h @@ -34,6 +34,8 @@ THE SOFTWARE. #include #endif +#pragma clang diagnostic ignored "-Wunused-but-set-variable" + #if defined(_WIN32) class CaptureStream { private: @@ -153,7 +155,8 @@ struct CaptureStream { // Truncate the file up to size if we don't want too long log void Truncate(size_t size) { - struct stat sb = { 0 }; + struct stat sb; + memset(&sb, 0, sizeof(sb)); if (::stat(tempname, &sb) == -1) { std::cout << "failed lstat " << tempname; std::cout << "with error: " << ::strerror(errno) << std::endl; diff --git a/catch/unit/rtc/includepath.cc b/catch/unit/rtc/includepath.cc index e70c0eebb7..a72a8824f0 100644 --- a/catch/unit/rtc/includepath.cc +++ b/catch/unit/rtc/includepath.cc @@ -110,13 +110,13 @@ TEST_CASE("Unit_hiprtc_includepath") { void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, HIP_LAUNCH_PARAM_END}; - hipModuleLaunchKernel(kernel, NUM_BLOCKS, 1, 1, NUM_THREADS, 1, 1, 0, nullptr, nullptr, config); + HIP_CHECK(hipModuleLaunchKernel(kernel, NUM_BLOCKS, 1, 1, NUM_THREADS, 1, 1, 0, nullptr, nullptr, config)); HIP_CHECK(hipMemcpy(hOut.get(), dOut, bufferSize, hipMemcpyDeviceToHost)); - hipFree(dX); - hipFree(dY); - hipFree(dOut); + HIP_CHECK(hipFree(dX)); + HIP_CHECK(hipFree(dY)); + HIP_CHECK(hipFree(dOut)); HIP_CHECK(hipModuleUnload(module)); diff --git a/catch/unit/texture/hipTextureObjectTests.cc b/catch/unit/texture/hipTextureObjectTests.cc index aa19fe2520..1fefec4d14 100644 --- a/catch/unit/texture/hipTextureObjectTests.cc +++ b/catch/unit/texture/hipTextureObjectTests.cc @@ -48,7 +48,7 @@ class TextureObjectTestWrapper { } channel_desc = hipCreateChannelDesc(32, 0, 0, 0, hipChannelFormatKindFloat); - hipMallocArray(&array_member, &channel_desc, width); + HIP_CHECK(hipMallocArray(&array_member, &channel_desc, width)); HIP_CHECK( hipMemcpy2DToArray(array_member, 0, 0, host_data_, size, size, 1, hipMemcpyHostToDevice)); From 7ee1b668fb861dd915f1b220226d7c7afb17a14a Mon Sep 17 00:00:00 2001 From: Satyanvesh Dittakavi <53337087+satyanveshd@users.noreply.github.com> Date: Mon, 21 Aug 2023 20:46:46 +0530 Subject: [PATCH 25/30] Address texture related test issues with -Werror (#405) --- catch/unit/memory/hipArrayCommon.hh | 4 +++- catch/unit/surface/hipSurfaceObj1D.cc | 3 +++ catch/unit/surface/hipSurfaceObj2D.cc | 3 +++ catch/unit/surface/hipSurfaceObj3D.cc | 3 +++ catch/unit/texture/hipBindTex2DPitch.cc | 3 ++- catch/unit/texture/hipBindTexRef1DFetch.cc | 3 ++- catch/unit/texture/hipBindTextureToMipmappedArray.cc | 3 ++- catch/unit/texture/hipNormalizedFloatValueTex.cc | 3 ++- catch/unit/texture/hipSimpleTexture2DLayered.cc | 3 ++- catch/unit/texture/hipSimpleTexture3D.cc | 3 ++- catch/unit/texture/hipTex1DFetchCheckModes.cc | 3 ++- catch/unit/texture/hipTexObjPitch.cc | 3 ++- catch/unit/texture/hipTextureMipmapObj2D.cc | 3 ++- catch/unit/texture/hipTextureObj1DCheckModes.cc | 3 ++- catch/unit/texture/hipTextureObj1DCheckSRGBModes.cc | 3 ++- catch/unit/texture/hipTextureObj1DFetch.cc | 3 ++- catch/unit/texture/hipTextureObj2D.cc | 3 ++- catch/unit/texture/hipTextureObj2DCheckModes.cc | 3 ++- catch/unit/texture/hipTextureObj2DCheckSRGBModes.cc | 3 ++- catch/unit/texture/hipTextureObj3DCheckModes.cc | 3 ++- catch/unit/texture/hipTextureObjFetchVector.cc | 5 ++++- catch/unit/texture/hipTextureRef2D.cc | 3 ++- 22 files changed, 50 insertions(+), 19 deletions(-) diff --git a/catch/unit/memory/hipArrayCommon.hh b/catch/unit/memory/hipArrayCommon.hh index 52ade2ea21..4d41700605 100644 --- a/catch/unit/memory/hipArrayCommon.hh +++ b/catch/unit/memory/hipArrayCommon.hh @@ -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 @@ -22,6 +22,8 @@ THE SOFTWARE. #pragma once +#pragma clang diagnostic ignored "-Wunused-parameter" + #include constexpr size_t BlockSize = 16; diff --git a/catch/unit/surface/hipSurfaceObj1D.cc b/catch/unit/surface/hipSurfaceObj1D.cc index e8a59f30a0..c3a3536ec5 100644 --- a/catch/unit/surface/hipSurfaceObj1D.cc +++ b/catch/unit/surface/hipSurfaceObj1D.cc @@ -19,7 +19,10 @@ THE SOFTWARE. #include #include #include + #pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wunused-parameter" + template __global__ void surf1DKernelR(hipSurfaceObject_t surfaceObject, diff --git a/catch/unit/surface/hipSurfaceObj2D.cc b/catch/unit/surface/hipSurfaceObj2D.cc index 725f949a20..2adbe041a7 100644 --- a/catch/unit/surface/hipSurfaceObj2D.cc +++ b/catch/unit/surface/hipSurfaceObj2D.cc @@ -19,7 +19,10 @@ THE SOFTWARE. #include #include #include + #pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wunused-parameter" + #define LOG_DATA 0 template diff --git a/catch/unit/surface/hipSurfaceObj3D.cc b/catch/unit/surface/hipSurfaceObj3D.cc index cb62de3524..1c2e6c0963 100644 --- a/catch/unit/surface/hipSurfaceObj3D.cc +++ b/catch/unit/surface/hipSurfaceObj3D.cc @@ -19,7 +19,10 @@ THE SOFTWARE. #include #include #include + #pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wunused-parameter" + template __global__ void surf3DKernelR(hipSurfaceObject_t surfaceObject, diff --git a/catch/unit/texture/hipBindTex2DPitch.cc b/catch/unit/texture/hipBindTex2DPitch.cc index 26e073ed83..3d01d2429d 100644 --- a/catch/unit/texture/hipBindTex2DPitch.cc +++ b/catch/unit/texture/hipBindTex2DPitch.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 @@ -17,6 +17,7 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#pragma clang diagnostic ignored "-Wunused-parameter" #include #include diff --git a/catch/unit/texture/hipBindTexRef1DFetch.cc b/catch/unit/texture/hipBindTexRef1DFetch.cc index a223d27711..9de21ecbf7 100644 --- a/catch/unit/texture/hipBindTexRef1DFetch.cc +++ b/catch/unit/texture/hipBindTexRef1DFetch.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 @@ -17,6 +17,7 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#pragma clang diagnostic ignored "-Wunused-parameter" #include #if CUDA_VERSION < CUDA_12000 diff --git a/catch/unit/texture/hipBindTextureToMipmappedArray.cc b/catch/unit/texture/hipBindTextureToMipmappedArray.cc index 670e4f75eb..9eafef9190 100644 --- a/catch/unit/texture/hipBindTextureToMipmappedArray.cc +++ b/catch/unit/texture/hipBindTextureToMipmappedArray.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 @@ -17,6 +17,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#pragma clang diagnostic ignored "-Wunused-parameter" #include /** diff --git a/catch/unit/texture/hipNormalizedFloatValueTex.cc b/catch/unit/texture/hipNormalizedFloatValueTex.cc index 3bc1d8ca7d..2ae5472c71 100644 --- a/catch/unit/texture/hipNormalizedFloatValueTex.cc +++ b/catch/unit/texture/hipNormalizedFloatValueTex.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 @@ -17,6 +17,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#pragma clang diagnostic ignored "-Wunused-parameter" #include diff --git a/catch/unit/texture/hipSimpleTexture2DLayered.cc b/catch/unit/texture/hipSimpleTexture2DLayered.cc index 73d2167d5c..3473aa6d95 100644 --- a/catch/unit/texture/hipSimpleTexture2DLayered.cc +++ b/catch/unit/texture/hipSimpleTexture2DLayered.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 @@ -17,6 +17,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#pragma clang diagnostic ignored "-Wunused-parameter" #include #include diff --git a/catch/unit/texture/hipSimpleTexture3D.cc b/catch/unit/texture/hipSimpleTexture3D.cc index c17d218a53..1b5940d6c9 100644 --- a/catch/unit/texture/hipSimpleTexture3D.cc +++ b/catch/unit/texture/hipSimpleTexture3D.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 @@ -17,6 +17,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#pragma clang diagnostic ignored "-Wunused-parameter" #include #include diff --git a/catch/unit/texture/hipTex1DFetchCheckModes.cc b/catch/unit/texture/hipTex1DFetchCheckModes.cc index 158777e42b..0954e770f5 100644 --- a/catch/unit/texture/hipTex1DFetchCheckModes.cc +++ b/catch/unit/texture/hipTex1DFetchCheckModes.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 @@ -17,6 +17,7 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#pragma clang diagnostic ignored "-Wunused-parameter" #include #define N 16 diff --git a/catch/unit/texture/hipTexObjPitch.cc b/catch/unit/texture/hipTexObjPitch.cc index 24f9c21aeb..bfd5b4c563 100644 --- a/catch/unit/texture/hipTexObjPitch.cc +++ b/catch/unit/texture/hipTexObjPitch.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 @@ -17,6 +17,7 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#pragma clang diagnostic ignored "-Wunused-parameter" #include #include diff --git a/catch/unit/texture/hipTextureMipmapObj2D.cc b/catch/unit/texture/hipTextureMipmapObj2D.cc index 72b6d196a0..35f4557f42 100644 --- a/catch/unit/texture/hipTextureMipmapObj2D.cc +++ b/catch/unit/texture/hipTextureMipmapObj2D.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 @@ -17,6 +17,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#pragma clang diagnostic ignored "-Wunused-parameter" #include /** diff --git a/catch/unit/texture/hipTextureObj1DCheckModes.cc b/catch/unit/texture/hipTextureObj1DCheckModes.cc index a3e8e10f5e..43e0405bc1 100644 --- a/catch/unit/texture/hipTextureObj1DCheckModes.cc +++ b/catch/unit/texture/hipTextureObj1DCheckModes.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 @@ -17,6 +17,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#pragma clang diagnostic ignored "-Wunused-parameter" #include #include #include diff --git a/catch/unit/texture/hipTextureObj1DCheckSRGBModes.cc b/catch/unit/texture/hipTextureObj1DCheckSRGBModes.cc index 848a25bc89..499f51fd2f 100644 --- a/catch/unit/texture/hipTextureObj1DCheckSRGBModes.cc +++ b/catch/unit/texture/hipTextureObj1DCheckSRGBModes.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 @@ -17,6 +17,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#pragma clang diagnostic ignored "-Wunused-parameter" #include #include #include diff --git a/catch/unit/texture/hipTextureObj1DFetch.cc b/catch/unit/texture/hipTextureObj1DFetch.cc index 62c6c2c5c1..c267bec29d 100644 --- a/catch/unit/texture/hipTextureObj1DFetch.cc +++ b/catch/unit/texture/hipTextureObj1DFetch.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 @@ -17,6 +17,7 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#pragma clang diagnostic ignored "-Wunused-parameter" #include #define N 512 diff --git a/catch/unit/texture/hipTextureObj2D.cc b/catch/unit/texture/hipTextureObj2D.cc index ee4e895b32..7592b87a22 100644 --- a/catch/unit/texture/hipTextureObj2D.cc +++ b/catch/unit/texture/hipTextureObj2D.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 @@ -17,6 +17,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#pragma clang diagnostic ignored "-Wunused-parameter" #include /** diff --git a/catch/unit/texture/hipTextureObj2DCheckModes.cc b/catch/unit/texture/hipTextureObj2DCheckModes.cc index 0e95023dc0..47f90ca04a 100644 --- a/catch/unit/texture/hipTextureObj2DCheckModes.cc +++ b/catch/unit/texture/hipTextureObj2DCheckModes.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 @@ -17,6 +17,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#pragma clang diagnostic ignored "-Wunused-parameter" #include #include #include diff --git a/catch/unit/texture/hipTextureObj2DCheckSRGBModes.cc b/catch/unit/texture/hipTextureObj2DCheckSRGBModes.cc index 73df5dd16b..a641c4c057 100644 --- a/catch/unit/texture/hipTextureObj2DCheckSRGBModes.cc +++ b/catch/unit/texture/hipTextureObj2DCheckSRGBModes.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 @@ -17,6 +17,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#pragma clang diagnostic ignored "-Wunused-parameter" #include #include #include diff --git a/catch/unit/texture/hipTextureObj3DCheckModes.cc b/catch/unit/texture/hipTextureObj3DCheckModes.cc index 708caf1201..5746d5ae53 100644 --- a/catch/unit/texture/hipTextureObj3DCheckModes.cc +++ b/catch/unit/texture/hipTextureObj3DCheckModes.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 @@ -17,6 +17,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#pragma clang diagnostic ignored "-Wunused-parameter" #include #include #include diff --git a/catch/unit/texture/hipTextureObjFetchVector.cc b/catch/unit/texture/hipTextureObjFetchVector.cc index 7aa2fc8b37..b12f0e7da0 100644 --- a/catch/unit/texture/hipTextureObjFetchVector.cc +++ b/catch/unit/texture/hipTextureObjFetchVector.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 @@ -21,7 +21,10 @@ THE SOFTWARE. #include #include #include + #pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wunused-parameter" + template __global__ void tex1dKernelFetch(T *val, hipTextureObject_t obj, int N) { #if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT diff --git a/catch/unit/texture/hipTextureRef2D.cc b/catch/unit/texture/hipTextureRef2D.cc index 9ecaab9365..fec47f0a73 100644 --- a/catch/unit/texture/hipTextureRef2D.cc +++ b/catch/unit/texture/hipTextureRef2D.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 @@ -17,6 +17,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#pragma clang diagnostic ignored "-Wunused-parameter" #include From 901a4c227a8194a46d6b1b09f267bf22d6ad8913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mirza=20Halil=C4=8Devi=C4=87?= <109971222+mirza-halilcevic@users.noreply.github.com> Date: Wed, 23 Aug 2023 16:51:16 +0200 Subject: [PATCH 26/30] Revert "EXSWHTEC-275 - Implement tests for atomic CAS operations. (#197)" This reverts commit a8640d8c6285e8b92be110cf80c9b6ee20988dbe. --- catch/unit/atomics/CMakeLists.txt | 42 -- catch/unit/atomics/arithmetic_common.hh | 449 ------------------ catch/unit/atomics/atomicCAS.cc | 172 ------- .../atomics/atomicCAS_negative_kernels.cc | 62 --- .../atomics/atomicCAS_negative_kernels_rtc.hh | 273 ----------- catch/unit/atomics/atomicCAS_system.cc | 185 -------- 6 files changed, 1183 deletions(-) delete mode 100644 catch/unit/atomics/CMakeLists.txt delete mode 100644 catch/unit/atomics/arithmetic_common.hh delete mode 100644 catch/unit/atomics/atomicCAS.cc delete mode 100644 catch/unit/atomics/atomicCAS_negative_kernels.cc delete mode 100644 catch/unit/atomics/atomicCAS_negative_kernels_rtc.hh delete mode 100644 catch/unit/atomics/atomicCAS_system.cc diff --git a/catch/unit/atomics/CMakeLists.txt b/catch/unit/atomics/CMakeLists.txt deleted file mode 100644 index fc30955d5a..0000000000 --- a/catch/unit/atomics/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -# 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. - -set(TEST_SRC - atomicCAS.cc - atomicCAS_system.cc -) - -if(HIP_PLATFORM MATCHES "nvidia") - set_source_files_properties(atomicCAS_system.cc PROPERTIES COMPILE_FLAGS "-rdc=true -gencode arch=compute_60,code=sm_60 -gencode arch=compute_70,code=sm_70 -gencode arch=compute_80,code=sm_80") - hip_add_exe_to_target(NAME AtomicsTest - TEST_SRC ${TEST_SRC} - TEST_TARGET_NAME build_tests - LINKER_LIBS "nvrtc -rdc=true -gencode arch=compute_60,code=sm_60 -gencode arch=compute_70,code=sm_70 -gencode arch=compute_80,code=sm_80") -elseif(HIP_PLATFORM MATCHES "amd") - hip_add_exe_to_target(NAME AtomicsTest - TEST_SRC ${TEST_SRC} - TEST_TARGET_NAME build_tests - LINKER_LIBS hiprtc) -endif() - -add_test(NAME Unit_atomicCAS_Negative_Parameters - COMMAND python3 ${CMAKE_CURRENT_SOURCE_DIR}/../compileAndCaptureOutput.py - ${CMAKE_CURRENT_SOURCE_DIR} ${HIP_PLATFORM} ${HIP_PATH} - atomicCAS_negative_kernels.cc 48) diff --git a/catch/unit/atomics/arithmetic_common.hh b/catch/unit/atomics/arithmetic_common.hh deleted file mode 100644 index 384665b502..0000000000 --- a/catch/unit/atomics/arithmetic_common.hh +++ /dev/null @@ -1,449 +0,0 @@ -/* -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. -*/ - -#pragma once - -#include -#include -#include -#include - -namespace cg = cooperative_groups; - -enum class AtomicOperation { - kAdd = 0, - kAddSystem, - kSub, - kSubSystem, - kInc, - kDec, - kUnsafeAdd, - kSafeAdd, - kCASAdd, - kCASAddSystem -}; - -constexpr auto kIntegerTestValue = 7; -constexpr auto kFloatingPointTestValue = 3.125; -constexpr auto kIncDecWraparoundValue = 1023; - -template -__host__ __device__ TestType GetTestValue() { - if constexpr (operation == AtomicOperation::kInc || operation == AtomicOperation::kDec) { - return kIncDecWraparoundValue; - } - - return std::is_floating_point_v ? kFloatingPointTestValue : kIntegerTestValue; -} - -template __device__ TestType CASAtomicAdd(TestType* address, TestType val) { - TestType old = *address, assumed; - - do { - assumed = old; - old = atomicCAS(address, assumed, val + assumed); - } while (assumed != old); - - return old; -} - -template -__device__ TestType CASAtomicAddSystem(TestType* address, TestType val) { - TestType old = *address, assumed; - - do { - assumed = old; - old = atomicCAS_system(address, assumed, val + assumed); - } while (assumed != old); - - return old; -} - -template -__device__ TestType PerformAtomicOperation(TestType* const mem) { - const auto val = GetTestValue(); - - if constexpr (operation == AtomicOperation::kAdd) { - return atomicAdd(mem, val); - } else if constexpr (operation == AtomicOperation::kAddSystem) { - return atomicAdd_system(mem, val); - } else if constexpr (operation == AtomicOperation::kSub) { - return atomicSub(mem, val); - } else if constexpr (operation == AtomicOperation::kSubSystem) { - return atomicSub_system(mem, val); - } else if constexpr (operation == AtomicOperation::kInc) { - return atomicInc(mem, val); - } else if constexpr (operation == AtomicOperation::kDec) { - return atomicDec(mem, val); - } else if constexpr (operation == AtomicOperation::kUnsafeAdd) { - return unsafeAtomicAdd(mem, val); - } else if constexpr (operation == AtomicOperation::kSafeAdd) { - return safeAtomicAdd(mem, val); - } else if constexpr (operation == AtomicOperation::kCASAdd) { - return CASAtomicAdd(mem, val); - } else if constexpr (operation == AtomicOperation::kCASAddSystem) { - return CASAtomicAddSystem(mem, val); - } -} - -template -__global__ void TestKernel(TestType* const global_mem, TestType* const old_vals) { - __shared__ TestType shared_mem; - - const auto tid = cg::this_grid().thread_rank(); - - TestType* const mem = use_shared_mem ? &shared_mem : global_mem; - - if constexpr (use_shared_mem) { - if (tid == 0) mem[0] = global_mem[0]; - __syncthreads(); - } - - old_vals[tid] = PerformAtomicOperation(mem); - - if constexpr (use_shared_mem) { - __syncthreads(); - if (tid == 0) global_mem[0] = mem[0]; - } -} - -template -__host__ __device__ TestType* PitchedOffset(TestType* const ptr, const unsigned int pitch, - const unsigned int idx) { - const auto byte_ptr = reinterpret_cast(ptr); - return reinterpret_cast(byte_ptr + idx * pitch); -} - -template -__global__ void TestKernel(TestType* const global_mem, TestType* const old_vals, - const unsigned int width, const unsigned pitch) { - extern __shared__ uint8_t shared_mem[]; - - const auto tid = cg::this_grid().thread_rank(); - - TestType* const mem = use_shared_mem ? reinterpret_cast(shared_mem) : global_mem; - - if constexpr (use_shared_mem) { - if (tid < width) { - const auto target = PitchedOffset(mem, pitch, tid); - *target = *PitchedOffset(global_mem, pitch, tid); - }; - __syncthreads(); - } - - old_vals[tid] = - PerformAtomicOperation(PitchedOffset(mem, pitch, tid % width)); - - if constexpr (use_shared_mem) { - __syncthreads(); - if (tid < width) { - const auto target = PitchedOffset(global_mem, pitch, tid); - *target = *PitchedOffset(mem, pitch, tid); - }; - } -} - -struct TestParams { - auto ThreadCount() const { - return blocks.x * blocks.y * blocks.z * threads.x * threads.y * threads.z; - } - - auto HostIterationsPerThread() const { - return std::max(num_devices * kernel_count * ThreadCount() / 20, width); - } - - dim3 blocks; - dim3 threads; - unsigned int num_devices = 1u; - unsigned int kernel_count = 1u; - unsigned int width = 1u; - unsigned int pitch = 0u; - unsigned int host_thread_count = 0u; - LinearAllocs alloc_type; -}; - -template -std::tuple, std::vector> TestKernelHostRef(const TestParams& p) { - const auto val = GetTestValue(); - - const auto total_thread_count = p.num_devices * p.kernel_count * p.ThreadCount() + - p.host_thread_count * p.HostIterationsPerThread(); - - std::vector res_vals(p.width); - std::vector old_vals; - old_vals.reserve(total_thread_count); - - auto perform_op = [&](unsigned id) { - auto& res = res_vals[id % p.width]; - old_vals.push_back(res); - - if constexpr (operation == AtomicOperation::kAdd || operation == AtomicOperation::kAddSystem || - operation == AtomicOperation::kUnsafeAdd || - operation == AtomicOperation::kSafeAdd || operation == AtomicOperation::kCASAdd || - operation == AtomicOperation::kCASAddSystem) { - res = res + val; - } else if constexpr (operation == AtomicOperation::kSub || - operation == AtomicOperation::kSubSystem) { - res = res - val; - } else if constexpr (operation == AtomicOperation::kInc) { - res = (res >= val) ? 0 : res + 1; - } else if constexpr (operation == AtomicOperation::kDec) { - res = ((res == 0) || (res > val)) ? val : res - 1; - } - }; - - for (auto i = 0u; i < p.num_devices; ++i) { - for (auto j = 0u; j < p.kernel_count; ++j) { - for (auto tid = 0u; tid < p.ThreadCount(); ++tid) { - perform_op(tid); - } - } - } - - for (auto i = 0u; i < p.host_thread_count; ++i) { - for (auto j = 0u; j < p.HostIterationsPerThread(); ++j) { - perform_op(j); - } - } - - return {res_vals, old_vals}; -} - -template -void Verify(const TestParams& p, std::vector& res_vals, std::vector& old_vals) { - auto [expected_res_vals, expected_old_vals] = TestKernelHostRef(p); - - for (auto i = 0u; i < res_vals.size(); ++i) { - INFO("Results index: " << i); - REQUIRE(expected_res_vals[i] == res_vals[i]); - } - - std::sort(begin(old_vals), end(old_vals)); - std::sort(begin(expected_old_vals), end(expected_old_vals)); - for (auto i = 0u; i < old_vals.size(); ++i) { - INFO("Old values index: " << i); - REQUIRE(expected_old_vals[i] == old_vals[i]); - } -} - -template -void LaunchKernel(const TestParams& p, hipStream_t stream, TestType* const mem_ptr, - TestType* const old_vals) { - const auto shared_mem_size = use_shared_mem ? p.width * p.pitch : 0u; - if (p.width == 1 && p.pitch == sizeof(TestType)) - TestKernel - <<>>(mem_ptr, old_vals); - else - TestKernel - <<>>(mem_ptr, old_vals, p.width, p.pitch); -} - -template -void HostAtomicOperation(const unsigned int iterations, TestType* mem, TestType* const old_vals, - const unsigned int width, const unsigned pitch, TestType base_val) { - const auto val = GetTestValue(); - - for (auto i = 0u; i < iterations; ++i) { - if constexpr (operation == AtomicOperation::kAddSystem || - operation == AtomicOperation::kCASAddSystem) { - old_vals[i] = __atomic_fetch_add(PitchedOffset(mem, pitch, i % width), val, __ATOMIC_RELAXED); - } else if constexpr (operation == AtomicOperation::kSubSystem) { - old_vals[i] = __atomic_fetch_sub(PitchedOffset(mem, pitch, i % width), val, __ATOMIC_RELAXED); - } - } -} - -template -void PerformHostAtomicOperation(const TestParams& p, TestType* mem, TestType* const old_vals) { - if (p.host_thread_count == 0) { - return; - } - - const auto host_base_val = p.num_devices * p.kernel_count * p.ThreadCount(); - - std::vector threads; - for (auto i = 0u; i < p.host_thread_count; ++i) { - const auto iterations = p.HostIterationsPerThread(); - const auto thread_base_val = host_base_val + i * iterations; - threads.push_back(std::thread(HostAtomicOperation, iterations, mem, - old_vals + thread_base_val, p.width, p.pitch, thread_base_val)); - } - - for (auto& th : threads) { - th.join(); - } -} - -template -void TestCore(const TestParams& p) { - const unsigned int flags = - p.alloc_type == LinearAllocs::mallocAndRegister ? hipHostRegisterMapped : 0u; - - const auto old_vals_alloc_size = p.kernel_count * p.ThreadCount() * sizeof(TestType); - std::vector> old_vals_devs; - std::vector streams; - for (auto i = 0; i < p.num_devices; ++i) { - HIP_CHECK(hipSetDevice(i)); - old_vals_devs.emplace_back(LinearAllocs::hipMalloc, old_vals_alloc_size); - for (auto j = 0; j < p.kernel_count; ++j) { - streams.emplace_back(Streams::created); - } - } - - const auto mem_alloc_size = p.width * p.pitch; - LinearAllocGuard mem_dev(p.alloc_type, mem_alloc_size, flags); - - std::vector old_vals(p.num_devices * p.kernel_count * p.ThreadCount() + - p.host_thread_count * p.HostIterationsPerThread()); - std::vector res_vals(p.width); - - TestType* const mem_ptr = - p.alloc_type == LinearAllocs::hipMalloc ? mem_dev.ptr() : mem_dev.host_ptr(); - - HIP_CHECK(hipMemset(mem_ptr, 0, mem_alloc_size)); - - for (auto i = 0u; i < p.num_devices; ++i) { - for (auto j = 0u; j < p.kernel_count; ++j) { - const auto& stream = streams[i * p.kernel_count + j].stream(); - const auto old_vals = old_vals_devs[i].ptr() + j * p.ThreadCount(); - LaunchKernel(p, stream, mem_dev.ptr(), old_vals); - } - } - - PerformHostAtomicOperation(p, mem_dev.host_ptr(), old_vals.data()); - - for (auto i = 0u; i < p.num_devices; ++i) { - const auto device_offset = i * p.kernel_count * p.ThreadCount(); - HIP_CHECK(hipMemcpy(old_vals.data() + device_offset, old_vals_devs[i].ptr(), - old_vals_alloc_size, hipMemcpyDeviceToHost)); - } - HIP_CHECK(hipMemcpy2D(res_vals.data(), sizeof(TestType), mem_ptr, p.pitch, sizeof(TestType), - p.width, hipMemcpyDeviceToHost)); - - Verify(p, res_vals, old_vals); -} - -inline dim3 GenerateThreadDimensions() { return GENERATE(dim3(16), dim3(1024)); } - -inline dim3 GenerateBlockDimensions() { - int sm_count = 0; - HIP_CHECK(hipDeviceGetAttribute(&sm_count, hipDeviceAttributeMultiprocessorCount, 0)); - return GENERATE_COPY(dim3(sm_count), dim3(sm_count + sm_count / 2)); -} - -template -void SingleDeviceSingleKernelTest(const unsigned int width, const unsigned int pitch) { - TestParams params; - params.num_devices = 1; - params.kernel_count = 1; - params.threads = GenerateThreadDimensions(); - params.width = width; - params.pitch = pitch; - - SECTION("Global memory") { - params.blocks = GenerateBlockDimensions(); - using LA = LinearAllocs; - for (const auto alloc_type : - {LA::hipMalloc, LA::hipHostMalloc, LA::hipMallocManaged, LA::mallocAndRegister}) { - params.alloc_type = alloc_type; - DYNAMIC_SECTION("Allocation type: " << to_string(alloc_type)) { - TestCore(params); - } - } - } - - SECTION("Shared memory") { - params.blocks = dim3(1); - params.alloc_type = LinearAllocs::hipMalloc; - TestCore(params); - } -} - -template -void SingleDeviceMultipleKernelTest(const unsigned int kernel_count, const unsigned int width, - const unsigned int pitch) { - int concurrent_kernels = 0; - HIP_CHECK(hipDeviceGetAttribute(&concurrent_kernels, hipDeviceAttributeConcurrentKernels, 0)); - if (!concurrent_kernels) { - HipTest::HIP_SKIP_TEST("Test requires support for concurrent kernel execution"); - return; - } - - TestParams params; - params.num_devices = 1; - params.kernel_count = kernel_count; - params.blocks = GenerateBlockDimensions(); - params.threads = GenerateThreadDimensions(); - params.width = width; - params.pitch = pitch; - - using LA = LinearAllocs; - for (const auto alloc_type : - {LA::hipMalloc, LA::hipHostMalloc, LA::hipMallocManaged, LA::mallocAndRegister}) { - params.alloc_type = alloc_type; - DYNAMIC_SECTION("Allocation type: " << to_string(alloc_type)) { - TestCore(params); - } - } -} - -template -void MultipleDeviceMultipleKernelAndHostTest(const unsigned int num_devices, - const unsigned int kernel_count, - const unsigned int width, const unsigned int pitch, - const unsigned int host_thread_count = 0u) { - if (num_devices > 1) { - if (HipTest::getDeviceCount() < num_devices) { - std::string msg = std::to_string(num_devices) + " devices are required"; - HipTest::HIP_SKIP_TEST(msg.c_str()); - return; - } - } - - if (kernel_count > 1) { - for (auto i = 0u; i < num_devices; ++i) { - int concurrent_kernels = 0; - HIP_CHECK(hipDeviceGetAttribute(&concurrent_kernels, hipDeviceAttributeConcurrentKernels, i)); - if (!concurrent_kernels) { - HipTest::HIP_SKIP_TEST("Test requires support for concurrent kernel execution"); - return; - } - } - } - - TestParams params; - params.num_devices = num_devices; - params.kernel_count = kernel_count; - params.blocks = GenerateBlockDimensions(); - params.threads = GenerateThreadDimensions(); - params.width = width; - params.pitch = pitch; - params.host_thread_count = host_thread_count; - - using LA = LinearAllocs; - for (const auto alloc_type : {LA::hipHostMalloc, LA::hipMallocManaged, LA::mallocAndRegister}) { - params.alloc_type = alloc_type; - DYNAMIC_SECTION("Allocation type: " << to_string(alloc_type)) { - TestCore(params); - } - } -} \ No newline at end of file diff --git a/catch/unit/atomics/atomicCAS.cc b/catch/unit/atomics/atomicCAS.cc deleted file mode 100644 index 3be684306d..0000000000 --- a/catch/unit/atomics/atomicCAS.cc +++ /dev/null @@ -1,172 +0,0 @@ -/* -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 "arithmetic_common.hh" -#include "atomicCAS_negative_kernels_rtc.hh" - -#include - -/** - * @addtogroup atomicCAS atomicCAS - * @{ - * @ingroup AtomicsTest - */ - -#ifdef HT_NVIDIA -#define TYPES -#else -#define TYPES , float, double -#endif - -/** - * Test Description - * ------------------------ - * - Executes a single kernel on a single device wherein all threads will perform an atomic - * addition, implemented using an atomic CAS operation, on a target memory location. Each thread - * will add the same value to the memory location, storing the return value into a separate output - * array slot corresponding to it. Once complete, the output array and target memory is validated to - * contain all the expected values. Several memory access patterns are tested: - * -# All threads exchange to a single, compile time deducible, memory location - * -# Each thread targets an array containing warp_size elements, using tid % warp_size - * for indexing - * -# Same as the above, but the elements are spread out by L1 cache line size bytes. - * - * - The test is run for: - * - All overloads of atomicCAS - * - hipMalloc, hipMallocManaged, hipHostMalloc and hipHostRegister allocated memory - * - Shared memory - * - Several grid and block dimension combinations (only one block is used for shared memory). - * Test source - * ------------------------ - * - unit/atomics/atomicCAS.cc - * Test requirements - * ------------------------ - * - HIP_VERSION >= 5.2 - */ -TEMPLATE_TEST_CASE("Unit_atomicCAS_Positive", "", int, unsigned int, unsigned long long TYPES) { - int warp_size = 0; - HIP_CHECK(hipDeviceGetAttribute(&warp_size, hipDeviceAttributeWarpSize, 0)); - const auto cache_line_size = 128u; - - for (auto current = 0; current < cmd_options.iterations; ++current) { - DYNAMIC_SECTION("Same address " << current) { - SingleDeviceSingleKernelTest(1, sizeof(TestType)); - } - - DYNAMIC_SECTION("Adjacent addresses " << current) { - SingleDeviceSingleKernelTest(warp_size, sizeof(TestType)); - } - - DYNAMIC_SECTION("Scattered addresses " << current) { - SingleDeviceSingleKernelTest(warp_size, cache_line_size); - } - } -} - -/** - * Test Description - * ------------------------ - * - Executes a kernel two times concurrently on a single device wherein all threads will perform - * an atomic addition, implemented using an atomic CAS operation, on a target memory location. Each - * thread will add the same value to the memory location, storing the return value into a separate - * output array slot corresponding to it. Once complete, the output array and target memory is - * validated to contain all the expected values. Several memory access patterns are tested: - * -# All threads exchange to a single, compile time deducible, memory location - * -# Each thread targets an array containing warp_size elements, using tid % warp_size - * for indexing - * -# Same as the above, but the elements are spread out by L1 cache line size bytes. - * - * - The test is run for: - * - All overloads of atomicCAS - * - hipMalloc, hipMallocManaged, hipHostMalloc and hipHostRegister allocated memory - * - Several grid and block dimension combinations. - * Test source - * ------------------------ - * - unit/atomics/atomicCAS.cc - * Test requirements - * ------------------------ - * - HIP_VERSION >= 5.2 - */ -TEMPLATE_TEST_CASE("Unit_atomicCAS_Positive_Multi_Kernel", "", int, unsigned int, - unsigned long long TYPES) { - int warp_size = 0; - HIP_CHECK(hipDeviceGetAttribute(&warp_size, hipDeviceAttributeWarpSize, 0)); - const auto cache_line_size = 128u; - - for (auto current = 0; current < cmd_options.iterations; ++current) { - DYNAMIC_SECTION("Same address " << current) { - SingleDeviceMultipleKernelTest(2, 1, sizeof(TestType)); - } - - DYNAMIC_SECTION("Adjacent addresses " << current) { - SingleDeviceMultipleKernelTest(2, warp_size, - sizeof(TestType)); - } - - DYNAMIC_SECTION("Scattered addresses " << current) { - SingleDeviceMultipleKernelTest(2, warp_size, - cache_line_size); - } - } -} - -/** - * Test Description - * ------------------------ - * - RTCs kernels that pass combinations of arguments of invalid types for all overloads of - * atomicCAS. - * Test source - * ------------------------ - * - unit/atomics/atomicCAS.cc - * Test requirements - * ------------------------ - * - HIP_VERSION >= 5.2 - */ -TEST_CASE("Unit_atomicCAS_Negative_Parameters_RTC") { - hiprtcProgram program{}; - - const auto program_source = GENERATE(kAtomicCAS_int, kAtomicCAS_uint, kAtomicCAS_ulong, - kAtomicCAS_ulonglong, kAtomicCAS_float, kAtomicCAS_double); - HIPRTC_CHECK( - hiprtcCreateProgram(&program, program_source, "atomicCAS_negative.cc", 0, nullptr, nullptr)); - hiprtcResult result{hiprtcCompileProgram(program, 0, nullptr)}; - - // Get the compile log and count compiler error messages - size_t log_size{}; - HIPRTC_CHECK(hiprtcGetProgramLogSize(program, &log_size)); - std::string log(log_size, ' '); - HIPRTC_CHECK(hiprtcGetProgramLog(program, log.data())); - int error_count{0}; - - int expected_error_count{8}; - std::string error_message{"error:"}; - - size_t n_pos = log.find(error_message, 0); - while (n_pos != std::string::npos) { - ++error_count; - n_pos = log.find(error_message, n_pos + 1); - } - - HIPRTC_CHECK(hiprtcDestroyProgram(&program)); - HIPRTC_CHECK_ERROR(result, HIPRTC_ERROR_COMPILATION); - REQUIRE(error_count == expected_error_count); -} diff --git a/catch/unit/atomics/atomicCAS_negative_kernels.cc b/catch/unit/atomics/atomicCAS_negative_kernels.cc deleted file mode 100644 index b0390bb3fa..0000000000 --- a/catch/unit/atomics/atomicCAS_negative_kernels.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* -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 - -class Dummy { - public: - __device__ Dummy() {} - __device__ ~Dummy() {} -}; - -#define ATOMIC_CAS_NEGATIVE_KERNEL(type_name) \ - __global__ void atomicCAS_v1(type_name* address, type_name* result) { \ - *result = atomicCAS(&address, 12, 13); \ - } \ - __global__ void atomicCAS_v2(type_name* address, type_name* result) { \ - *result = atomicCAS(address, address, 13); \ - } \ - __global__ void atomicCAS_v3(type_name* address, type_name* result) { \ - *result = atomicCAS(address, 12, address); \ - } \ - __global__ void atomicCAS_v4(Dummy* address, type_name* result) { \ - *result = atomicCAS(address, 12, 13); \ - } \ - __global__ void atomicCAS_v5(char* address, type_name* result) { \ - *result = atomicCAS(address, 12, 13); \ - } \ - __global__ void atomicCAS_v6(short* address, type_name* result) { \ - *result = atomicCAS(address, 12, 13); \ - } \ - __global__ void atomicCAS_v7(long* address, type_name* result) { \ - *result = atomicCAS(address, 12, 13); \ - } \ - __global__ void atomicCAS_v8(long long* address, type_name* result) { \ - *result = atomicCAS(address, 12, 13); \ - } - -ATOMIC_CAS_NEGATIVE_KERNEL(int) -ATOMIC_CAS_NEGATIVE_KERNEL(unsigned int) -ATOMIC_CAS_NEGATIVE_KERNEL(unsigned long) -ATOMIC_CAS_NEGATIVE_KERNEL(unsigned long long) -ATOMIC_CAS_NEGATIVE_KERNEL(float) -ATOMIC_CAS_NEGATIVE_KERNEL(double) diff --git a/catch/unit/atomics/atomicCAS_negative_kernels_rtc.hh b/catch/unit/atomics/atomicCAS_negative_kernels_rtc.hh deleted file mode 100644 index 952c4892fb..0000000000 --- a/catch/unit/atomics/atomicCAS_negative_kernels_rtc.hh +++ /dev/null @@ -1,273 +0,0 @@ -/* -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. -*/ - -#pragma once - -/* -Negative kernels used for the atomics negative Test Cases that are using RTC. -*/ - -static constexpr auto kAtomicCAS_int{ - R"( - class Dummy { - public: - __device__ Dummy() {} - __device__ ~Dummy() {} - }; - - __global__ void atomicCAS_int_v1(int* address, int* result) { - *result = atomicCAS(&address, 12, 13); - } - - __global__ void atomicCAS_int_v2(int* address, int* result) { - *result = atomicCAS(address, address, 13); - } - - __global__ void atomicCAS_int_v3(int* address, int* result) { - *result = atomicCAS(address, 12, address); - } - - __global__ void atomicCAS_int_v4(Dummy* address, int* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_int_v5(char* address, int* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_int_v6(short* address, int* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_int_v7(long* address, int* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_int_v8(long long* address, int* result) { - *result = atomicCAS(address, 12, 13); - } - )"}; - -static constexpr auto kAtomicCAS_uint{ - R"( - class Dummy { - public: - __device__ Dummy() {} - __device__ ~Dummy() {} - }; - - __global__ void atomicCAS_uint_v1(unsigned int* address, unsigned int* result) { - *result = atomicCAS(&address, 12, 13); - } - - __global__ void atomicCAS_uint_v2(unsigned int* address, unsigned int* result) { - *result = atomicCAS(address, address, 13); - } - - __global__ void atomicCAS_uint_v3(unsigned int* address, unsigned int* result) { - *result = atomicCAS(address, 12, address); - } - - __global__ void atomicCAS_uint_v4(Dummy* address, unsigned int* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_uint_v5(char* address, unsigned int* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_uint_v6(short* address, unsigned int* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_uint_v7(long* address, unsigned int* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_uint_v8(long long* address, unsigned int* result) { - *result = atomicCAS(address, 12, 13); - } - )"}; - -static constexpr auto kAtomicCAS_ulong{ - R"( - class Dummy { - public: - __device__ Dummy() {} - __device__ ~Dummy() {} - }; - - __global__ void atomicCAS_ulong_v1(unsigned long* address, unsigned long* result) { - *result = atomicCAS(&address, 12, 13); - } - - __global__ void atomicCAS_ulong_v2(unsigned long* address, unsigned long* result) { - *result = atomicCAS(address, address, 13); - } - - __global__ void atomicCAS_ulong_v3(unsigned long* address, unsigned long* result) { - *result = atomicCAS(address, 12, address); - } - - __global__ void atomicCAS_ulong_v4(Dummy* address, unsigned long* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_ulong_v5(char* address, unsigned long* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_ulong_v6(short* address, unsigned long* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_ulong_v7(long* address, unsigned long* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_ulong_v8(long long* address, unsigned long* result) { - *result = atomicCAS(address, 12, 13); - } - )"}; - -static constexpr auto kAtomicCAS_ulonglong{ - R"( - class Dummy { - public: - __device__ Dummy() {} - __device__ ~Dummy() {} - }; - - __global__ void atomicCAS_ulonglong_v1(unsigned long long* address, unsigned long long* result) { - *result = atomicCAS(&address, 12, 13); - } - - __global__ void atomicCAS_ulonglong_v2(unsigned long long* address, unsigned long long* result) { - *result = atomicCAS(address, address, 13); - } - - __global__ void atomicCAS_ulonglong_v3(unsigned long long* address, unsigned long long* result) { - *result = atomicCAS(address, 12, address); - } - - __global__ void atomicCAS_ulonglong_v4(Dummy* address, unsigned long long* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_ulonglong_v5(char* address, unsigned long long* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_ulonglong_v6(short* address, unsigned long long* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_ulonglong_v7(long* address, unsigned long long* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_ulonglong_v8(long long* address, unsigned long long* result) { - *result = atomicCAS(address, 12, 13); - } - )"}; - -static constexpr auto kAtomicCAS_float{ - R"( - class Dummy { - public: - __device__ Dummy() {} - __device__ ~Dummy() {} - }; - - __global__ void atomicCAS_float_v1(float* address, float* result) { - *result = atomicCAS(&address, 12, 13); - } - - __global__ void atomicCAS_float_v2(float* address, float* result) { - *result = atomicCAS(address, address, 13); - } - - __global__ void atomicCAS_float_v3(float* address, float* result) { - *result = atomicCAS(address, 12, address); - } - - __global__ void atomicCAS_float_v4(Dummy* address, float* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_float_v5(char* address, float* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_float_v6(short* address, float* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_float_v7(long* address, float* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_float_v8(long long* address, float* result) { - *result = atomicCAS(address, 12, 13); - } - )"}; - -static constexpr auto kAtomicCAS_double{ - R"( - class Dummy { - public: - __device__ Dummy() {} - __device__ ~Dummy() {} - }; - - __global__ void atomicCAS_double_v1(double* address, double* result) { - *result = atomicCAS(&address, 12, 13); - } - - __global__ void atomicCAS_double_v2(double* address, double* result) { - *result = atomicCAS(address, address, 13); - } - - __global__ void atomicCAS_double_v3(double* address, double* result) { - *result = atomicCAS(address, 12, address); - } - - __global__ void atomicCAS_double_v4(Dummy* address, double* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_double_v5(char* address, double* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_double_v6(short* address, double* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_double_v7(long* address, double* result) { - *result = atomicCAS(address, 12, 13); - } - - __global__ void atomicCAS_double_v8(long long* address, double* result) { - *result = atomicCAS(address, 12, 13); - } - )"}; diff --git a/catch/unit/atomics/atomicCAS_system.cc b/catch/unit/atomics/atomicCAS_system.cc deleted file mode 100644 index 8f2dd8306b..0000000000 --- a/catch/unit/atomics/atomicCAS_system.cc +++ /dev/null @@ -1,185 +0,0 @@ -/* -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 "arithmetic_common.hh" - -#include - -/** - * @addtogroup atomicCAS_system atomicCAS_system - * @{ - * @ingroup AtomicsTest - */ - -#ifdef HT_NVIDIA -#define TYPES -#else -#define TYPES , float, double -#endif - -/** - * Test Description - * ------------------------ - * - Executes a kernel two times concurrently on a two devices wherein all threads will perform - * an atomic addition, implemented using an atomic CAS operation, on a target memory location. Each - * thread will add the same value to the memory location, storing the return value into a separate - * output array slot corresponding to it. Once complete, the output array and target memory is - * validated to contain all the expected values. Several memory access patterns are tested: - * -# All threads exchange to a single, compile time deducible, memory location - * -# Each thread targets an array containing warp_size elements, using tid % warp_size - * for indexing - * -# Same as the above, but the elements are spread out by L1 cache line size bytes. - * - * - The test is run for: - * - All overloads of atomicCAS_system - * - hipMalloc, hipMallocManaged, hipHostMalloc and hipHostRegister allocated memory - * - Several grid and block dimension combinations. - * Test source - * ------------------------ - * - unit/atomics/atomicCAS_system.cc - * Test requirements - * ------------------------ - * - HIP_VERSION >= 5.2 - */ -TEMPLATE_TEST_CASE("Unit_atomicCAS_system_Positive_Peer_GPUs", "", int, unsigned int, - unsigned long long TYPES) { - int warp_size = 0; - HIP_CHECK(hipDeviceGetAttribute(&warp_size, hipDeviceAttributeWarpSize, 0)); - const auto cache_line_size = 128u; - - for (auto current = 0; current < cmd_options.iterations; ++current) { - DYNAMIC_SECTION("Same address " << current) { - MultipleDeviceMultipleKernelAndHostTest( - 2, 2, 1, sizeof(TestType)); - } - - DYNAMIC_SECTION("Adjacent addresses " << current) { - MultipleDeviceMultipleKernelAndHostTest( - 2, 2, warp_size, sizeof(TestType)); - } - - DYNAMIC_SECTION("Scattered addresses " << current) { - MultipleDeviceMultipleKernelAndHostTest( - 2, 2, warp_size, cache_line_size); - } - } -} - -/** - * Test Description - * ------------------------ - * - Executes a kernel on a single device wherein all threads will perform - * an atomic addition, implemented using an atomic CAS operation, on a target memory location. - * Each thread will add the same value to the memory location, storing the return value into a - * separate output array slot corresponding to it. While the kernel is running, the host - * performs atomic additions, in 4 threads, on the same memory location(s). Once complete, the - * output array and target memory is validated to contain all the expected values. Several - * memory access patterns are tested: - * -# All threads exchange to a single, compile time deducible, memory location - * -# Each thread targets an array containing warp_size elements, using tid % warp_size - * for indexing - * -# Same as the above, but the elements are spread out by L1 cache line size bytes. - * - * - The test is run for: - * - All overloads of atomicCAS_system - * - hipMalloc, hipMallocManaged, hipHostMalloc and hipHostRegister allocated memory - * - Several grid and block dimension combinations. - * Test source - * ------------------------ - * - unit/atomics/atomicCAS_system.cc - * Test requirements - * ------------------------ - * - HIP_VERSION >= 5.2 - */ -TEMPLATE_TEST_CASE("Unit_atomicCAS_system_Positive_Host_And_GPU", "", int, unsigned int, - unsigned long long TYPES) { - int warp_size = 0; - HIP_CHECK(hipDeviceGetAttribute(&warp_size, hipDeviceAttributeWarpSize, 0)); - const auto cache_line_size = 128u; - - for (auto current = 0; current < cmd_options.iterations; ++current) { - DYNAMIC_SECTION("Same address " << current) { - MultipleDeviceMultipleKernelAndHostTest( - 1, 1, 1, sizeof(TestType), 4); - } - - DYNAMIC_SECTION("Adjacent addresses " << current) { - MultipleDeviceMultipleKernelAndHostTest( - 1, 1, warp_size, sizeof(TestType), 4); - } - - DYNAMIC_SECTION("Scattered addresses " << current) { - MultipleDeviceMultipleKernelAndHostTest( - 1, 1, warp_size, cache_line_size, 4); - } - } -} - -/** - * Test Description - * ------------------------ - * - Executes a kernel two times on two devices wherein all threads will perform - * an atomic addition, implemented using an atomic CAS operation, on a target memory location. - * Each thread will add the same value to the memory location, storing the return value into a - * separate output array slot corresponding to it. While the kernel is running, the host - * performs atomic additions, in 4 threads, on the same memory location(s). Once complete, the - * output array and target memory is validated to contain all the expected values. Several - * memory access patterns are tested: - * -# All threads exchange to a single, compile time deducible, memory location - * -# Each thread targets an array containing warp_size elements, using tid % warp_size - * for indexing - * -# Same as the above, but the elements are spread out by L1 cache line size bytes. - * - * - The test is run for: - * - All overloads of atomicCAS_system - * - hipMalloc, hipMallocManaged, hipHostMalloc and hipHostRegister allocated memory - * - Several grid and block dimension combinations. - * Test source - * ------------------------ - * - unit/atomics/atomicCAS_system.cc - * Test requirements - * ------------------------ - * - HIP_VERSION >= 5.2 - */ -TEMPLATE_TEST_CASE("Unit_atomicCAS_system_Positive_Host_And_Peer_GPUs", "", int, unsigned int, - unsigned long long TYPES) { - int warp_size = 0; - HIP_CHECK(hipDeviceGetAttribute(&warp_size, hipDeviceAttributeWarpSize, 0)); - const auto cache_line_size = 128u; - - for (auto current = 0; current < cmd_options.iterations; ++current) { - DYNAMIC_SECTION("Same address " << current) { - MultipleDeviceMultipleKernelAndHostTest( - 2, 2, 1, sizeof(TestType), 4); - } - - DYNAMIC_SECTION("Adjacent addresses " << current) { - MultipleDeviceMultipleKernelAndHostTest( - 2, 2, warp_size, sizeof(TestType), 4); - } - - DYNAMIC_SECTION("Scattered addresses " << current) { - MultipleDeviceMultipleKernelAndHostTest( - 2, 2, warp_size, cache_line_size, 4); - } - } -} From 933b84b5bb060bcda3b1dac6ab509b14802f1fce Mon Sep 17 00:00:00 2001 From: arjun-raj-kuppala <60718144+arjun-raj-kuppala@users.noreply.github.com> Date: Thu, 24 Aug 2023 21:44:05 +0530 Subject: [PATCH 27/30] Update build-node labels (#407) --- .jenkins/jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.jenkins/jenkinsfile b/.jenkins/jenkinsfile index 42f99c32e7..0960eda8bb 100644 --- a/.jenkins/jenkinsfile +++ b/.jenkins/jenkinsfile @@ -97,7 +97,7 @@ timestamps { skipDefaultCheckout() // labels belonging to each backend - AMD, NVIDIA - String[] labels = ['hip-amd-vg20-ubu1804', 'hip-nvidia-rtx5000-ubu1804'] + String[] labels = ['hip-amd-mi100-ubu2004', 'hip-nvidia-rtx5000-ubu2004'] buildMap = [:] labels.each { backendLabel -> From 06398a85b92176fccdd3249438093c3c9ee95495 Mon Sep 17 00:00:00 2001 From: Maneesh Gupta Date: Thu, 7 Sep 2023 17:28:49 +0530 Subject: [PATCH 28/30] SWDEV-403773 - catch configuration to auto detect and generate json per arch (#413) Change-Id: Iad8e93157c3acc6fdecf2603fdf6d90416a3c6e4 --- catch/CMakeLists.txt | 85 ++++-- catch/hipTestMain/config/config_amd_linux | 179 +++++++++++++ .../config/config_amd_linux_MI2xx.json | 35 --- .../config/config_amd_linux_common.json | 135 ---------- catch/hipTestMain/config/config_amd_windows | 250 ++++++++++++++++++ .../config/config_amd_windows_MI2xx.json | 122 --------- .../config/config_amd_windows_common.json | 241 ----------------- .../config/config_nvidia_linux.json | 35 +++ .../config/config_nvidia_linux_common.json | 36 --- .../config/config_nvidia_windows.json | 20 ++ .../config/config_nvidia_windows_common.json | 21 -- catch/hipTestMain/hip_test_context.cc | 79 ++++-- catch/include/hip_test_context.hh | 1 + 13 files changed, 608 insertions(+), 631 deletions(-) create mode 100644 catch/hipTestMain/config/config_amd_linux delete mode 100644 catch/hipTestMain/config/config_amd_linux_MI2xx.json delete mode 100644 catch/hipTestMain/config/config_amd_linux_common.json create mode 100644 catch/hipTestMain/config/config_amd_windows delete mode 100644 catch/hipTestMain/config/config_amd_windows_MI2xx.json delete mode 100644 catch/hipTestMain/config/config_amd_windows_common.json create mode 100644 catch/hipTestMain/config/config_nvidia_linux.json delete mode 100644 catch/hipTestMain/config/config_nvidia_linux_common.json create mode 100644 catch/hipTestMain/config/config_nvidia_windows.json delete mode 100644 catch/hipTestMain/config/config_nvidia_windows_common.json diff --git a/catch/CMakeLists.txt b/catch/CMakeLists.txt index 8f7aa92624..7d9b20496c 100644 --- a/catch/CMakeLists.txt +++ b/catch/CMakeLists.txt @@ -41,13 +41,19 @@ if(WIN32) endif() if(NOT DEFINED HIP_PATH) - if(DEFINED ROCM_PATH) - set(HIP_PATH ${ROCM_PATH}) - else() - set(HIP_PATH "/opt/rocm") - endif() + if(DEFINED ROCM_PATH) + set(HIP_PATH ${ROCM_PATH}) + else() + set(HIP_PATH "/opt/rocm") + endif() endif() + +if(NOT DEFINED ROCM_PATH) + set(ROCM_PATH "/opt/rocm") +endif() + message(STATUS "HIP_PATH: ${HIP_PATH}") +message(STATUS "ROCM_PATH: ${ROCM_PATH}") set(CMAKE_CXX_COMPILER "${HIP_PATH}/bin/hipcc${EXT}") set(CMAKE_C_COMPILER "${HIP_PATH}/bin/hipcc${EXT}") @@ -65,6 +71,7 @@ list(GET VERSION_LIST 1 HIP_VERSION_MINOR) list(GET VERSION_LIST 2 HIP_VERSION_PATCH_GITHASH) string(REPLACE "-" ";" VERSION_LIST ${HIP_VERSION_PATCH_GITHASH}) list(GET VERSION_LIST 0 HIP_VERSION_PATCH) +list(GET VERSION_LIST 1 HIP_VERSION_GITHASH) if(DEFINED ENV{ROCM_LIBPATCH_VERSION}) set(HIP_PACKAGING_VERSION_PATCH ${HIP_VERSION_PATCH}.$ENV{ROCM_LIBPATCH_VERSION}) @@ -118,7 +125,13 @@ endif() add_definitions(-DKERNELS_PATH="${CMAKE_CURRENT_SOURCE_DIR}/kernels/") set(CATCH_BUILD_DIR catch_tests) -file(COPY ./hipTestMain/config DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/${CATCH_BUILD_DIR}/hipTestMain) +execute_process(COMMAND ${CMAKE_COMMAND} -E + make_directory ${CMAKE_CURRENT_BINARY_DIR}/${CATCH_BUILD_DIR}/hipTestMain/config) +file(GLOB JSON_FILES "./hipTestMain/config/*.json") +foreach(json IN LISTS JSON_FILES) + file(COPY ${json} + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/${CATCH_BUILD_DIR}/hipTestMain/config/) +endforeach() file(COPY ./external/Catch2/cmake/Catch2/CatchAddTests.cmake DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/${CATCH_BUILD_DIR}/script) file(COPY ./external/Catch2/cmake/Catch2/catch_include.cmake @@ -172,23 +185,22 @@ message(STATUS "CMAKE HIP ARCHITECTURES: ${CMAKE_HIP_ARCHITECTURES}") if(NOT DEFINED OFFLOAD_ARCH_STR AND EXISTS "${ROCM_PATH}/bin/rocm_agent_enumerator" AND HIP_PLATFORM STREQUAL "amd" AND UNIX) - execute_process(COMMAND ${ROCM_PATH}/bin/rocm_agent_enumerator + execute_process(COMMAND "${ROCM_PATH}/bin/rocm_agent_enumerator" OUTPUT_VARIABLE HIP_GPU_ARCH - RESULT_VARIABLE ROCM_AGENT_ENUM_RESULT) + RESULT_VARIABLE ROCM_AGENT_ENUM_RESULT + OUTPUT_STRIP_TRAILING_WHITESPACE) # Trim out gfx000 string(REPLACE "gfx000\n" "" HIP_GPU_ARCH ${HIP_GPU_ARCH}) if (NOT HIP_GPU_ARCH STREQUAL "") - string(LENGTH ${HIP_GPU_ARCH} HIP_GPU_ARCH_LEN) - # If string has more gfx target except gfx000 - if(${HIP_GPU_ARCH_LEN} GREATER_EQUAL 1) - string(REGEX REPLACE "\n" ";" HIP_GPU_ARCH_LIST "${HIP_GPU_ARCH}") - set(OFFLOAD_ARCH_STR "") - foreach(_hip_gpu_arch ${HIP_GPU_ARCH_LIST}) - set(OFFLOAD_ARCH_STR "--offload-arch=${_hip_gpu_arch} ${OFFLOAD_ARCH_STR}") - endforeach() - endif() + string(REGEX REPLACE "\n" ";" HIP_GPU_ARCH_LIST "${HIP_GPU_ARCH}") + list(REMOVE_DUPLICATES HIP_GPU_ARCH_LIST) + list(LENGTH HIP_GPU_ARCH_LIST HIP_GPU_ARCH_LEN) + set(OFFLOAD_ARCH_STR "") + foreach(_hip_gpu_arch ${HIP_GPU_ARCH_LIST}) + set(OFFLOAD_ARCH_STR "--offload-arch=${_hip_gpu_arch} ${OFFLOAD_ARCH_STR}") + endforeach() else() - message(STATUS "ROCm Agent Enumurator found no valid architectures") + message(STATUS "ROCm Agent Enumerator found no valid architectures") endif() elseif(DEFINED OFFLOAD_ARCH_STR) string(REPLACE "--offload-arch=" "" HIP_GPU_ARCH_LIST ${OFFLOAD_ARCH_STR}) @@ -210,7 +222,44 @@ if(git_result EQUAL 0) set(HIP_TESTS_GITHASH ${git_output}) endif() +set(OFFLOAD_ARCH_LIST ${OFFLOAD_ARCH_STR}) +separate_arguments(OFFLOAD_ARCH_LIST) +list(REMOVE_DUPLICATES OFFLOAD_ARCH_LIST) +set(hip_gpu_arch_list "") +foreach(__offload_arch ${OFFLOAD_ARCH_LIST}) + string(REPLACE "--offload-arch=" "" targetid ${__offload_arch}) + string(REPLACE ":" ";" target_id_list ${targetid}) + list(GET target_id_list 0 arch) + string(APPEND hip_gpu_arch_list "${arch};") + list(REMOVE_DUPLICATES hip_gpu_arch_list) +endforeach() +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CATCH_BUILD_DIR}/hipTestMain/config) +set(config_gen_path ${CMAKE_CURRENT_BINARY_DIR}/${CATCH_BUILD_DIR}/hipTestMain/config) +if(WIN32) + set(configToUse "config_amd_windows") + set(config_file ${CMAKE_SOURCE_DIR}/hipTestMain/config/${configToUse}) + set(json_file ${config_gen_path}/${configToUse}.json) + set(CLANG_CPP "${HIP_PATH}/../lc/bin/clang-cpp.exe") + + set(cmd "${CLANG_CPP} -P -DGITHASH=\"${HIP_VERSION_GITHASH}\" ${config_file}>${json_file}") + message(${cmd}) + execute_process(COMMAND cmd.exe /C ${cmd} + RESULT_VARIABLE json_result) + message(STATUS "${configToUse}.json file generation result: ${json_result}") +else() + set(configToUse "config_amd_linux") + foreach(arch ${hip_gpu_arch_list}) + set(config_file ${CMAKE_SOURCE_DIR}/hipTestMain/config/${configToUse}) + set(config_gen_path ${CMAKE_CURRENT_BINARY_DIR}/${CATCH_BUILD_DIR}/hipTestMain/config) + set(json_file ${config_gen_path}/${configToUse}_${arch}.json) + set(cmd "${ROCM_PATH}/llvm/bin/clang-cpp -P -D${arch} -DGITHASH=\\\"${HIP_VERSION_GITHASH}\\\" ${config_file}>${json_file}") + message(${cmd}) + execute_process(COMMAND bash -c ${cmd} + RESULT_VARIABLE json_result) + message(STATUS "${configToUse}_${arch}.json file generation result: ${json_result}") + endforeach() +endif() # prints the catch info to a file string(TIMESTAMP _timestamp UTC) set(_autogen "# Auto-generated by cmake on ${_timestamp} UTC\n") diff --git a/catch/hipTestMain/config/config_amd_linux b/catch/hipTestMain/config/config_amd_linux new file mode 100644 index 0000000000..aded65f0d6 --- /dev/null +++ b/catch/hipTestMain/config/config_amd_linux @@ -0,0 +1,179 @@ +#define COMMON +#if defined gfx90a || defined gfx940 + #define MI2XX +#endif + +{ + "Info": [ + "File generated for commit on below mentioned date and time", + __DATE__, + __TIME__, + GITHASH + ], + "DisabledTests": [ + #if defined COMMON + "Unit_hipStreamPerThread_DeviceReset_1", + "Unit_hipMallocManaged_OverSubscription", + "Unit_hipDeviceGetSharedMemConfig_Positive_Basic", + "Unit_hipDeviceGetSharedMemConfig_Positive_Threaded", + "Unit_hipDeviceGetCacheConfig_Positive_Basic", + "Unit_hipDeviceGetCacheConfig_Positive_Threaded", + "Unit_hipGetDeviceFlags_Positive_Context", + "Unit_hipIpcCloseMemHandle_Negative_Close_In_Originating_Process", + "Unit_hipIpcOpenMemHandle_Negative_Open_In_Creating_Process", + "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", + "Unit_hipGraphExecMemcpyNodeSetParamsFromSymbol_Positive_Basic", + "Unit_hipKernelNameRef_Negative_Parameters", + "Unit_hipMemAdvise_AccessedBy_All_Devices", + "Unit_hipMemAdvise_No_Flag_Interference", + "Unit_hipMemGetAddressRange_Negative", + "NOTE: The following 2 tests are disabled due to defect - EXSWHTEC-238", + "Unit_hipDrvMemcpy3D_Positive_Array", + "Unit_hipDrvMemcpy3DAsync_Positive_Array", + "Unit_hipMemRangeGetAttribute_Positive_AccessedBy_Basic", + "Unit_hipMemRangeGetAttribute_Positive_AccessedBy_Partial_Range", + "Unit_hipMemGetAddressRange_Positive", + "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", + "Unit_hipGraphAddMemsetNode_Positive_Basic - uint16_t", + "Unit_hipGraphAddMemsetNode_Positive_Basic - uint32_t", + "Unit_hipStreamSetCaptureDependencies_Positive_Functional", + "Note: Test disabled due to defect - EXSWHTEC-207", + "Unit_hipIpcGetMemHandle_Positive_Unique_Handles_Separate_Allocations", + "Unit_hipStreamCreateWithFlags_DefaultStreamInteraction", + "Unit_hipStreamWaitEvent_UninitializedStream_Negative", + "Unit_hipMemset3DSync", + "Unit_hipStreamAddCallback_StrmSyncTiming", + "Disabling test tracked SWDEV-394199", + "Unit_hipStreamCreateWithPriority_MulthreadNonblockingflag", + "Disabling test tracked SWDEV-395683", + "Unit_hipStreamPerThread_MultiThread", + "SWDEV-396963", + "Unit_hipMemcpy2DFromArrayAsync_Positive_Synchronization_Behavior", + "Disabling tests tracked with SWDEV-389647..", + "Unit_hipMemcpy2DToArrayAsync_Positive_Synchronization_Behavior", + "Disabling test tracked SWDEV-391555", + "Unit_hipMemcpyPeer_Positive_ZeroSize", + "Unit_hipMemcpyPeerAsync_Positive_ZeroSize", + "Disabling test tracked SWDEV-391718", + "Unit_hipMemRangeGetAttribute_TstCountParam", + "Fails in Stress test SWDEV-398971", + "SWDEV-398975 Seg faults in stress test", + "Unit_hipMemcpyWithStream_MultiThread", + "SWDEV-398977 fails in stress tests", + "Unit_hipMemset2DSync", + "SWDEV-398981 fails in stress test", + "Unit_hipStreamCreateWithPriority_MulthreadDefaultflag", + "SWDEV-402054 fails in external github build", + "Unit_hipEventDestroy_WithWaitingStream", + "=== Below tests fail in stress test on 23/06/23 ===", + "Unit_hipIpcMemAccess_ParameterValidation", + "Unit_hipMemcpy2DFromArrayAsync_Positive_Synchronization_Behavior", + "Unit_hipGraphClone_Test_hipGraphExecMemcpyNodeSetParams", + "Unit_hipGraphClone_Test_hipGraphMemcpyNodeSetParams1D_and_exec", + "Unit_hipStreamValue_Wait64_Blocking_NoMask_And", + "Unit_hipStreamValue_Wait64_Blocking_NoMask_Nor", + "=== Below tests fail in stress test on 30/06/23 ===", + "Unit_hipStreamValue_Wait32_Blocking_NoMask_Nor", + "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", + "=== 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", + "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", + "Unit_hipStreamValue_Wait32_Blocking_Mask_Eq_1", + "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/327 ===", + "Unit_hiprtcGpuRdcComplrOptnTst", + "Unit_hiprtcDisabledSlpVectorizeComplrOptnTst", + "Unit_hiprtcRpassInlineComplrOptnTst", + "Unit_hiprtcCombiComplrOptnTst", + "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/92 ===", + "Unit_hipGetChannelDesc_Negative_Parameters", + "Unit_hipGraphAddChildGraphNode_CmplxNstGrph_UpdKerFun_Clone", + "=== Below tests fail in stress test on 24/07/23 ===", + "Unit_hipStreamCreateWithPriority_ValidateWithEvents", + "Unit_hipEventIpc", + "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", + "Unit_hiprtc_saxpy", + "Unit_hiprtc_warpsize", + "Unit_hiprtc_functional", + "Unit_hipStreamCaptureRtc", + "Unit_hiprtc_cpp17", + "Unit_hiprtc_namehandling", + "Unit_hiprtc_getloweredname", + "Unit_hiprtc_test_hip_bfloat16", + "Unit_RTC_LinkerAPI", + "Unit_hiprtc_half_shuffle", + "Unit_hiprtc_includepath", + #endif + #if defined MI2XX + "Unit_hipStreamPerThread_DeviceReset_1", + "Unit_hipMallocManaged_OverSubscription", + "Unit_hipDeviceGetPCIBusId_Negative_PartialFill", + "Unit_hipInit_Negative", + "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_Grid_Group_Sync_Positive_Basic", + "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", + "Unit_hiprtc_saxpy", + "Unit_hiprtc_warpsize", + "Unit_hiprtc_functional", + "Unit_hipStreamCaptureRtc", + "Unit_hiprtc_cpp17", + "Unit_hiprtc_namehandling", + "Unit_hiprtc_getloweredname", + "Unit_hiprtc_test_hip_bfloat16", + "Unit_RTC_LinkerAPI", + "Unit_hiprtc_half_shuffle", + "Unit_hiprtc_includepath", + #endif + "End of json" + ] +} diff --git a/catch/hipTestMain/config/config_amd_linux_MI2xx.json b/catch/hipTestMain/config/config_amd_linux_MI2xx.json deleted file mode 100644 index 20da9c8d66..0000000000 --- a/catch/hipTestMain/config/config_amd_linux_MI2xx.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "DisabledTests": - [ - "Unit_hipStreamPerThread_DeviceReset_1", - "Unit_hipMallocManaged_OverSubscription", - "Unit_hipDeviceGetPCIBusId_Negative_PartialFill", - "Unit_hipInit_Negative", - "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_Grid_Group_Sync_Positive_Basic", - "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", - "Unit_hiprtc_saxpy", - "Unit_hiprtc_warpsize", - "Unit_hiprtc_functional", - "Unit_hipStreamCaptureRtc", - "Unit_hiprtc_cpp17", - "Unit_hiprtc_namehandling", - "Unit_hiprtc_getloweredname", - "Unit_hiprtc_test_hip_bfloat16", - "Unit_RTC_LinkerAPI", - "Unit_hiprtc_half_shuffle", - "Unit_hiprtc_includepath" - ] - -} diff --git a/catch/hipTestMain/config/config_amd_linux_common.json b/catch/hipTestMain/config/config_amd_linux_common.json deleted file mode 100644 index 7068f83d1e..0000000000 --- a/catch/hipTestMain/config/config_amd_linux_common.json +++ /dev/null @@ -1,135 +0,0 @@ -{ - "DisabledTests": - [ - "Unit_hipStreamPerThread_DeviceReset_1", - "Unit_hipMallocManaged_OverSubscription", - "Unit_hipDeviceGetSharedMemConfig_Positive_Basic", - "Unit_hipDeviceGetSharedMemConfig_Positive_Threaded", - "Unit_hipDeviceGetCacheConfig_Positive_Basic", - "Unit_hipDeviceGetCacheConfig_Positive_Threaded", - "Unit_hipGetDeviceFlags_Positive_Context", - "Unit_hipIpcCloseMemHandle_Negative_Close_In_Originating_Process", - "Unit_hipIpcOpenMemHandle_Negative_Open_In_Creating_Process", - "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", - "Unit_hipGraphExecMemcpyNodeSetParamsFromSymbol_Positive_Basic", - "Unit_hipKernelNameRef_Negative_Parameters", - "Unit_hipMemAdvise_AccessedBy_All_Devices", - "Unit_hipMemAdvise_No_Flag_Interference", - "Unit_hipMemGetAddressRange_Negative", - "NOTE: The following 2 tests are disabled due to defect - EXSWHTEC-238", - "Unit_hipDrvMemcpy3D_Positive_Array", - "Unit_hipDrvMemcpy3DAsync_Positive_Array", - "Unit_hipMemRangeGetAttribute_Positive_AccessedBy_Basic", - "Unit_hipMemRangeGetAttribute_Positive_AccessedBy_Partial_Range", - "Unit_hipMemGetAddressRange_Positive", - "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", - "Unit_hipGraphAddMemsetNode_Positive_Basic - uint16_t", - "Unit_hipGraphAddMemsetNode_Positive_Basic - uint32_t", - "Unit_hipStreamSetCaptureDependencies_Positive_Functional", - "Note: Test disabled due to defect - EXSWHTEC-207", - "Unit_hipIpcGetMemHandle_Positive_Unique_Handles_Separate_Allocations", - "Unit_hipStreamCreateWithFlags_DefaultStreamInteraction", - "Unit_hipStreamWaitEvent_UninitializedStream_Negative", - "Unit_hipMemset3DSync", - "Unit_hipStreamAddCallback_StrmSyncTiming", - "Disabling test tracked SWDEV-394199", - "Unit_hipStreamCreateWithPriority_MulthreadNonblockingflag", - "Disabling test tracked SWDEV-395683", - "Unit_hipStreamPerThread_MultiThread", - "SWDEV-396963", - "Unit_hipMemcpy2DFromArrayAsync_Positive_Synchronization_Behavior", - "Disabling tests tracked with SWDEV-389647..", - "Unit_hipMemcpy2DToArrayAsync_Positive_Synchronization_Behavior", - "Disabling test tracked SWDEV-391555", - "Unit_hipMemcpyPeer_Positive_ZeroSize", - "Unit_hipMemcpyPeerAsync_Positive_ZeroSize", - "Disabling test tracked SWDEV-391718", - "Unit_hipMemRangeGetAttribute_TstCountParam", - "Fails in Stress test SWDEV-398971", - "SWDEV-398975 Seg faults in stress test", - "Unit_hipMemcpyWithStream_MultiThread", - "SWDEV-398977 fails in stress tests", - "Unit_hipMemset2DSync", - "SWDEV-398981 fails in stress test", - "Unit_hipStreamCreateWithPriority_MulthreadDefaultflag", - "SWDEV-402054 fails in external github build", - "Unit_hipEventDestroy_WithWaitingStream", - "=== Below tests fail in stress test on 23/06/23 ===", - "Unit_hipIpcMemAccess_ParameterValidation", - "Unit_hipMemcpy2DFromArrayAsync_Positive_Synchronization_Behavior", - "Unit_hipGraphClone_Test_hipGraphExecMemcpyNodeSetParams", - "Unit_hipGraphClone_Test_hipGraphMemcpyNodeSetParams1D_and_exec", - "Unit_hipStreamValue_Wait64_Blocking_NoMask_And", - "Unit_hipStreamValue_Wait64_Blocking_NoMask_Nor", - "=== Below tests fail in stress test on 30/06/23 ===", - "Unit_hipStreamValue_Wait32_Blocking_NoMask_Nor", - "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", - "=== 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", - "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", - "Unit_hipStreamValue_Wait32_Blocking_Mask_Eq_1", - "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/327 ===", - "Unit_hiprtcGpuRdcComplrOptnTst", - "Unit_hiprtcDisabledSlpVectorizeComplrOptnTst", - "Unit_hiprtcRpassInlineComplrOptnTst", - "Unit_hiprtcCombiComplrOptnTst", - "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/92 ===", - "Unit_hipGetChannelDesc_Negative_Parameters", - "Unit_hipGraphAddChildGraphNode_CmplxNstGrph_UpdKerFun_Clone", - "=== Below tests fail in stress test on 24/07/23 ===", - "Unit_hipStreamCreateWithPriority_ValidateWithEvents", - "Unit_hipEventIpc", - "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", - "Unit_hiprtc_saxpy", - "Unit_hiprtc_warpsize", - "Unit_hiprtc_functional", - "Unit_hipStreamCaptureRtc", - "Unit_hiprtc_cpp17", - "Unit_hiprtc_namehandling", - "Unit_hiprtc_getloweredname", - "Unit_hiprtc_test_hip_bfloat16", - "Unit_RTC_LinkerAPI", - "Unit_hiprtc_half_shuffle", - "Unit_hiprtc_includepath" - ] -} diff --git a/catch/hipTestMain/config/config_amd_windows b/catch/hipTestMain/config/config_amd_windows new file mode 100644 index 0000000000..cb95233c16 --- /dev/null +++ b/catch/hipTestMain/config/config_amd_windows @@ -0,0 +1,250 @@ +#define COMMON +{ + "Info": [ + "File generated for commit on below mentioned date and time", + __DATE__, + __TIME__, + GITHASH + ], + "DisabledTests": [ + #if defined COMMON + "Unit_hipMalloc_CoherentTst", + "Unit_hipTextureMipmapObj2D_Check", + "Unit_hipGraphAddHostNode_ClonedGraphwithHostNode", + "Unit_hipEventIpc", + "Unit_hipMalloc3D_Negative", + "Unit_hipMemPoolApi_BasicAlloc", + "Unit_hipMemPoolApi_BasicTrim", + "Unit_hipMemPoolApi_BasicReuse", + "Unit_hipMemPoolApi_Opportunistic", + "Unit_hipMalloc3D_ValidatePitch", + "Unit_hipMemAllocPitch_ValidatePitch", + "Unit_hipGraphExecMemcpyNodeSetParamsToSymbol_Functional", + "Unit_hipMallocManaged_OverSubscription", + "Unit_hipMallocManaged_CoherentTstWthAdvise", + "Unit_hipMallocManaged_Advanced", + "Unit_hipMemRangeGetAttribute_TstCountParam", + "Unit_hipMemRangeGetAttribute_NegativeTests", + "Unit_hipMemRangeGetAttribute_AccessedBy1", + "Unit_hipMemRangeGetAttribte_3", + "Unit_hipMemRangeGetAttribute_4", + "Unit_hipMemRangeGetAttribute_PrefetchAndGtAttr", + "Unit_hipMemAdvise_TstFlags", + "Unit_hipMemAdvise_PrefrdLoc", + "Unit_hipMemAdvise_ReadMostly", + "Unit_hipMemAdvise_TstFlgOverrideEffect", + "Unit_hipMemAdvise_TstAccessedByFlg", + "Unit_hipMemAdvise_TstAccessedByFlg4", + "Unit_hipMemAdvise_TstMemAdvisePrefrdLoc", + "Unit_hipMemAdvise_TstMemAdviseMultiFlag", + "Unit_hipMemAdvise_ReadMosltyMgpuTst", + "Unit_hipMemAdvise_TstSetUnsetPrfrdLoc", + "Unit_hipMallocManaged_DeviceContextChange - unsigned char", + "Unit_hipMallocManaged_DeviceContextChange - int", + "Unit_hipMallocManaged_DeviceContextChange - float", + "Unit_hipMallocManaged_DeviceContextChange - double", + "Unit_hipStreamCreateWithPriority_ValidateWithEvents", + "Unit_hipStreamPerThread_StrmWaitEvt", + "Unit_hipMemGetInfo_DifferentMallocSmall", + "Unit_hipMemGetInfo_MallocArray - int", + "Unit_hipMemGetInfo_MallocArray - int4", + "Unit_hipMemGetInfo_MallocArray - char", + "Unit_hipMemGetInfo_Malloc3D", + "Unit_hipMemGetInfo_Malloc3DArray - char", + "Unit_hipMemGetInfo_Malloc3DArray - int", + "Unit_hipMemGetInfo_Malloc3DArray - int4", + "Unit_hipMemGetInfo_ParaSmall", + "Unit_hipMemGetInfo_ParaMultiSmall", + "Unit_hipMultiThreadDevice_NearZero", + "Unit_hipStreamPerThread_DeviceReset_1", + "Unit_hipStreamCreateWithPriority_ValidateWithEvents", + "Unit_hipStreamPerThread_StrmWaitEvt", + "Unit_hipGraphMemcpyNodeSetParamsToSymbol_Functional", + "Unit_hipStreamWaitEvent_DifferentStreams", + "Unit_hipStreamQuery_WithFinishedWork", + "Unit_hipDeviceGetCacheConfig_Positive_Basic", + "Unit_hipDeviceGetCacheConfig_Positive_Basic", + "Unit_hipDeviceGetCacheConfig_Positive_Threaded", + "Unit_hipStreamValue_Wait32_Blocking_Mask_Gte", + "Unit_hipStreamValue_Wait32_Blocking_Mask_Eq_1", + "Unit_hipStreamValue_Wait32_Blocking_Mask_Eq_2", + "Unit_hipStreamValue_Wait32_Blocking_Mask_And", + "Unit_hipStreamValue_Wait32_Blocking_NoMask_Eq", + "Unit_hipStreamValue_Wait32_Blocking_NoMask_Gte", + "Unit_hipStreamValue_Wait32_Blocking_NoMask_And", + "Unit_hipStreamValue_Wait32_Blocking_NoMask_Nor", + "Unit_hipStreamValue_Wait64_Blocking_Mask_Gte_1", + "Unit_hipStreamValue_Wait64_Blocking_Mask_Gte_2", + "Unit_hipStreamValue_Wait64_Blocking_Mask_Eq_1", + "Unit_hipStreamValue_Wait64_Blocking_Mask_Eq_2", + "Unit_hipStreamValue_Wait64_Blocking_Mask_And", + "Unit_hipStreamValue_Wait64_Blocking_NoMask_Gte", + "Unit_hipStreamValue_Wait64_Blocking_NoMask_Eq", + "Unit_hipStreamValue_Wait64_Blocking_NoMask_And", + "Unit_hipStreamValue_Wait64_Blocking_NoMask_Nor", + "Unit_hipGetDeviceFlags_Positive_Context", + "Unit_hipIpcCloseMemHandle_Negative_Close_In_Originating_Process", + "Unit_hipIpcOpenMemHandle_Negative_Open_In_Creating_Process", + "Unit_hipDeviceGetPCIBusId_Negative_PartialFill", + "Unit_hipDeviceGetSharedMemConfig_Positive_Basic", + "Unit_hipDeviceGetSharedMemConfig_Positive_Threaded", + "Unit_hipDeviceReset_Positive_Basic", + "Unit_hipDeviceReset_Positive_Threaded", + "Unit_hipInit_Negative", + "Unit_hipGraphMemcpyNodeSetParams_Functional", + "Unit_hipGraphNodeGetDependentNodes_Functional", + "Unit_hipGraphNodeGetDependencies_Functional", + "Unit_hipGraphExecChildGraphNodeSetParams_ChildTopology", + "Unit_hipGraphAddEventRecordNode_MultipleRun", + "Unit_hipGraphAddEventRecordNode_Functional_ElapsedTime", + "Unit_hipStreamBeginCapture_captureComplexGraph", + "Note: needs to be enabled when streamPerThread issues are fixed", + "Unit_hipStreamSynchronize_NullStreamAndStreamPerThread", + "Note: intermittent Seg fault failure ", + "Unit_hipGraphAddEventRecordNode_Functional_WithoutFlags", + "Unit_hipGraphAddChildGraphNode_MultGraphsAsSingleGraph", + "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", + "Unit_hipEventCreateWithFlags_DisableSystemFence_HstVisMem", + "Unit_hipEventCreateWithFlags_DefaultFlg_HstVisMem", + "Unit_hipEventCreateWithFlags_DisableSystemFence_NonCohHstMem", + "Unit_hipEventCreateWithFlags_DefaultFlg_NonCohHstMem", + "Unit_hipEventCreateWithFlags_DisableSystemFence_CohHstMem", + "Unit_hipEventCreateWithFlags_DefaultFlg_CohHstMem", + "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", + "Unit_hipGraphMemcpyNodeSetParamsFromSymbol_Positive_Basic", + "Unit_hipGraphExecMemcpyNodeSetParamsFromSymbol_Positive_Basic", + "Unit_hipKernelNameRef_Negative_Parameters", + "Unit_hipKernelNameRef_Positive_Basic", + "Unit_hipMemAdvise_AccessedBy_All_Devices", + "Unit_hipMemAdvise_No_Flag_Interference", + "Unit_hipGraphAddEventRecordNode_Functional_WithoutFlags", + "Unit_hipGraphDestroyNode_Complx_ChkNumOfNodesNDep", + "Unit_hipGraphDestroyNode_Complx_ChkNumOfNodesNDep_ClonedGrph", + "Unit_hipGraphDestroyNode_Complx_ChkNumOfNodesNDep_ChldNode", + "Unit_hipMemGetAddressRange_Negative", + "NOTE: The following 2 tests are disabled due to defect - EXSWHTEC-238", + "Unit_hipDrvMemcpy3D_Positive_Array", + "Unit_hipDrvMemcpy3DAsync_Positive_Array", + "Unit_hipMemGetAddressRange_Positive", + "Note: devicelib hangs and failures", + "Unit_deviceAllocation_Malloc_PerThread_PrimitiveDataType", + "Unit_deviceAllocation_New_PerThread_PrimitiveDataType", + "Unit_deviceAllocation_Malloc_PerThread_StructDataType", + "Unit_deviceAllocation_New_PerThread_StructDataType", + "Unit_deviceAllocation_Malloc_AcrossKernels", + "Unit_deviceAllocation_New_AcrossKernels", + "Unit_deviceAllocation_Malloc_SingleCodeObj", + "Unit_deviceAllocation_New_SingleCodeObj", + "Unit_deviceAllocation_Malloc_PerThread_Graph", + "Unit_deviceAllocation_New_PerThread_Graph", + "Unit_deviceAllocation_Malloc_DeviceFunc", + "Unit_deviceAllocation_VirtualFunction", + "Unit_deviceAllocation_Malloc_MulKernels_MulThreads", + "Unit_deviceAllocation_New_MulKernels_MulThreads", + "Unit_deviceAllocation_Malloc_MulCodeObj", + "Unit_deviceAllocation_New_MulCodeObj", + "Unit_deviceAllocation_New_DeviceFunc", + "Unit_hipGraphAddEventRecordNode_MultipleRun", + "Unit_hipDeviceGetPCIBusId_Negative_PartialFill", + "Unit_hipStreamValue_Wait64_Blocking_NoMask_Nor", + "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", + "Unit_hipGraphAddMemsetNode_Positive_Basic - uint32_t", + "Unit_hipGraphMemsetNodeSetParams_Positive_Basic - uint16_t", + "Unit_hipGraphMemsetNodeSetParams_Positive_Basic - uint32_t", + "Note: Test disabled due to defect - EXSWHTEC-207", + "Unit_hipGraphExecMemsetNodeSetParams_Negative_Updating_Non1D_Node", + "Unit_hipGraphExecMemsetNodeSetParams_Positive_Basic - uint8_t", + "Unit_hipGraphExecMemsetNodeSetParams_Positive_Basic - uint16_t", + "Unit_hipGraphExecMemsetNodeSetParams_Positive_Basic - uint32_t", + "Unit_hipGraphMemsetNodeSetParams_Positive_Basic - uint8_t", + "Unit_hipStreamWaitEvent_UninitializedStream_Negative", + "Unit_hipDeviceGetUuid_Positive", + "Disabling test tracked SWDEV-394199", + "Unit_hipStreamCreateWithPriority_MulthreadNonblockingflag", + "SWDEV-396618 hipEventElapsedTime returns sucess", + "Unit_hipEventElapsedTime_NotReady_Negative", + "SWDEV-396617 ExecMemcpyNodeSetParamsFromSymbol fails in direction", + "Unit_hipGraphExecMemcpyNodeSetParamsFromSymbol_Negative_Parameters", + "SWDEV-396616 hipMemMap returns invalid error", + "Unit_hipMemVmm_Basic", + "SWDEV-396615 mGPUs not considered correctly", + "Unit_hipManagedKeyword_MultiGpu", + "Disabling test tracked SWDEV-391555", + "Unit_hipMemcpyPeer_Positive_ZeroSize", + "Unit_hipMemcpyPeerAsync_Positive_ZeroSize", + "Disabling test tracked SWDEV-391718", + "Unit_hipMemRangeGetAttribute_TstCountParam", + "SWDEV-400049 tdr intermittently", + "Unit_hipMemsetDSync – init16_t", + "Unit_hipStreamAddCallback_StrmSyncTiming", + "SWDEV-402082 - PAL Backend fails to reserve address on GPU except first one", + "Unit_hipGraphInstantiateWithFlags_FlagAutoFreeOnLaunch_check", + "SWDEV-398981 fails in stress test", + "Unit_hipStreamCreateWithPriority_MulthreadDefaultflag", + "Disabling below tests temporarily due to change in API behavior", + "Unit_hipMemPrefetchAsync_NonPageSz", + "Unit_hipStreamCreateWithFlags_DefaultStreamInteraction", + "SWDEV-402054 fails in external github build", + "Unit_hipEventDestroy_WithWaitingStream", + "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", + "=== 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", + "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", + "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/92 ===", + "Unit_hipGetChannelDesc_Negative_Parameters", + "Unit_hipTextureMipmapRef2D_Positive_Check", + "Unit_hipTextureMipmapRef2D_Negative_Parameters", + "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", + "Unit_hiprtc_saxpy", + "Unit_hiprtc_warpsize", + "Unit_hiprtc_functional", + "Unit_hipStreamCaptureRtc", + "Unit_hiprtc_cpp17", + "Unit_hiprtc_namehandling", + "Unit_hiprtc_getloweredname", + "Unit_hiprtc_test_hip_bfloat16", + "Unit_RTC_LinkerAPI", + "Unit_hiprtc_half_shuffle", + "Unit_hiprtc_includepath", + #endif + "End of json" + ] +} \ No newline at end of file diff --git a/catch/hipTestMain/config/config_amd_windows_MI2xx.json b/catch/hipTestMain/config/config_amd_windows_MI2xx.json deleted file mode 100644 index 8bb1400846..0000000000 --- a/catch/hipTestMain/config/config_amd_windows_MI2xx.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "DisabledTests": - [ - "Unit_hipMalloc_CoherentTst", - "Unit_printf_flags", - "Unit_printf_specifier", - "Unit_hipTextureMipmapObj2D_Check", - "Unit_hipGraphAddHostNode_ClonedGraphwithHostNode", - "Unit_hipEventIpc", - "Unit_hipMalloc3D_Negative", - "Unit_hipPointerGetAttribute_MappedMem", - "Unit_hipStreamValue_Write", - "Unit_hipMemPoolApi_Basic", - "Unit_hipMemPoolApi_BasicAlloc", - "Unit_hipMemPoolApi_BasicTrim", - "Unit_hipMemPoolApi_BasicReuse", - "Unit_hipMemPoolApi_Opportunistic", - "Unit_hipMemPoolApi_Default", - "Unit_hipDeviceGetUuid", - "Unit_hipGraphMemcpyNodeSetParams_Functional", - "Unit_hipMalloc3D_ValidatePitch", - "Unit_hipArrayCreate_happy", - "Unit_hipHostRegister_Negative - int", - "Unit_hipHostRegister_Negative - float", - "Unit_hipHostRegister_Negative - double", - "Unit_hipMemAllocPitch_ValidatePitch", - "Unit_hipArrayCreate_happy - int", - "Unit_hipArrayCreate_happy - int4", - "Unit_hipArrayCreate_happy - short2", - "Unit_hipArrayCreate_happy - char", - "Unit_hipArrayCreate_happy - char4", - "Unit_hipArrayCreate_happy - float", - "Unit_hipArrayCreate_happy - float2", - "Unit_hipArrayCreate_happy - float4", - "Unit_hipMemVmm_Basic", - "Unit_hipGraphExecMemcpyNodeSetParamsToSymbol_Functional", - "Unit_hipMallocManaged_MultiChunkMultiDevice", - "Unit_hipMallocManaged_TwoPointers - int", - "Unit_hipMallocManaged_TwoPointers - float", - "Unit_hipMallocManaged_TwoPointers - double", - "Unit_hipMallocManaged_DeviceContextChange - unsigned char", - "Unit_hipMallocManaged_DeviceContextChange - int", - "Unit_hipMallocManaged_DeviceContextChange - float", - "Unit_hipMallocManaged_DeviceContextChange - double", - "Unit_hipGraphNodeGetDependentNodes_Functional", - "Unit_hipGraphNodeGetDependentNodes_ParamValidation", - "Unit_hipGraphNodeGetDependencies_Functional", - "Unit_hipGraphNodeGetDependencies_ParamValidation", - "Unit_hipMemGetInfo_DifferentMallocSmall", - "Unit_hipMemGetInfo_MallocArray - int", - "Unit_hipMemGetInfo_MallocArray - int4", - "Unit_hipMemGetInfo_MallocArray - char", - "Unit_hipMemGetInfo_Malloc3D", - "Unit_hipMemGetInfo_Malloc3DArray - char", - "Unit_hipMemGetInfo_Malloc3DArray - int", - "Unit_hipMemGetInfo_Malloc3DArray - int4", - "Unit_hipMemGetInfo_ParaSmall", - "Unit_hipMemGetInfo_ParaMultiSmall", - "Unit_hipFreeMultiTDev - char", - "Unit_hipFreeMultiTDev - int", - "Unit_hipFreeMultiTDev - float2", - "Unit_hipFreeMultiTDev - float4", - "Unit_hipFreeMultiTHost - char", - "Unit_hipFreeMultiTHost - int", - "Unit_hipFreeMultiTHost - float2", - "Unit_hipFreeMultiTHost - float4", - "Unit_hipFreeMultiTArray - char", - "Unit_hipFreeMultiTArray - int", - "Unit_hipFreeMultiTArray - float2", - "Unit_hipFreeMultiTArray - float4", - "Unit_hipStreamSynchronize_FinishWork", - "Unit_hipStreamSynchronize_NullStreamAndStreamPerThread", - "Unit_hipMultiThreadDevice_NearZero", - "Unit_hipStreamPerThread_DeviceReset_1", - "Unit_hipStreamValue_Wait32_Blocking_Mask_Gte", - "Unit_hipStreamValue_Wait32_Blocking_Mask_Eq_1", - "Unit_hipStreamValue_Wait32_Blocking_Mask_Eq_2", - "Unit_hipStreamValue_Wait32_Blocking_Mask_And", - "Unit_hipStreamValue_Wait32_Blocking_NoMask_Eq", - "Unit_hipStreamValue_Wait32_Blocking_NoMask_Gte", - "Unit_hipStreamValue_Wait32_Blocking_NoMask_And", - "Unit_hipStreamValue_Wait32_Blocking_NoMask_Nor", - "Unit_hipStreamValue_Wait64_Blocking_Mask_Gte_1", - "Unit_hipStreamValue_Wait64_Blocking_Mask_Gte_2", - "Unit_hipStreamValue_Wait64_Blocking_Mask_Eq_1", - "Unit_hipStreamValue_Wait64_Blocking_Mask_Eq_2", - "Unit_hipStreamValue_Wait64_Blocking_Mask_And", - "Unit_hipStreamValue_Wait64_Blocking_NoMask_Gte", - "Unit_hipStreamValue_Wait64_Blocking_NoMask_Eq", - "Unit_hipStreamValue_Wait64_Blocking_NoMask_And", - "Unit_hipStreamValue_Wait64_Blocking_NoMask_Nor", - "Unit_hipDeviceGetPCIBusId_Negative_PartialFill", - "Unit_hipInit_Negative", - "Unit_hipGraphAddEventRecordNode_Functional_ElapsedTime", - "Unit_hipStreamBeginCapture_captureComplexGraph", - "Unit_hipGraphAddChildGraphNode_MultGraphsAsSingleGraph", - "Unit_hipMemGetAddressRange_Negative", - "Unit_hipStreamValue_Wait64_Blocking_NoMask_Nor", - "Unit_hipLaunchHostFunc_Graph", - "Unit_hipLaunchHostFunc_KernelHost", - "Unit_hipEventCreateWithFlags_DisableSystemFence_HstVisMem", - "Unit_hipEventCreateWithFlags_DefaultFlg_HstVisMem", - "Unit_hipEventCreateWithFlags_DisableSystemFence_NonCohHstMem", - "Unit_hipEventCreateWithFlags_DefaultFlg_NonCohHstMem", - "Unit_hipEventCreateWithFlags_DisableSystemFence_CohHstMem", - "Unit_hipEventCreateWithFlags_DefaultFlg_CohHstMem", - "Unit_hipStreamCreateWithPriority_MulthreadNonblockingflag", - "Unit_hipDeviceGetUuid_Positive", - "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", - "Unit_hiprtc_saxpy", - "Unit_hiprtc_warpsize", - "Unit_hiprtc_functional", - "Unit_hipStreamCaptureRtc", - "Unit_hiprtc_cpp17", - "Unit_hiprtc_namehandling", - "Unit_hiprtc_getloweredname", - "Unit_hiprtc_test_hip_bfloat16", - "Unit_RTC_LinkerAPI", - "Unit_hiprtc_half_shuffle", - "Unit_hiprtc_includepath" - ] -} diff --git a/catch/hipTestMain/config/config_amd_windows_common.json b/catch/hipTestMain/config/config_amd_windows_common.json deleted file mode 100644 index be73937091..0000000000 --- a/catch/hipTestMain/config/config_amd_windows_common.json +++ /dev/null @@ -1,241 +0,0 @@ -{ - "DisabledTests": - [ - "Unit_hipMalloc_CoherentTst", - "Unit_hipTextureMipmapObj2D_Check", - "Unit_hipGraphAddHostNode_ClonedGraphwithHostNode", - "Unit_hipEventIpc", - "Unit_hipMalloc3D_Negative", - "Unit_hipMemPoolApi_BasicAlloc", - "Unit_hipMemPoolApi_BasicTrim", - "Unit_hipMemPoolApi_BasicReuse", - "Unit_hipMemPoolApi_Opportunistic", - "Unit_hipMalloc3D_ValidatePitch", - "Unit_hipMemAllocPitch_ValidatePitch", - "Unit_hipGraphExecMemcpyNodeSetParamsToSymbol_Functional", - "Unit_hipMallocManaged_OverSubscription", - "Unit_hipMallocManaged_CoherentTstWthAdvise", - "Unit_hipMallocManaged_Advanced", - "Unit_hipMemRangeGetAttribute_TstCountParam", - "Unit_hipMemRangeGetAttribute_NegativeTests", - "Unit_hipMemRangeGetAttribute_AccessedBy1", - "Unit_hipMemRangeGetAttribte_3", - "Unit_hipMemRangeGetAttribute_4", - "Unit_hipMemRangeGetAttribute_PrefetchAndGtAttr", - "Unit_hipMemAdvise_TstFlags", - "Unit_hipMemAdvise_PrefrdLoc", - "Unit_hipMemAdvise_ReadMostly", - "Unit_hipMemAdvise_TstFlgOverrideEffect", - "Unit_hipMemAdvise_TstAccessedByFlg", - "Unit_hipMemAdvise_TstAccessedByFlg4", - "Unit_hipMemAdvise_TstMemAdvisePrefrdLoc", - "Unit_hipMemAdvise_TstMemAdviseMultiFlag", - "Unit_hipMemAdvise_ReadMosltyMgpuTst", - "Unit_hipMemAdvise_TstSetUnsetPrfrdLoc", - "Unit_hipMallocManaged_DeviceContextChange - unsigned char", - "Unit_hipMallocManaged_DeviceContextChange - int", - "Unit_hipMallocManaged_DeviceContextChange - float", - "Unit_hipMallocManaged_DeviceContextChange - double", - "Unit_hipStreamCreateWithPriority_ValidateWithEvents", - "Unit_hipStreamPerThread_StrmWaitEvt", - "Unit_hipMemGetInfo_DifferentMallocSmall", - "Unit_hipMemGetInfo_MallocArray - int", - "Unit_hipMemGetInfo_MallocArray - int4", - "Unit_hipMemGetInfo_MallocArray - char", - "Unit_hipMemGetInfo_Malloc3D", - "Unit_hipMemGetInfo_Malloc3DArray - char", - "Unit_hipMemGetInfo_Malloc3DArray - int", - "Unit_hipMemGetInfo_Malloc3DArray - int4", - "Unit_hipMemGetInfo_ParaSmall", - "Unit_hipMemGetInfo_ParaMultiSmall", - "Unit_hipMultiThreadDevice_NearZero", - "Unit_hipStreamPerThread_DeviceReset_1", - "Unit_hipStreamCreateWithPriority_ValidateWithEvents", - "Unit_hipStreamPerThread_StrmWaitEvt", - "Unit_hipGraphMemcpyNodeSetParamsToSymbol_Functional", - "Unit_hipStreamWaitEvent_DifferentStreams", - "Unit_hipStreamQuery_WithFinishedWork", - "Unit_hipDeviceGetCacheConfig_Positive_Basic", - "Unit_hipDeviceGetCacheConfig_Positive_Basic", - "Unit_hipDeviceGetCacheConfig_Positive_Threaded", - "Unit_hipStreamValue_Wait32_Blocking_Mask_Gte", - "Unit_hipStreamValue_Wait32_Blocking_Mask_Eq_1", - "Unit_hipStreamValue_Wait32_Blocking_Mask_Eq_2", - "Unit_hipStreamValue_Wait32_Blocking_Mask_And", - "Unit_hipStreamValue_Wait32_Blocking_NoMask_Eq", - "Unit_hipStreamValue_Wait32_Blocking_NoMask_Gte", - "Unit_hipStreamValue_Wait32_Blocking_NoMask_And", - "Unit_hipStreamValue_Wait32_Blocking_NoMask_Nor", - "Unit_hipStreamValue_Wait64_Blocking_Mask_Gte_1", - "Unit_hipStreamValue_Wait64_Blocking_Mask_Gte_2", - "Unit_hipStreamValue_Wait64_Blocking_Mask_Eq_1", - "Unit_hipStreamValue_Wait64_Blocking_Mask_Eq_2", - "Unit_hipStreamValue_Wait64_Blocking_Mask_And", - "Unit_hipStreamValue_Wait64_Blocking_NoMask_Gte", - "Unit_hipStreamValue_Wait64_Blocking_NoMask_Eq", - "Unit_hipStreamValue_Wait64_Blocking_NoMask_And", - "Unit_hipStreamValue_Wait64_Blocking_NoMask_Nor", - "Unit_hipGetDeviceFlags_Positive_Context", - "Unit_hipIpcCloseMemHandle_Negative_Close_In_Originating_Process", - "Unit_hipIpcOpenMemHandle_Negative_Open_In_Creating_Process", - "Unit_hipDeviceGetPCIBusId_Negative_PartialFill", - "Unit_hipDeviceGetSharedMemConfig_Positive_Basic", - "Unit_hipDeviceGetSharedMemConfig_Positive_Threaded", - "Unit_hipDeviceReset_Positive_Basic", - "Unit_hipDeviceReset_Positive_Threaded", - "Unit_hipInit_Negative", - "Unit_hipGraphMemcpyNodeSetParams_Functional", - "Unit_hipGraphNodeGetDependentNodes_Functional", - "Unit_hipGraphNodeGetDependencies_Functional", - "Unit_hipGraphExecChildGraphNodeSetParams_ChildTopology", - "Unit_hipGraphAddEventRecordNode_MultipleRun", - "Unit_hipGraphAddEventRecordNode_Functional_ElapsedTime", - "Unit_hipStreamBeginCapture_captureComplexGraph", - "Note: needs to be enabled when streamPerThread issues are fixed", - "Unit_hipStreamSynchronize_NullStreamAndStreamPerThread", - "Note: intermittent Seg fault failure ", - "Unit_hipGraphAddEventRecordNode_Functional_WithoutFlags", - "Unit_hipGraphAddChildGraphNode_MultGraphsAsSingleGraph", - "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", - "Unit_hipEventCreateWithFlags_DisableSystemFence_HstVisMem", - "Unit_hipEventCreateWithFlags_DefaultFlg_HstVisMem", - "Unit_hipEventCreateWithFlags_DisableSystemFence_NonCohHstMem", - "Unit_hipEventCreateWithFlags_DefaultFlg_NonCohHstMem", - "Unit_hipEventCreateWithFlags_DisableSystemFence_CohHstMem", - "Unit_hipEventCreateWithFlags_DefaultFlg_CohHstMem", - "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", - "Unit_hipGraphMemcpyNodeSetParamsFromSymbol_Positive_Basic", - "Unit_hipGraphExecMemcpyNodeSetParamsFromSymbol_Positive_Basic", - "Unit_hipKernelNameRef_Negative_Parameters", - "Unit_hipKernelNameRef_Positive_Basic", - "Unit_hipMemAdvise_AccessedBy_All_Devices", - "Unit_hipMemAdvise_No_Flag_Interference", - "Unit_hipGraphAddEventRecordNode_Functional_WithoutFlags", - "Unit_hipGraphDestroyNode_Complx_ChkNumOfNodesNDep", - "Unit_hipGraphDestroyNode_Complx_ChkNumOfNodesNDep_ClonedGrph", - "Unit_hipGraphDestroyNode_Complx_ChkNumOfNodesNDep_ChldNode", - "Unit_hipMemGetAddressRange_Negative", - "NOTE: The following 2 tests are disabled due to defect - EXSWHTEC-238", - "Unit_hipDrvMemcpy3D_Positive_Array", - "Unit_hipDrvMemcpy3DAsync_Positive_Array", - "Unit_hipMemGetAddressRange_Positive", - "Note: devicelib hangs and failures", - "Unit_deviceAllocation_Malloc_PerThread_PrimitiveDataType", - "Unit_deviceAllocation_New_PerThread_PrimitiveDataType", - "Unit_deviceAllocation_Malloc_PerThread_StructDataType", - "Unit_deviceAllocation_New_PerThread_StructDataType", - "Unit_deviceAllocation_Malloc_AcrossKernels", - "Unit_deviceAllocation_New_AcrossKernels", - "Unit_deviceAllocation_Malloc_SingleCodeObj", - "Unit_deviceAllocation_New_SingleCodeObj", - "Unit_deviceAllocation_Malloc_PerThread_Graph", - "Unit_deviceAllocation_New_PerThread_Graph", - "Unit_deviceAllocation_Malloc_DeviceFunc", - "Unit_deviceAllocation_VirtualFunction", - "Unit_deviceAllocation_Malloc_MulKernels_MulThreads", - "Unit_deviceAllocation_New_MulKernels_MulThreads", - "Unit_deviceAllocation_Malloc_MulCodeObj", - "Unit_deviceAllocation_New_MulCodeObj", - "Unit_deviceAllocation_New_DeviceFunc", - "Unit_hipGraphAddEventRecordNode_MultipleRun", - "Unit_hipDeviceGetPCIBusId_Negative_PartialFill", - "Unit_hipStreamValue_Wait64_Blocking_NoMask_Nor", - "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", - "Unit_hipGraphAddMemsetNode_Positive_Basic - uint32_t", - "Unit_hipGraphMemsetNodeSetParams_Positive_Basic - uint16_t", - "Unit_hipGraphMemsetNodeSetParams_Positive_Basic - uint32_t", - "Note: Test disabled due to defect - EXSWHTEC-207", - "Unit_hipGraphExecMemsetNodeSetParams_Negative_Updating_Non1D_Node", - "Unit_hipGraphExecMemsetNodeSetParams_Positive_Basic - uint8_t", - "Unit_hipGraphExecMemsetNodeSetParams_Positive_Basic - uint16_t", - "Unit_hipGraphExecMemsetNodeSetParams_Positive_Basic - uint32_t", - "Unit_hipGraphMemsetNodeSetParams_Positive_Basic - uint8_t", - "Unit_hipStreamWaitEvent_UninitializedStream_Negative", - "Unit_hipDeviceGetUuid_Positive", - "Disabling test tracked SWDEV-394199", - "Unit_hipStreamCreateWithPriority_MulthreadNonblockingflag", - "SWDEV-396618 hipEventElapsedTime returns sucess", - "Unit_hipEventElapsedTime_NotReady_Negative", - "SWDEV-396617 ExecMemcpyNodeSetParamsFromSymbol fails in direction", - "Unit_hipGraphExecMemcpyNodeSetParamsFromSymbol_Negative_Parameters", - "SWDEV-396616 hipMemMap returns invalid error", - "Unit_hipMemVmm_Basic", - "SWDEV-396615 mGPUs not considered correctly", - "Unit_hipManagedKeyword_MultiGpu", - "Disabling test tracked SWDEV-391555", - "Unit_hipMemcpyPeer_Positive_ZeroSize", - "Unit_hipMemcpyPeerAsync_Positive_ZeroSize", - "Disabling test tracked SWDEV-391718", - "Unit_hipMemRangeGetAttribute_TstCountParam", - "SWDEV-400049 tdr intermittently", - "Unit_hipMemsetDSync – init16_t", - "Unit_hipStreamAddCallback_StrmSyncTiming", - "SWDEV-402082 - PAL Backend fails to reserve address on GPU except first one", - "Unit_hipGraphInstantiateWithFlags_FlagAutoFreeOnLaunch_check", - "SWDEV-398981 fails in stress test", - "Unit_hipStreamCreateWithPriority_MulthreadDefaultflag", - "Disabling below tests temporarily due to change in API behavior", - "Unit_hipMemPrefetchAsync_NonPageSz", - "Unit_hipStreamCreateWithFlags_DefaultStreamInteraction", - "SWDEV-402054 fails in external github build", - "Unit_hipEventDestroy_WithWaitingStream", - "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", - "=== 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", - "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", - "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/92 ===", - "Unit_hipGetChannelDesc_Negative_Parameters", - "Unit_hipTextureMipmapRef2D_Positive_Check", - "Unit_hipTextureMipmapRef2D_Negative_Parameters", - "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", - "Unit_hiprtc_saxpy", - "Unit_hiprtc_warpsize", - "Unit_hiprtc_functional", - "Unit_hipStreamCaptureRtc", - "Unit_hiprtc_cpp17", - "Unit_hiprtc_namehandling", - "Unit_hiprtc_getloweredname", - "Unit_hiprtc_test_hip_bfloat16", - "Unit_RTC_LinkerAPI", - "Unit_hiprtc_half_shuffle", - "Unit_hiprtc_includepath" - ] -} diff --git a/catch/hipTestMain/config/config_nvidia_linux.json b/catch/hipTestMain/config/config_nvidia_linux.json new file mode 100644 index 0000000000..b0c78ee1cf --- /dev/null +++ b/catch/hipTestMain/config/config_nvidia_linux.json @@ -0,0 +1,35 @@ +{ + "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", + "=== 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", + "=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/38 ===", + "Unit_hipFreeAsync_negative", + "=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/222 ===", + "Unit_hipStreamCreate_Performance", + "Unit_hipStreamCreate_WithPriorityPerformance_Nonblocking_high", + "Unit_hipStreamCreate_WithPriorityPerformance_Default_low", + "Unit_hipStreamCreate_WithPriorityPerformance_Nonblocking_low", + "=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/92 ===", + "Unit_hipGetTexObjectResourceDesc_positive", + "Unit_hipGetTexObjectResourceDesc_Negative_Parameters", + "Unit_hipGetTexObjectTextureDesc_positive", + "Unit_hipGetTexObjectTextureDesc_Negative_Parameters", + "Unit_hipTexObjectDestroy_positive" + ] +} diff --git a/catch/hipTestMain/config/config_nvidia_linux_common.json b/catch/hipTestMain/config/config_nvidia_linux_common.json deleted file mode 100644 index 07b62e9329..0000000000 --- a/catch/hipTestMain/config/config_nvidia_linux_common.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "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", - "=== 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", - "=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/38 ===", - "Unit_hipFreeAsync_negative", - "=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/222 ===", - "Unit_hipStreamCreate_Performance", - "Unit_hipStreamCreate_WithPriorityPerformance_Nonblocking_high", - "Unit_hipStreamCreate_WithPriorityPerformance_Default_low", - "Unit_hipStreamCreate_WithPriorityPerformance_Nonblocking_low", - "=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/92 ===", - "Unit_hipGetTexObjectResourceDesc_positive", - "Unit_hipGetTexObjectResourceDesc_Negative_Parameters", - "Unit_hipGetTexObjectTextureDesc_positive", - "Unit_hipGetTexObjectTextureDesc_Negative_Parameters", - "Unit_hipTexObjectDestroy_positive" - ] -} diff --git a/catch/hipTestMain/config/config_nvidia_windows.json b/catch/hipTestMain/config/config_nvidia_windows.json new file mode 100644 index 0000000000..5f35a92780 --- /dev/null +++ b/catch/hipTestMain/config/config_nvidia_windows.json @@ -0,0 +1,20 @@ +{ + "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/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/catch/hipTestMain/config/config_nvidia_windows_common.json b/catch/hipTestMain/config/config_nvidia_windows_common.json deleted file mode 100644 index 771113cc69..0000000000 --- a/catch/hipTestMain/config/config_nvidia_windows_common.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "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/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/catch/hipTestMain/hip_test_context.cc b/catch/hipTestMain/hip_test_context.cc index f30a747d59..deb51e37bb 100644 --- a/catch/hipTestMain/hip_test_context.cc +++ b/catch/hipTestMain/hip_test_context.cc @@ -35,31 +35,61 @@ std::string TestContext::substringFound(std::vector list, std::stri return match; } - -std::string TestContext::getMatchingConfigFile(std::string config_dir) { - std::string configFileToUse; - for (auto& p : fs::recursive_directory_iterator(config_dir)) { - fs::path filename = p.path(); - std::string cur_arch = "TODO"; - std::string arch = substringFound(amd_arch_list_, filename.filename().string()); - std::string platform = substringFound(platform_list_, filename.filename().string()); - std::string os = substringFound(os_list_, filename.filename().string()); - std::string common_arch = "common"; - std::vector default_arch_vec {common_arch}; - std::string common = substringFound(default_arch_vec, filename.filename().string()); - // if arch found then use that exit from loop - if (arch == cur_arch) { - configFileToUse = filename.string(); - break; - // match the platform/os and continue to look - } else if ((platform == config_.platform) && (os == config_.os || os == "all") && - common == common_arch) { // ensures only common file is returned - configFileToUse = filename.string(); +std::string TestContext::getCurrentArch() { +#if HT_LINUX + const char* cmd = "/opt/rocm/bin/rocm_agent_enumerator | sort -u | xargs | sed -e 's/ /;/g'"; + std::array buffer; + std::string result; + std::unique_ptr pipe(popen(cmd, "r"), pclose); + if (!pipe) { + printf("popen() failed!"); + return ""; + } + while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { + std::string res = buffer.data(); + result = res; + } + result.erase(std::remove(result.begin(), result.end(), '\n'), result.end()); + size_t pos = result.find("gfx000"); + if (pos != std::string::npos) { + result.erase(pos, 7); + } + std::stringstream arch_list(result); + std::string arch1 = "", arch2 = ""; + if (!arch_list.eof()) { + getline(arch_list, arch1, ';'); + } + while (!arch_list.eof()) { + getline(arch_list, arch2, ';'); + int result = strcmp(arch1.c_str(), arch2.c_str()); + if (result != 0) { + LogPrintf("%s", + "[ERROR] Cannot run tests on Hetrogenous Architecture. Please set " + "HIP_VISIBLE_DEVICES with devices of same arch"); + abort(); } } - return configFileToUse; + return arch1; +#else + return ""; +#endif } +std::string TestContext::getMatchingConfigFile(std::string config_dir) { + std::string configFileToUse = ""; + if (isLinux() && isAmd()) { + std::string cur_arch = getCurrentArch(); + configFileToUse = config_dir + "/config_" + getConfig().platform + "_" + getConfig().os + "_" + + cur_arch + ".json"; + } else { + configFileToUse = + config_dir + "/config_" + getConfig().platform + "_" + getConfig().os + ".json"; + } + if (fs::exists(configFileToUse)) { + return configFileToUse; + } + return ""; +} std::string& TestContext::getCommonJsonFile() { fs::path config_dir = exe_path; @@ -102,15 +132,18 @@ void TestContext::getConfigFiles() { std::string env_config = TestContext::getEnvVar("HIP_CATCH_EXCLUDE_FILE"); LogPrintf("Env Config file: %s", - (!env_config.empty()) ? env_config.c_str() : "Not found, using common config"); + (!env_config.empty()) ? env_config.c_str() : "Not found"); // HIP_CATCH_EXCLUDE_FILE is set for custom file path if (!env_config.empty()) { if(fs::exists(env_config)) { config_.json_files.push_back(env_config); } } else { + std::string jsonFile = getCommonJsonFile(); // get common json file - config_.json_files.push_back(getCommonJsonFile()); + if (jsonFile != "") { + config_.json_files.push_back(getCommonJsonFile()); + } } for (const auto& fl : config_.json_files) { diff --git a/catch/include/hip_test_context.hh b/catch/include/hip_test_context.hh index f2e5b95757..34be4becb0 100644 --- a/catch/include/hip_test_context.hh +++ b/catch/include/hip_test_context.hh @@ -100,6 +100,7 @@ class TestContext { void parseOptions(int, char**); bool parseJsonFiles(); std::string getMatchingConfigFile(std::string config_dir); + std::string getCurrentArch(); const Config& getConfig() const { return config_; } From 400c4a1bfe86daa770c2288832ac64e5445a0fe2 Mon Sep 17 00:00:00 2001 From: Rakesh Roy <137397847+rakesroy@users.noreply.github.com> Date: Fri, 8 Sep 2023 14:01:44 +0530 Subject: [PATCH 29/30] Disable failed tests in PSDB stress test on 29th Aug 2023 (#415) - Unit_hipHostRegister_Memcpy - int/float/double failures are fixed in latest mainline (SWDEV-393727). - Remaining testcases were random failures seen only during stress test. Could be due to driver/hardware issue. --- catch/hipTestMain/config/config_amd_linux | 36 +++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/catch/hipTestMain/config/config_amd_linux b/catch/hipTestMain/config/config_amd_linux index aded65f0d6..6c353b8921 100644 --- a/catch/hipTestMain/config/config_amd_linux +++ b/catch/hipTestMain/config/config_amd_linux @@ -1,4 +1,13 @@ #define COMMON + +#if defined gfx906 + #define VEGA20 +#endif + +#if defined gfx908 + #define MI100 +#endif + #if defined gfx90a || defined gfx940 #define MI2XX #endif @@ -143,6 +152,15 @@ "Unit_hiprtc_half_shuffle", "Unit_hiprtc_includepath", #endif + #if defined VEGA20 + "=== SWDEV-419112 Below tests fail in stress test on 29/08/23 ===", + "Unit_deviceAllocation_Malloc_ComplexDataType", + "Unit_hipStreamCreate_WithPriorityPerformance_Default_low", + #endif + #if defined MI100 + "=== Below test soft hang in stress test on 29/08/23 ===", + "Unit_hipMultiThreadStreams2", + #endif #if defined MI2XX "Unit_hipStreamPerThread_DeviceReset_1", "Unit_hipMallocManaged_OverSubscription", @@ -160,6 +178,7 @@ "Unit_hipSignalExternalSemaphoresAsync_Vulkan_Negative_Parameters", "Unit_hipImportExternalSemaphore_Vulkan_Negative_Parameters", "Unit_hipDestroyExternalSemaphore_Vulkan_Negative_Parameters", + "SWDEV-415692 Soft hang in stress test on 29/08/23", "Unit_Grid_Group_Sync_Positive_Basic", "=== Below hiprtc tests are disabled temporarily, will be renabled once patches for SWDEV-395996 are merged ===", "Unit_hiprtc_saxpy", @@ -173,6 +192,23 @@ "Unit_RTC_LinkerAPI", "Unit_hiprtc_half_shuffle", "Unit_hiprtc_includepath", + "=== Below tests fail in stress test on 29/08/23 ===", + "Unit_hipMemcpy2DToArray_multiDevicePinnedMemPeerGpu", + "Unit_hipMemcpy2DToArray_multiDeviceDeviceContextChange", + "Unit_hipMemcpy2DToArrayAsync_multiDeviceDeviceContextChange", + "Unit_hipMemcpy3D_multiDevice-OnPeerDevice", + "Unit_hipMemcpy3DAsync_multiDevice-D2D", + "Unit_hipMemcpy3DAsync_multiDevice-DiffStream", + "Unit_hipMemcpy2DFromArray_multiDevicePinnedMemPeerGpu", + "Unit_hipMemcpy2DFromArray_multiDeviceContextChange", + "Unit_hipMemcpy2DFromArrayAsync_multiDeviceContextChange", + "Unit_hipMemcpyAtoH_multiDevice-PeerDeviceContext - char", + "Unit_hipMemcpyAtoH_multiDevice-PeerDeviceContext - int", + "Unit_hipMemcpyAtoH_multiDevice-PeerDeviceContext - float", + "Unit_hipMemcpyHtoA_multiDevice-PeerDeviceContext - char", + "Unit_hipMemcpyHtoA_multiDevice-PeerDeviceContext - int", + "Unit_hipMemcpyHtoA_multiDevice-PeerDeviceContext - float", + "Unit_hipDrvMemcpy3D_Host2ArrayDeviceContextChange", #endif "End of json" ] From 8a8b157ca7e34fd59c6e2f950a6427900e4b1727 Mon Sep 17 00:00:00 2001 From: Rakesh Roy <137397847+rakesroy@users.noreply.github.com> Date: Thu, 14 Sep 2023 12:40:03 +0530 Subject: [PATCH 30/30] Disable tests which fail/hang in PSDB stress test on 13th Sep 2023 (#416) --- catch/hipTestMain/config/config_amd_linux | 30 +++++++++++++++++++++ catch/hipTestMain/config/config_amd_windows | 5 ++++ 2 files changed, 35 insertions(+) diff --git a/catch/hipTestMain/config/config_amd_linux b/catch/hipTestMain/config/config_amd_linux index 6c353b8921..d1cd4c975c 100644 --- a/catch/hipTestMain/config/config_amd_linux +++ b/catch/hipTestMain/config/config_amd_linux @@ -12,6 +12,10 @@ #define MI2XX #endif +#if defined gfx1100 || defined gfx1102 + #define NAVI3X +#endif + { "Info": [ "File generated for commit on below mentioned date and time", @@ -156,6 +160,9 @@ "=== SWDEV-419112 Below tests fail in stress test on 29/08/23 ===", "Unit_deviceAllocation_Malloc_ComplexDataType", "Unit_hipStreamCreate_WithPriorityPerformance_Default_low", + "=== Below tests tests fail in stress test on 13/09/23 ===", + "Unit_hipStreamCreate_Performance", + "Unit_hipStreamCreate_WithPriorityPerformance_Default_high", #endif #if defined MI100 "=== Below test soft hang in stress test on 29/08/23 ===", @@ -209,6 +216,29 @@ "Unit_hipMemcpyHtoA_multiDevice-PeerDeviceContext - int", "Unit_hipMemcpyHtoA_multiDevice-PeerDeviceContext - float", "Unit_hipDrvMemcpy3D_Host2ArrayDeviceContextChange", + "=== Below tests tests fail in stress test on 13/09/23 ===", + "Unit_hipGraphInstantiateWithFlags_DependencyGraphDeviceCtxtChg", + "Unit_hipGraphUpload_Functional_multidevice_test", + "Unit_hipMemcpyParam2D_multiDevice-D2D - char", + "Unit_hipMemcpyParam2D_multiDevice-D2D - float", + "Unit_hipMemcpyParam2D_multiDevice-D2D - int", + "Unit_hipMemcpyParam2D_multiDevice-D2D - double", + "Unit_hipMemcpyParam2D_multiDevice-D2D - long double", + "Unit_hipMemcpyParam2DAsync_multiDevice-StreamOnDiffDevice - char", + #endif + #if defined NAVI3X + "=== Below tests soft hang in stress test on 13/09/23 ===", + "Unit_hipMemsetFunctional_ZeroValue_hipMemsetD16", + "Unit_hipIpcMemAccess_Semaphores", + "Unit_hipStreamCreate_WithFlagsPerformance_Nonblocking", + "Unit_hipStreamCreate_WithFlagsPerformance_Default", + "Unit_hipStreamAttachMemAsync_Negative_Parameters", + "hipStreamPerThread_CoopLaunch", + "hipCGMultiGridGroupType", + "Grid_Group_Getters_Positive_Basic", + "Grid_Group_Getters_Via_Non_Member_Functions_Positive_Basic", + "Grid_Group_Sync_Positive_Basic", + "dynamic_loading_device_kernels_from_library", #endif "End of json" ] diff --git a/catch/hipTestMain/config/config_amd_windows b/catch/hipTestMain/config/config_amd_windows index cb95233c16..8ada36e3d9 100644 --- a/catch/hipTestMain/config/config_amd_windows +++ b/catch/hipTestMain/config/config_amd_windows @@ -244,6 +244,11 @@ "Unit_RTC_LinkerAPI", "Unit_hiprtc_half_shuffle", "Unit_hiprtc_includepath", + "=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/416 ===", + "Unit_hipStreamCreate_Performance", + "Unit_hipStreamCreate_WithFlagsPerformance_Nonblocking", + "Unit_hipStreamCreate_WithFlagsPerformance_Default", + "Unit_hipStreamCreate_WithPriorityPerformance_Nonblocking_low", #endif "End of json" ]