/* * Copyright (c) Advanced Micro Devices, Inc., or its affiliates. * * SPDX-License-Identifier: MIT */ #include "atomicMin_negative_kernels_rtc.hh" #include "min_max_common.hh" #include /** * @addtogroup atomicMin atomicMin * @{ * @ingroup AtomicsTest * `atomicMin(TestType* address, TestType* val)` - * calculates minimum between address and val, returns old value. */ // Helper function to run atomicMin tests for same address (single kernel) template static void runAtomicMinSameAddressTest() { for (auto current = 0; current < cmd_options.iterations; ++current) { DYNAMIC_SECTION("Same address " << current) { MinMax::SingleDeviceSingleKernelTest( 1, sizeof(TestType)); } } } // Helper function to run atomicMin tests for adjacent addresses (single kernel) template static void runAtomicMinAdjacentAddressesTest() { int warp_size = 0; HIP_CHECK(hipDeviceGetAttribute(&warp_size, hipDeviceAttributeWarpSize, 0)); for (auto current = 0; current < cmd_options.iterations; ++current) { DYNAMIC_SECTION("Adjacent address " << current) { MinMax::SingleDeviceSingleKernelTest( warp_size, sizeof(TestType)); } } } // Helper function to run atomicMin tests for scattered addresses (single kernel) template static void runAtomicMinScatteredAddressesTest() { 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("Scattered address " << current) { MinMax::SingleDeviceSingleKernelTest( warp_size, cache_line_size); } } } // Helper function to run atomicMin tests for same address (multiple kernels) template static void runAtomicMinMultiKernelSameAddressTest() { for (auto current = 0; current < cmd_options.iterations; ++current) { DYNAMIC_SECTION("Same address " << current) { MinMax::SingleDeviceMultipleKernelTest( 2, 1, sizeof(TestType)); } } } // Helper function to run atomicMin tests for adjacent addresses (multiple kernels) template static void runAtomicMinMultiKernelAdjacentAddressesTest() { int warp_size = 0; HIP_CHECK(hipDeviceGetAttribute(&warp_size, hipDeviceAttributeWarpSize, 0)); for (auto current = 0; current < cmd_options.iterations; ++current) { DYNAMIC_SECTION("Adjacent address " << current) { MinMax::SingleDeviceMultipleKernelTest( 2, warp_size, sizeof(TestType)); } } } // Helper function to run atomicMin tests for scattered addresses (multiple kernels) template static void runAtomicMinMultiKernelScatteredAddressesTest() { 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("Scattered address " << current) { MinMax::SingleDeviceMultipleKernelTest( 2, warp_size, cache_line_size); } } } /** * Test Description * ------------------------ * - Performs atomicMin from multiple threads on the same address. * - Uses only one device and launches one kernel. * Test source * ------------------------ * - unit/atomics/atomicMin.cc * Test requirements * ------------------------ * - HIP_VERSION >= 5.2 */ HIP_TEST_CASE(Unit_atomicMin_Positive_SameAddress) { SECTION("int") { runAtomicMinSameAddressTest(); } SECTION("unsigned int") { runAtomicMinSameAddressTest(); } SECTION("unsigned long") { runAtomicMinSameAddressTest(); } SECTION("unsigned long long") { runAtomicMinSameAddressTest(); } SECTION("float") { runAtomicMinSameAddressTest(); } SECTION("double") { runAtomicMinSameAddressTest(); } } /** * Test Description * ------------------------ * - Performs atomicMin from multiple threads on adjacent addresses. * - Uses only one device and launches one kernel. * Test source * ------------------------ * - unit/atomics/atomicMin.cc * Test requirements * ------------------------ * - HIP_VERSION >= 5.2 */ HIP_TEST_CASE(Unit_atomicMin_Positive_Adjacent_Addresses) { SECTION("int") { runAtomicMinAdjacentAddressesTest(); } SECTION("unsigned int") { runAtomicMinAdjacentAddressesTest(); } SECTION("unsigned long") { runAtomicMinAdjacentAddressesTest(); } SECTION("unsigned long long") { runAtomicMinAdjacentAddressesTest(); } SECTION("float") { runAtomicMinAdjacentAddressesTest(); } SECTION("double") { runAtomicMinAdjacentAddressesTest(); } } /** * Test Description * ------------------------ * - Performs atomicMin from multiple threads on the scaterred addresses. * - Uses only one device and launches one kernel. * Test source * ------------------------ * - unit/atomics/atomicMin.cc * Test requirements * ------------------------ * - HIP_VERSION >= 5.2 */ HIP_TEST_CASE(Unit_atomicMin_Positive_Scattered_Addresses) { SECTION("int") { runAtomicMinScatteredAddressesTest(); } SECTION("unsigned int") { runAtomicMinScatteredAddressesTest(); } SECTION("unsigned long") { runAtomicMinScatteredAddressesTest(); } SECTION("unsigned long long") { runAtomicMinScatteredAddressesTest(); } SECTION("float") { runAtomicMinScatteredAddressesTest(); } SECTION("double") { runAtomicMinScatteredAddressesTest(); } } /** * Test Description * ------------------------ * - Performs atomicMin from multiple threads on the same address. * - Uses only one device and launches multiple kernels. * Test source * ------------------------ * - unit/atomics/atomicMin.cc * Test requirements * ------------------------ * - HIP_VERSION >= 5.2 */ HIP_TEST_CASE(Unit_atomicMin_Positive_Multi_Kernel_Same_Address) { SECTION("int") { runAtomicMinMultiKernelSameAddressTest(); } SECTION("unsigned int") { runAtomicMinMultiKernelSameAddressTest(); } SECTION("unsigned long") { runAtomicMinMultiKernelSameAddressTest(); } SECTION("unsigned long long") { runAtomicMinMultiKernelSameAddressTest(); } SECTION("float") { runAtomicMinMultiKernelSameAddressTest(); } SECTION("double") { runAtomicMinMultiKernelSameAddressTest(); } } /** * Test Description * ------------------------ * - Performs atomicMin from multiple threads on adjacent addresses. * - Uses only one device and launches multiple kernels. * Test source * ------------------------ * - unit/atomics/atomicMin.cc * Test requirements * ------------------------ * - HIP_VERSION >= 5.2 */ HIP_TEST_CASE(Unit_atomicMin_Positive_Multi_Kernel_Adjacent_Addresses) { SECTION("int") { runAtomicMinMultiKernelAdjacentAddressesTest(); } SECTION("unsigned int") { runAtomicMinMultiKernelAdjacentAddressesTest(); } SECTION("unsigned long") { runAtomicMinMultiKernelAdjacentAddressesTest(); } SECTION("unsigned long long") { runAtomicMinMultiKernelAdjacentAddressesTest(); } SECTION("float") { runAtomicMinMultiKernelAdjacentAddressesTest(); } SECTION("double") { runAtomicMinMultiKernelAdjacentAddressesTest(); } } /** * Test Description * ------------------------ * - Performs atomicMin from multiple threads on the scaterred addresses. * - Uses only one device and launches multiple kernels. * Test source * ------------------------ * - unit/atomics/atomicMin.cc * Test requirements * ------------------------ * - HIP_VERSION >= 5.2 */ HIP_TEST_CASE(Unit_atomicMin_Positive_Multi_Kernel_Scattered_Addresses) { SECTION("int") { runAtomicMinMultiKernelScatteredAddressesTest(); } SECTION("unsigned int") { runAtomicMinMultiKernelScatteredAddressesTest(); } SECTION("unsigned long") { runAtomicMinMultiKernelScatteredAddressesTest(); } SECTION("unsigned long long") { runAtomicMinMultiKernelScatteredAddressesTest(); } SECTION("float") { runAtomicMinMultiKernelScatteredAddressesTest(); } SECTION("double") { runAtomicMinMultiKernelScatteredAddressesTest(); } } /** * Test Description * ------------------------ * - Compiles atomicMin with invalid parameters. * - Compiles the source with RTC. * Test source * ------------------------ * - unit/atomics/atomicMin.cc * Test requirements * ------------------------ * - HIP_VERSION >= 5.2 */ HIP_TEST_CASE(Unit_atomicMin_Negative_Parameters_RTC) { hiprtcProgram program{}; const auto program_source = GENERATE(kAtomicMin_int, kAtomicMin_uint, kAtomicMin_ulong, kAtomicMin_ulonglong, kAtomicMin_float, kAtomicMin_double); HIPRTC_CHECK( hiprtcCreateProgram(&program, program_source, "atomicMin_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}; // Please check the content of negative_kernels_rtc.hh int expected_error_count{7}; 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); } /** * End doxygen group AtomicsTest. * @} */