From ae0bb9de3920a133d580c808850b23ea5519a528 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Wed, 12 Jul 2023 10:59:59 +0200 Subject: [PATCH 01/44] add resource_groups property to tests --- cmake/create_test.cmake | 265 +++++++++++++++++++++++------------ hip/test/base/CMakeLists.txt | 2 +- resources.json | 51 +++++++ 3 files changed, 230 insertions(+), 88 deletions(-) create mode 100644 resources.json diff --git a/cmake/create_test.cmake b/cmake/create_test.cmake index 58a49ca066c..937beb4eb8d 100644 --- a/cmake/create_test.cmake +++ b/cmake/create_test.cmake @@ -1,10 +1,12 @@ -set(gko_test_single_args "MPI_SIZE") +set(gko_test_resource_args "LOCAL_CORES;PERCENT;TYPE") +set(gko_test_single_args "MPI_SIZE;${gko_test_resource_args}") set(gko_test_multi_args "DISABLE_EXECUTORS;ADDITIONAL_LIBRARIES;ADDITIONAL_INCLUDES") +set(gko_test_option_args "NO_RESOURCES") ## Replaces / by _ to create valid target names from relative paths function(ginkgo_build_test_name test_name target_name) file(RELATIVE_PATH REL_BINARY_DIR - ${PROJECT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + ${PROJECT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}) string(REPLACE "/" "_" TEST_TARGET_NAME "${REL_BINARY_DIR}/${test_name}") set(${target_name} ${TEST_TARGET_NAME} PARENT_SCOPE) endfunction(ginkgo_build_test_name) @@ -12,8 +14,8 @@ endfunction(ginkgo_build_test_name) function(ginkgo_create_gtest_mpi_main) add_library(gtest_mpi_main "") target_sources(gtest_mpi_main - PRIVATE - ${PROJECT_SOURCE_DIR}/core/test/mpi/gtest/mpi_listener.cpp) + PRIVATE + ${PROJECT_SOURCE_DIR}/core/test/mpi/gtest/mpi_listener.cpp) find_package(MPI 3.1 COMPONENTS CXX REQUIRED) target_link_libraries(gtest_mpi_main PRIVATE GTest::GTest MPI::MPI_CXX) endfunction(ginkgo_create_gtest_mpi_main) @@ -24,33 +26,96 @@ function(ginkgo_set_test_target_properties test_target_name) cmake_parse_arguments(PARSE_ARGV 1 set_properties "" "${gko_test_single_args}" "${gko_test_multi_args}") if (GINKGO_FAST_TESTS) target_compile_definitions(${test_target_name} PRIVATE GINKGO_FAST_TESTS) - endif() + endif () if (GINKGO_TEST_NONDEFAULT_STREAM) target_compile_definitions(${test_target_name} PRIVATE GKO_TEST_NONDEFAULT_STREAM) - endif() + endif () if (GINKGO_COMPILING_DPCPP_TEST AND GINKGO_DPCPP_SINGLE_MODE) target_compile_definitions(${test_target_name} PRIVATE GINKGO_DPCPP_SINGLE_MODE=1) - endif() + endif () if (GINKGO_CHECK_CIRCULAR_DEPS) target_link_libraries(${test_target_name} PRIVATE "${GINKGO_CIRCULAR_DEPS_FLAGS}") - endif() + endif () if (set_properties_MPI_SIZE) - if(NOT TARGET gtest_mpi_main) + if (NOT TARGET gtest_mpi_main) ginkgo_create_gtest_mpi_main() - endif() + endif () set(gtest_main gtest_mpi_main MPI::MPI_CXX) - else() + else () set(gtest_main GTest::Main) - endif() + endif () target_compile_features(${test_target_name} PUBLIC cxx_std_14) target_compile_options(${test_target_name} PRIVATE $<$:${GINKGO_COMPILER_FLAGS}>) target_include_directories(${test_target_name} PRIVATE ${Ginkgo_BINARY_DIR} ${set_properties_ADDITIONAL_INCLUDES}) target_link_libraries(${test_target_name} PRIVATE ginkgo ${gtest_main} GTest::GTest ${set_properties_ADDITIONAL_LIBRARIES}) endfunction() +function(ginkgo_add_cpu_resource_requirement_internal test_name local_cores mpi_size) + if (mpi_size) + math(EXPR cores "${mpi_size} * ${local_cores}") + else () + set(cores ${local_cores}) + endif () + set_property(TEST ${test_name} PROPERTY + RESOURCE_GROUPS "cpus:${cores}") +endfunction() + +function(ginkgo_add_resource_requirement test_name) + cmake_parse_arguments(PARSE_ARGV 1 add_rr "${gko_test_option_args}" "${gko_test_single_args}" "") + if(add_rr_NO_RESOURCES) + return() + endif() + + if (NOT add_rr_TYPE) + message(FATAL_ERROR "Need to provide resource type used by test.") + endif () + + if(add_rr_TYPE STREQUAL "ref") + set(single_resource "cpus:1") + elseif(add_rr_TYPE STREQUAL "cpu") + if(NOT add_rr_CORES) + set(add_rr_CORES 4) # perhaps get this from environment variable? + endif() + if(NOT add_rr_CORES MATCHES "^[0-9]+") + message(FATAL_ERROR "Resource specification is invalid: CORE=${add_rr_CORES}") + endif() + + set(single_resource "cpus:${add_rr_CORES}") + elseif(add_rr_TYPE STREQUAL "gpu") + if(NOT add_rr_PERCENTAGE) + set(add_rr_PERCENTAGE 50) + endif() + if(add_rr_MPI_SIZE GREATER 1) + set(add_rr_PERCENTAGE 100) + endif() + if(NOT add_rr_PERCENTAGE MATCHES "^[0-9]([0-9][0-9]?)?" + OR add_rr_PERCENTAGE LESS 0 + OR add_rr_PERCENTAGE GREATER 100) + message(FATAL_ERROR "Resource specification is invalid: PERCENTAGE=${add_rr_PERCENTAGE}") + endif() + + set(single_resource "gpus:${add_rr_PERCENTAGE}") + else() + message(FATAL_ERROR "Unrecognized resource type ${add_rr_TYPE}, allowed are: ref, cpu, gpu.") + endif() + + if(NOT add_rr_MPI_SIZE) + set(add_rr_MPI_SIZE 1) + endif() + foreach(unused RANGE ${MPI_SIZE}) + list(APPEND resources "${single_resource}") + endforeach() + set_property(TEST ${test_name} + PROPERTY + RESOURCE_GROUPS ${resources}) +endfunction() + + ## Adds a test to the list executed by ctest and sets its output binary name ## Possible additional arguments: ## - `MPI_SIZE size` causes the tests to be run with `size` MPI processes. +## - `CORES` the number of threads used by a test, default is 4 +## - `PERCENTAGE` usage percentage of a single GPU, default is 50 ## - `DISABLE_EXECUTORS exec1 exec2` disables the test for certain backends (if built for multiple) ## - `ADDITIONAL_LIBRARIES lib1 lib2` adds additional target link dependencies ## - `ADDITIONAL_INCLUDES path1 path2` adds additional target include paths @@ -60,36 +125,39 @@ function(ginkgo_add_test test_name test_target_name) set_target_properties(${test_target_name} PROPERTIES OUTPUT_NAME ${test_name}) if (add_test_MPI_SIZE) add_test(NAME ${REL_BINARY_DIR}/${test_name} - COMMAND - ${MPIEXEC_EXECUTABLE} - ${MPIEXEC_NUMPROC_FLAG} - ${add_test_MPI_SIZE} - "$" - WORKING_DIRECTORY "$") - else() + COMMAND + ${MPIEXEC_EXECUTABLE} + ${MPIEXEC_NUMPROC_FLAG} + ${add_test_MPI_SIZE} + "$" + WORKING_DIRECTORY "$") + else () add_test(NAME ${REL_BINARY_DIR}/${test_name} - COMMAND ${test_target_name} - WORKING_DIRECTORY "$") - endif() + COMMAND ${test_target_name} + WORKING_DIRECTORY "$") + endif () + + ginkgo_add_resource_requirement(${REL_BINARY_DIR}/${test_name} ${ARGN}) + set(test_preload) if (GINKGO_TEST_NONDEFAULT_STREAM AND GINKGO_BUILD_CUDA) set(test_preload $:${test_preload}) - endif() + endif () if (GINKGO_TEST_NONDEFAULT_STREAM AND GINKGO_BUILD_HIP AND GINKGO_HIP_PLATFORM MATCHES "${HIP_PLATFORM_AMD_REGEX}") set(test_preload $:${test_preload}) - endif() - if(test_preload) + endif () + if (test_preload) set_tests_properties(${REL_BINARY_DIR}/${test_name} PROPERTIES ENVIRONMENT LD_PRELOAD=${test_preload}) - endif() + endif () endfunction() ## Normal test function(ginkgo_create_test test_name) ginkgo_build_test_name(${test_name} test_target_name) add_executable(${test_target_name} ${test_name}.cpp) - target_link_libraries(${test_target_name} PRIVATE ${create_test_ADDITIONAL_LIBRARIES}) + target_link_libraries(${test_target_name}) ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) - ginkgo_add_test(${test_name} ${test_target_name} ${ARGN}) + ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} TYPE ref) endfunction(ginkgo_create_test) ## Test compiled with dpcpp @@ -100,11 +168,11 @@ function(ginkgo_create_dpcpp_test test_name) target_compile_options(${test_target_name} PRIVATE ${GINKGO_DPCPP_FLAGS}) target_link_options(${test_target_name} PRIVATE -fsycl-device-code-split=per_kernel) ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) - ginkgo_add_test(${test_name} ${test_target_name} ${ARGN}) + ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} TYPE gpu) # Note: MKL_ENV is empty on linux. Maybe need to apply MKL_ENV to all test. if (MKL_ENV) set_tests_properties(${test_target_name} PROPERTIES ENVIRONMENT "${MKL_ENV}") - endif() + endif () endfunction(ginkgo_create_dpcpp_test) ## Test compiled with CUDA @@ -118,23 +186,23 @@ function(ginkgo_create_cuda_test_internal test_name filename test_target_name) add_executable(${test_target_name} ${filename}) target_compile_definitions(${test_target_name} PRIVATE GKO_COMPILING_CUDA) target_compile_options(${test_target_name} - PRIVATE + PRIVATE $<$:${GINKGO_CUDA_COMPILER_FLAGS}>) - if(MSVC) + if (MSVC) target_compile_options(${test_target_name} - PRIVATE + PRIVATE $<$:--extended-lambda --expt-relaxed-constexpr>) - elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") + elseif (CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") target_compile_options(${test_target_name} - PRIVATE + PRIVATE $<$:--expt-extended-lambda --expt-relaxed-constexpr>) - endif() + endif () # we handle CUDA architecture flags for now, disable CMake handling - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.18) + if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.18) set_target_properties(${test_target_name} PROPERTIES CUDA_ARCHITECTURES OFF) - endif() + endif () ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) - ginkgo_add_test(${test_name} ${test_target_name} ${ARGN}) + ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} TYPE gpu) endfunction(ginkgo_create_cuda_test_internal) ## Test compiled with HIP @@ -149,71 +217,94 @@ function(ginkgo_create_hip_test_internal test_name filename test_target_name add set(GINKGO_TEST_HIP_DEFINES -DGKO_COMPILING_HIP ${additional_flags}) if (GINKGO_FAST_TESTS) list(APPEND GINKGO_TEST_HIP_DEFINES -DGINKGO_FAST_TESTS) - endif() + endif () if (GINKGO_TEST_NONDEFAULT_STREAM) list(APPEND GINKGO_TEST_HIP_DEFINES -DGKO_TEST_NONDEFAULT_STREAM) - endif() + endif () # NOTE: With how HIP works, passing the flags `HIPCC_OPTIONS` etc. here # creates a redefinition of all flags. This creates some issues with `nvcc`, # but `clang` seems fine with the redefinitions. if (GINKGO_HIP_PLATFORM MATCHES "${HIP_PLATFORM_NVIDIA_REGEX}") hip_add_executable(${test_target_name} ${filename} - # If `FindHIP.cmake`, namely `HIP_PARSE_HIPCC_OPTIONS` macro and - # call gets fixed, uncomment this. - HIPCC_OPTIONS ${GINKGO_TEST_HIP_DEFINES} # ${GINKGO_HIPCC_OPTIONS} - # NVCC_OPTIONS ${GINKGO_TEST_HIP_DEFINES} ${GINKGO_HIP_NVCC_OPTIONS} - # CLANG_OPTIONS ${GINKGO_TEST_HIP_DEFINES} ${GINKGO_HIP_CLANG_OPTIONS} - --expt-relaxed-constexpr --expt-extended-lambda - ) - else() # hcc/clang + # If `FindHIP.cmake`, namely `HIP_PARSE_HIPCC_OPTIONS` macro and + # call gets fixed, uncomment this. + HIPCC_OPTIONS ${GINKGO_TEST_HIP_DEFINES} # ${GINKGO_HIPCC_OPTIONS} + # NVCC_OPTIONS ${GINKGO_TEST_HIP_DEFINES} ${GINKGO_HIP_NVCC_OPTIONS} + # CLANG_OPTIONS ${GINKGO_TEST_HIP_DEFINES} ${GINKGO_HIP_CLANG_OPTIONS} + --expt-relaxed-constexpr --expt-extended-lambda + ) + else () # hcc/clang hip_add_executable(${test_target_name} ${filename} - HIPCC_OPTIONS ${GINKGO_HIPCC_OPTIONS} ${GINKGO_TEST_HIP_DEFINES} - NVCC_OPTIONS ${GINKGO_HIP_NVCC_OPTIONS} - CLANG_OPTIONS ${GINKGO_HIP_CLANG_OPTIONS} - ) - endif() + HIPCC_OPTIONS ${GINKGO_HIPCC_OPTIONS} ${GINKGO_TEST_HIP_DEFINES} + NVCC_OPTIONS ${GINKGO_HIP_NVCC_OPTIONS} + CLANG_OPTIONS ${GINKGO_HIP_CLANG_OPTIONS} + ) + endif () # Let's use a normal compiler for linking set_target_properties(${test_target_name} PROPERTIES LINKER_LANGUAGE CXX) target_include_directories(${test_target_name} - PRIVATE - # Only `math` requires it so far, but it's much easier - # to put these this way. - ${GINKGO_HIP_THRUST_PATH} - # Only `exception_helpers` requires these so far, but it's much easier - # to put these this way. - ${HIPBLAS_INCLUDE_DIRS} - ${HIPFFT_INCLUDE_DIRS} - ${hiprand_INCLUDE_DIRS} - ${HIPSPARSE_INCLUDE_DIRS} - ) + PRIVATE + # Only `math` requires it so far, but it's much easier + # to put these this way. + ${GINKGO_HIP_THRUST_PATH} + # Only `exception_helpers` requires these so far, but it's much easier + # to put these this way. + ${HIPBLAS_INCLUDE_DIRS} + ${HIPFFT_INCLUDE_DIRS} + ${hiprand_INCLUDE_DIRS} + ${HIPSPARSE_INCLUDE_DIRS} + ) ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) - ginkgo_add_test(${test_name} ${test_target_name} ${ARGN}) + ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} TYPE gpu) endfunction(ginkgo_create_hip_test_internal) + +## Test compiled with OpenMP +function(ginkgo_create_omp_test test_name) + ginkgo_build_test_name(${test_name} test_target_name) + ginkgo_create_omp_test_internal(${test_name} ${test_name}.cpp ${test_target_name} "" ${ARGN}) +endfunction() + +function(ginkgo_create_omp_test_internal test_name filename test_target_name) + ginkgo_build_test_name(${test_name} test_target_name) + add_executable(${test_target_name} ${test_name}.cpp) + target_compile_definitions(${test_target_name} PRIVATE GKO_COMPILING_OMP) + target_link_libraries(${test_target_name} PRIVATE OpenMP::OpenMP_CXX) + ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) + ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} TYPE cpu) +endfunction() + ## Common test compiled with the host compiler, one target for each enabled backend function(ginkgo_create_common_test test_name) - if(GINKGO_BUILD_OMP) + if (GINKGO_BUILD_OMP) ginkgo_create_common_test_internal(${test_name} OmpExecutor omp ${ARGN}) - endif() - if(GINKGO_BUILD_HIP) + endif () + if (GINKGO_BUILD_HIP) ginkgo_create_common_test_internal(${test_name} HipExecutor hip ${ARGN}) - endif() - if(GINKGO_BUILD_CUDA) + endif () + if (GINKGO_BUILD_CUDA) ginkgo_create_common_test_internal(${test_name} CudaExecutor cuda ${ARGN}) - endif() - if(GINKGO_BUILD_DPCPP) + endif () + if (GINKGO_BUILD_DPCPP) ginkgo_create_common_test_internal(${test_name} DpcppExecutor dpcpp ${ARGN}) - endif() + endif () endfunction(ginkgo_create_common_test) function(ginkgo_create_common_test_internal test_name exec_type exec) cmake_parse_arguments(PARSE_ARGV 3 common_test "" "${gko_test_single_args}" "${gko_test_multi_args}") - if(exec IN_LIST common_test_DISABLE_EXECUTORS) + if (exec IN_LIST common_test_DISABLE_EXECUTORS) return() - endif() + endif () + if (exec STREQUAL reference) + set(test_resource_type ref) + elseif (exec STREQUAL omp) + set(test_resource_type cpu) + else () + set(test_resource_type gpu) + endif () ginkgo_build_test_name(${test_name} test_target_name) string(TOUPPER ${exec} exec_upper) # set up actual test @@ -222,39 +313,39 @@ function(ginkgo_create_common_test_internal test_name exec_type exec) target_compile_definitions(${test_target_name} PRIVATE EXEC_TYPE=${exec_type} EXEC_NAMESPACE=${exec} GKO_COMPILING_${exec_upper}) target_link_libraries(${test_target_name} PRIVATE ${common_test_ADDITIONAL_LIBRARIES}) # use float for DPC++ if necessary - if((exec STREQUAL "dpcpp") AND GINKGO_DPCPP_SINGLE_MODE) + if ((exec STREQUAL "dpcpp") AND GINKGO_DPCPP_SINGLE_MODE) target_compile_definitions(${test_target_name} PRIVATE GINKGO_COMMON_SINGLE_MODE=1) target_compile_definitions(${test_target_name} PRIVATE GINKGO_DPCPP_SINGLE_MODE=1) - endif() + endif () ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) - ginkgo_add_test(${test_name}_${exec} ${test_target_name} ${ARGN}) + ginkgo_add_test(${test_name}_${exec} ${test_target_name} ${ARGN} TYPE ${test_resource_type}) endfunction(ginkgo_create_common_test_internal) ## Common test compiled with the device compiler, one target for each enabled backend function(ginkgo_create_common_device_test test_name) cmake_parse_arguments(PARSE_ARGV 1 common_device_test "" "${gko_test_single_args}" "${gko_test_multi_args}") ginkgo_build_test_name(${test_name} test_target_name) - if(GINKGO_BUILD_DPCPP) + if (GINKGO_BUILD_DPCPP) ginkgo_create_common_test_internal(${test_name} DpcppExecutor dpcpp ${ARGN}) target_compile_features(${test_target_name}_dpcpp PRIVATE cxx_std_17) target_compile_options(${test_target_name}_dpcpp PRIVATE ${GINKGO_DPCPP_FLAGS}) target_link_options(${test_target_name}_dpcpp PRIVATE -fsycl-device-lib=all -fsycl-device-code-split=per_kernel) - endif() - if(GINKGO_BUILD_OMP) + endif () + if (GINKGO_BUILD_OMP) ginkgo_create_common_test_internal(${test_name} OmpExecutor omp ${ARGN}) target_link_libraries(${test_target_name}_omp PUBLIC OpenMP::OpenMP_CXX) - endif() - if(GINKGO_BUILD_CUDA) + endif () + if (GINKGO_BUILD_CUDA) # need to make a separate file for this, since we can't set conflicting properties on the same file configure_file(${test_name}.cpp ${test_name}.cu COPYONLY) ginkgo_create_cuda_test_internal(${test_name}_cuda ${CMAKE_CURRENT_BINARY_DIR}/${test_name}.cu ${test_target_name}_cuda ${ARGN}) target_compile_definitions(${test_target_name}_cuda PRIVATE EXEC_TYPE=CudaExecutor EXEC_NAMESPACE=cuda) - endif() - if(GINKGO_BUILD_HIP) + endif () + if (GINKGO_BUILD_HIP) # need to make a separate file for this, since we can't set conflicting properties on the same file configure_file(${test_name}.cpp ${test_name}.hip.cpp COPYONLY) ginkgo_create_hip_test_internal(${test_name}_hip ${CMAKE_CURRENT_BINARY_DIR}/${test_name}.hip.cpp ${test_target_name}_hip "-std=c++14;-DEXEC_TYPE=HipExecutor;-DEXEC_NAMESPACE=hip" ${ARGN}) - endif() + endif () endfunction(ginkgo_create_common_device_test) ## Common test compiled with the host compiler for all enabled backends and Reference diff --git a/hip/test/base/CMakeLists.txt b/hip/test/base/CMakeLists.txt index 486fca294c2..ed32ab5b6a7 100644 --- a/hip/test/base/CMakeLists.txt +++ b/hip/test/base/CMakeLists.txt @@ -15,4 +15,4 @@ if (GINKGO_HIP_PLATFORM MATCHES "${HIP_PLATFORM_AMD_REGEX}") else() ginkgo_create_hip_test(exception_helpers) endif() -ginkgo_create_hip_test(scoped_device_id) +ginkgo_create_hip_test(scoped_device_id NO_RESOURCES) diff --git a/resources.json b/resources.json new file mode 100644 index 00000000000..9d69ada752b --- /dev/null +++ b/resources.json @@ -0,0 +1,51 @@ +{ + "version": { + "major": 1, + "minor": 0 + }, + "local": [ + { + "cpus": [ + { + "id": "0", + "slots": 32 + } + ], + + "gpus": [ + { + "id": "0", + "slots": 100 + }, + { + "id": "1", + "slots": 100 + }, + { + "id": "2", + "slots": 100 + }, + { + "id": "3", + "slots": 100 + }, + { + "id": "4", + "slots": 100 + }, + { + "id": "5", + "slots": 100 + }, + { + "id": "6", + "slots": 100 + }, + { + "id": "7", + "slots": 100 + } + ] + } + ] +} \ No newline at end of file From 6e336ee11519bb2e7747dc8b92578d9caa3d972b Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Tue, 1 Aug 2023 17:52:21 +0200 Subject: [PATCH 02/44] add custom gtest main files --- cmake/create_test.cmake | 57 +++++++++++-------- core/test/gtest/environments.hpp | 40 +++++++++++++ core/test/gtest/ginkgo_main.cpp | 14 +++++ .../ginkgo_mpi_main.cpp} | 5 ++ cuda/test/utils.hpp | 9 --- hip/test/utils.hip.hpp | 9 --- test/utils/executor.hpp | 33 ----------- 7 files changed, 93 insertions(+), 74 deletions(-) create mode 100644 core/test/gtest/environments.hpp create mode 100644 core/test/gtest/ginkgo_main.cpp rename core/test/{mpi/gtest/mpi_listener.cpp => gtest/ginkgo_mpi_main.cpp} (98%) diff --git a/cmake/create_test.cmake b/cmake/create_test.cmake index 937beb4eb8d..e6ebc6523a2 100644 --- a/cmake/create_test.cmake +++ b/cmake/create_test.cmake @@ -5,20 +5,28 @@ set(gko_test_option_args "NO_RESOURCES") ## Replaces / by _ to create valid target names from relative paths function(ginkgo_build_test_name test_name target_name) - file(RELATIVE_PATH REL_BINARY_DIR - ${PROJECT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}) - string(REPLACE "/" "_" TEST_TARGET_NAME "${REL_BINARY_DIR}/${test_name}") - set(${target_name} ${TEST_TARGET_NAME} PARENT_SCOPE) -endfunction(ginkgo_build_test_name) + file(RELATIVE_PATH REL_BINARY_DIR + ${PROJECT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + string(REPLACE "/" "_" TEST_TARGET_NAME "${REL_BINARY_DIR}/${test_name}") + set(${target_name} ${TEST_TARGET_NAME} PARENT_SCOPE) +endfunction() + +function(ginkgo_create_gtest_main) + add_library(ginkgo_gtest_main "") + target_sources(ginkgo_gtest_main + PRIVATE + ${PROJECT_SOURCE_DIR}/core/test/gtest/ginkgo_main.cpp) + target_link_libraries(ginkgo_gtest_main PRIVATE GTest::GTest Ginkgo::ginkgo) +endfunction() function(ginkgo_create_gtest_mpi_main) - add_library(gtest_mpi_main "") - target_sources(gtest_mpi_main - PRIVATE - ${PROJECT_SOURCE_DIR}/core/test/mpi/gtest/mpi_listener.cpp) - find_package(MPI 3.1 COMPONENTS CXX REQUIRED) - target_link_libraries(gtest_mpi_main PRIVATE GTest::GTest MPI::MPI_CXX) -endfunction(ginkgo_create_gtest_mpi_main) + add_library(ginkgo_gtest_mpi_main "") + target_sources(ginkgo_gtest_mpi_main + PRIVATE + ${PROJECT_SOURCE_DIR}/core/test/gtest/ginkgo_mpi_main.cpp) + find_package(MPI 3.1 COMPONENTS CXX REQUIRED) + target_link_libraries(ginkgo_gtest_mpi_main PRIVATE GTest::GTest MPI::MPI_CXX Ginkgo::ginkgo) +endfunction() ## Set up shared target properties and handle ADDITIONAL_LIBRARIES/ADDITIONAL_INCLUDES ## `MPI_SIZE size` causes the tests to be run with `size` MPI processes. @@ -33,17 +41,20 @@ function(ginkgo_set_test_target_properties test_target_name) if (GINKGO_COMPILING_DPCPP_TEST AND GINKGO_DPCPP_SINGLE_MODE) target_compile_definitions(${test_target_name} PRIVATE GINKGO_DPCPP_SINGLE_MODE=1) endif () - if (GINKGO_CHECK_CIRCULAR_DEPS) - target_link_libraries(${test_target_name} PRIVATE "${GINKGO_CIRCULAR_DEPS_FLAGS}") - endif () - if (set_properties_MPI_SIZE) - if (NOT TARGET gtest_mpi_main) - ginkgo_create_gtest_mpi_main() - endif () - set(gtest_main gtest_mpi_main MPI::MPI_CXX) - else () - set(gtest_main GTest::Main) - endif () + if(GINKGO_CHECK_CIRCULAR_DEPS) + target_link_libraries(${test_target_name} PRIVATE "${GINKGO_CIRCULAR_DEPS_FLAGS}") + endif() + if(set_properties_MPI_SIZE) + if(NOT TARGET ginkgo_gtest_mpi_main) + ginkgo_create_gtest_mpi_main() + endif() + set(gtest_main ginkgo_gtest_mpi_main MPI::MPI_CXX) + else() + if(NOT TARGET ginkgo_gtest_main) + ginkgo_create_gtest_main() + endif() + set(gtest_main ginkgo_gtest_main) + endif() target_compile_features(${test_target_name} PUBLIC cxx_std_14) target_compile_options(${test_target_name} PRIVATE $<$:${GINKGO_COMPILER_FLAGS}>) target_include_directories(${test_target_name} PRIVATE ${Ginkgo_BINARY_DIR} ${set_properties_ADDITIONAL_INCLUDES}) diff --git a/core/test/gtest/environments.hpp b/core/test/gtest/environments.hpp new file mode 100644 index 00000000000..b248829bdfb --- /dev/null +++ b/core/test/gtest/environments.hpp @@ -0,0 +1,40 @@ +#ifndef GINKGO_ENVIRONMENTS_HPP +#define GINKGO_ENVIRONMENTS_HPP + + +#include + + +#ifdef GKO_COMPILING_CUDA + +#include "cuda/base/device.hpp" + +class CudaEnvironment : public ::testing::Environment { +public: + void TearDown() override { gko::kernels::cuda::reset_device(0); } +}; + +#else + +class CudaEnvironment : public ::testing::Environment {}; + +#endif + + +#ifdef GKO_COMPILING_HIP + +#include "hip/base/device.hpp" + +class HipEnvironment : public ::testing::Environment { +public: + void TearDown() override { gko::kernels::hip::reset_device(0); } +}; + +#else + +class HipEnvironment : public ::testing::Environment {}; + +#endif + + +#endif // GINKGO_ENVIRONMENTS_HPP diff --git a/core/test/gtest/ginkgo_main.cpp b/core/test/gtest/ginkgo_main.cpp new file mode 100644 index 00000000000..c284db84794 --- /dev/null +++ b/core/test/gtest/ginkgo_main.cpp @@ -0,0 +1,14 @@ +#include + + +#include "core/test/gtest/environments.hpp" + + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + ::testing::AddGlobalTestEnvironment(new CudaEnvironment); + ::testing::AddGlobalTestEnvironment(new HipEnvironment); + int result = RUN_ALL_TESTS(); + return result; +} \ No newline at end of file diff --git a/core/test/mpi/gtest/mpi_listener.cpp b/core/test/gtest/ginkgo_mpi_main.cpp similarity index 98% rename from core/test/mpi/gtest/mpi_listener.cpp rename to core/test/gtest/ginkgo_mpi_main.cpp index 66c9e6cd319..6c9b1b248f3 100644 --- a/core/test/mpi/gtest/mpi_listener.cpp +++ b/core/test/gtest/ginkgo_mpi_main.cpp @@ -51,6 +51,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +#include "core/test/gtest/environments.hpp" + + namespace GTestMPIListener { // This class sets up the global test environment, which is needed @@ -378,6 +381,8 @@ int main(int argc, char** argv) ::testing::InitGoogleTest(&argc, argv); MPI_Init(&argc, &argv); ::testing::AddGlobalTestEnvironment(new GTestMPIListener::MPIEnvironment); + ::testing::AddGlobalTestEnvironment(new CudaEnvironment); + ::testing::AddGlobalTestEnvironment(new HipEnvironment); ::testing::TestEventListeners& listeners = ::testing::UnitTest::GetInstance()->listeners(); ::testing::TestEventListener* l = diff --git a/cuda/test/utils.hpp b/cuda/test/utils.hpp index e1156b91903..58d310024bd 100644 --- a/cuda/test/utils.hpp +++ b/cuda/test/utils.hpp @@ -47,15 +47,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace { -class CudaEnvironment : public ::testing::Environment { -public: - void TearDown() override { gko::kernels::cuda::reset_device(0); } -}; - -testing::Environment* cuda_env = - testing::AddGlobalTestEnvironment(new CudaEnvironment); - - class CudaTestFixture : public ::testing::Test { protected: CudaTestFixture() diff --git a/hip/test/utils.hip.hpp b/hip/test/utils.hip.hpp index bf7073cf9a1..dcecc8d2522 100644 --- a/hip/test/utils.hip.hpp +++ b/hip/test/utils.hip.hpp @@ -47,15 +47,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace { -class HipEnvironment : public ::testing::Environment { -public: - void TearDown() override { gko::kernels::hip::reset_device(0); } -}; - -testing::Environment* hip_env = - testing::AddGlobalTestEnvironment(new HipEnvironment); - - class HipTestFixture : public ::testing::Test { protected: HipTestFixture() diff --git a/test/utils/executor.hpp b/test/utils/executor.hpp index 200f4652644..ca6ad2a75c9 100644 --- a/test/utils/executor.hpp +++ b/test/utils/executor.hpp @@ -44,39 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include - - -#ifdef GKO_COMPILING_CUDA - -#include "cuda/base/device.hpp" - -class CudaEnvironment : public ::testing::Environment { -public: - void TearDown() override { gko::kernels::cuda::reset_device(0); } -}; - -testing::Environment* cuda_env = - testing::AddGlobalTestEnvironment(new CudaEnvironment); - -#endif - - -#ifdef GKO_COMPILING_HIP - -#include "hip/base/device.hpp" - -class HipEnvironment : public ::testing::Environment { -public: - void TearDown() override { gko::kernels::hip::reset_device(0); } -}; - -testing::Environment* hip_env = - testing::AddGlobalTestEnvironment(new HipEnvironment); - -#endif - - #if GINKGO_COMMON_SINGLE_MODE #define SKIP_IF_SINGLE_MODE GTEST_SKIP() << "Skip due to single mode" #else From 258e329ce64e1fe22858770ffe568da0ae11cb5e Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Wed, 12 Jul 2023 17:15:45 +0200 Subject: [PATCH 03/44] use resources in tests --- core/test/gtest/environments.hpp | 109 +++++++++++++++++++++++++++- core/test/gtest/ginkgo_main.cpp | 7 ++ core/test/gtest/ginkgo_mpi_main.cpp | 23 ++++-- test/utils/executor.hpp | 16 ++-- test/utils/mpi/executor.hpp | 73 +------------------ 5 files changed, 145 insertions(+), 83 deletions(-) diff --git a/core/test/gtest/environments.hpp b/core/test/gtest/environments.hpp index b248829bdfb..3f93ea95b8a 100644 --- a/core/test/gtest/environments.hpp +++ b/core/test/gtest/environments.hpp @@ -1,17 +1,119 @@ #ifndef GINKGO_ENVIRONMENTS_HPP #define GINKGO_ENVIRONMENTS_HPP +#include +#include + #include +std::vector split(const std::string& s, char delimiter = ',') +{ + std::istringstream iss(s); + std::vector tokens; + std::string token; + while (std::getline(iss, token, delimiter)) { + tokens.push_back(token); + } + return tokens; +} + + +struct resource { + int id; + int slots; +}; + +resource parse_single_resource(const std::string& resource_string) +{ + std::regex re(R"(id\:(\d+),slots\:(\d+))"); + std::smatch match; + + if (!std::regex_match(resource_string, match, re)) { + GKO_INVALID_STATE("Can't parse resource string: " + resource_string); + } + + return resource{std::stoi(match[1]), std::stoi(match[2])}; +} + +std::vector parse_all_resources(const std::string& resource_string) +{ + auto resource_strings = split(resource_string, ';'); + + std::vector resources; + for (const auto& rs : resource_strings) { + resources.push_back(parse_single_resource(rs)); + } + return resources; +} + + +std::vector get_ctest_resources() +{ + auto rs_count_env = std::getenv("CTEST_RESOURCE_GROUP_COUNT"); + + if (!rs_count_env) { + return {{0, 1}}; + } + + auto rs_count = std::stoi(rs_count_env); + + if (rs_count > 1) { + GKO_INVALID_STATE("Can handle only one resource group."); + } + + std::string rs_type = std::getenv("CTEST_RESOURCE_GROUP_0"); + std::transform(rs_type.begin(), rs_type.end(), rs_type.begin(), + [](auto c) { return std::toupper(c); }); + std::string rs_env = + std::getenv(std::string("CTEST_RESOURCE_GROUP_0_" + rs_type).c_str()); + std::cerr << rs_env << std::endl; + return parse_all_resources(rs_env); +} + + +class ResourceEnvironment : public ::testing::Environment { +public: + explicit ResourceEnvironment(resource rs_) : ::testing::Environment() + { + rs = rs_; + } + + static resource rs; +}; + + +#ifdef GKO_COMPILING_OMP + +#include + +class OmpEnvironment : public ::testing::Environment { +public: + void SetUp() override + { + omp_set_num_threads(ResourceEnvironment::rs.slots); + } +}; + +#else + + +class OmpEnvironment : public ::testing::Environment {}; + +#endif + + #ifdef GKO_COMPILING_CUDA #include "cuda/base/device.hpp" class CudaEnvironment : public ::testing::Environment { public: - void TearDown() override { gko::kernels::cuda::reset_device(0); } + void TearDown() override + { + gko::kernels::cuda::reset_device(ResourceEnvironment::rs.id); + } }; #else @@ -27,7 +129,10 @@ class CudaEnvironment : public ::testing::Environment {}; class HipEnvironment : public ::testing::Environment { public: - void TearDown() override { gko::kernels::hip::reset_device(0); } + void TearDown() override + { + gko::kernels::hip::reset_device(ResourceEnvironment::rs.id); + } }; #else diff --git a/core/test/gtest/ginkgo_main.cpp b/core/test/gtest/ginkgo_main.cpp index c284db84794..76a005a66e2 100644 --- a/core/test/gtest/ginkgo_main.cpp +++ b/core/test/gtest/ginkgo_main.cpp @@ -3,12 +3,19 @@ #include "core/test/gtest/environments.hpp" +resource ResourceEnvironment::rs = {}; int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); + + auto resources = get_ctest_resources(); + + ::testing::AddGlobalTestEnvironment( + new ResourceEnvironment(resources.front())); ::testing::AddGlobalTestEnvironment(new CudaEnvironment); ::testing::AddGlobalTestEnvironment(new HipEnvironment); + ::testing::AddGlobalTestEnvironment(new OmpEnvironment); int result = RUN_ALL_TESTS(); return result; } \ No newline at end of file diff --git a/core/test/gtest/ginkgo_mpi_main.cpp b/core/test/gtest/ginkgo_mpi_main.cpp index 6c9b1b248f3..934a3dcd3f5 100644 --- a/core/test/gtest/ginkgo_mpi_main.cpp +++ b/core/test/gtest/ginkgo_mpi_main.cpp @@ -45,10 +45,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include +#include -#include +#include #include "core/test/gtest/environments.hpp" @@ -95,7 +95,6 @@ class MPIEnvironment : public ::testing::Environment { private: // Disallow copying MPIEnvironment(const MPIEnvironment& env) {} - }; // class MPIEnvironment @@ -376,19 +375,31 @@ class MPIWrapperPrinter : public ::testing::TestEventListener { } // namespace GTestMPIListener +resource ResourceEnvironment::rs = {}; + int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); + MPI_Init(&argc, &argv); - ::testing::AddGlobalTestEnvironment(new GTestMPIListener::MPIEnvironment); + MPI_Comm comm(MPI_COMM_WORLD); + int rank; + MPI_Comm_rank(comm, &rank); + + auto resources = get_ctest_resources(); + + testing::AddGlobalTestEnvironment(new GTestMPIListener::MPIEnvironment); + ::testing::AddGlobalTestEnvironment( + new ResourceEnvironment(resources[rank])); ::testing::AddGlobalTestEnvironment(new CudaEnvironment); ::testing::AddGlobalTestEnvironment(new HipEnvironment); + ::testing::AddGlobalTestEnvironment(new OmpEnvironment); + ::testing::TestEventListeners& listeners = ::testing::UnitTest::GetInstance()->listeners(); ::testing::TestEventListener* l = listeners.Release(listeners.default_result_printer()); - listeners.Append( - new GTestMPIListener::MPIWrapperPrinter(l, MPI_COMM_WORLD)); + listeners.Append(new GTestMPIListener::MPIWrapperPrinter(l, comm)); int result = RUN_ALL_TESTS(); return result; } diff --git a/test/utils/executor.hpp b/test/utils/executor.hpp index ca6ad2a75c9..ad4621d5c31 100644 --- a/test/utils/executor.hpp +++ b/test/utils/executor.hpp @@ -44,6 +44,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +#include "core/test/gtest/environments.hpp" + + #if GINKGO_COMMON_SINGLE_MODE #define SKIP_IF_SINGLE_MODE GTEST_SKIP() << "Skip due to single mode" #else @@ -77,7 +80,7 @@ inline void init_executor(std::shared_ptr ref, throw std::runtime_error{"No suitable CUDA devices"}; } exec = gko::CudaExecutor::create( - 0, ref, std::make_shared(), stream); + ResourceEnvironment::rs.id, ref, std::make_shared(), stream); } } @@ -90,7 +93,8 @@ inline void init_executor(std::shared_ptr ref, throw std::runtime_error{"No suitable HIP devices"}; } exec = gko::HipExecutor::create( - 0, ref, std::make_shared(), stream); + ResourceEnvironment::rs.id, ref, std::make_shared< + gko::HipAllocator>(), stream); } @@ -98,9 +102,11 @@ inline void init_executor(std::shared_ptr ref, std::shared_ptr& exec) { if (gko::DpcppExecutor::get_num_devices("gpu") > 0) { - exec = gko::DpcppExecutor::create(0, ref, "gpu"); + exec = + gko::DpcppExecutor::create(ResourceEnvironment::rs.id, ref, "gpu"); } else if (gko::DpcppExecutor::get_num_devices("cpu") > 0) { - exec = gko::DpcppExecutor::create(0, ref, "cpu"); + exec = + gko::DpcppExecutor::create(ResourceEnvironment::rs.id, ref, "cpu"); } else { throw std::runtime_error{"No suitable DPC++ devices"}; } @@ -120,7 +126,7 @@ class CommonTestFixture : public ::testing::Test { : #if defined(GKO_TEST_NONDEFAULT_STREAM) && \ (defined(GKO_COMPILING_CUDA) || defined(GKO_COMPILING_HIP)) - stream{0}, + stream(ResourceEnvironment::rs.id), #endif ref{gko::ReferenceExecutor::create()} { diff --git a/test/utils/mpi/executor.hpp b/test/utils/mpi/executor.hpp index d8c94e01804..4eba5593c90 100644 --- a/test/utils/mpi/executor.hpp +++ b/test/utils/mpi/executor.hpp @@ -35,6 +35,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +#include #include @@ -43,73 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include -#include - - -inline void init_executor(std::shared_ptr, - std::shared_ptr& exec) -{ - exec = gko::ReferenceExecutor::create(); -} - - -inline void init_executor(std::shared_ptr, - std::shared_ptr& exec) -{ - exec = gko::OmpExecutor::create(); -} - - -inline void init_executor(std::shared_ptr ref, - std::shared_ptr& exec, - CUstream_st* stream = nullptr) -{ - { - if (gko::CudaExecutor::get_num_devices() == 0) { - throw std::runtime_error{"No suitable CUDA devices"}; - } - exec = gko::CudaExecutor::create( - gko::experimental::mpi::map_rank_to_device_id( - MPI_COMM_WORLD, gko::CudaExecutor::get_num_devices()), - ref, std::make_shared(), stream); - } -} - - -inline void init_executor(std::shared_ptr ref, - std::shared_ptr& exec, - GKO_HIP_STREAM_STRUCT* stream = nullptr) -{ - if (gko::HipExecutor::get_num_devices() == 0) { - throw std::runtime_error{"No suitable HIP devices"}; - } - exec = gko::HipExecutor::create( - gko::experimental::mpi::map_rank_to_device_id( - MPI_COMM_WORLD, gko::HipExecutor::get_num_devices()), - ref, std::make_shared(), stream); -} - - -inline void init_executor(std::shared_ptr ref, - std::shared_ptr& exec) -{ - auto num_gpu_devices = gko::DpcppExecutor::get_num_devices("gpu"); - auto num_cpu_devices = gko::DpcppExecutor::get_num_devices("cpu"); - if (num_gpu_devices > 0) { - exec = gko::DpcppExecutor::create( - gko::experimental::mpi::map_rank_to_device_id(MPI_COMM_WORLD, - num_gpu_devices), - ref, "gpu"); - } else if (num_cpu_devices > 0) { - exec = gko::DpcppExecutor::create( - gko::experimental::mpi::map_rank_to_device_id(MPI_COMM_WORLD, - num_cpu_devices), - ref, "cpu"); - } else { - throw std::runtime_error{"No suitable DPC++ devices"}; - } -} +#include "test/utils/executor.hpp" class CommonMpiTestFixture : public ::testing::Test { @@ -125,9 +60,7 @@ class CommonMpiTestFixture : public ::testing::Test { : comm(MPI_COMM_WORLD), #if defined(GKO_TEST_NONDEFAULT_STREAM) && \ (defined(GKO_COMPILING_CUDA) || defined(GKO_COMPILING_HIP)) - - stream(gko::experimental::mpi::map_rank_to_device_id( - comm.get(), gko::EXEC_TYPE::get_num_devices())), + stream(ResourceEnvironment::rs.id), #endif ref{gko::ReferenceExecutor::create()} { From 6ca783f83aa37f5b0f256934a62f8209aa8b3da5 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Thu, 20 Jul 2023 14:14:09 +0200 Subject: [PATCH 04/44] add gtest_main.cpp directly to target --- cmake/create_test.cmake | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/cmake/create_test.cmake b/cmake/create_test.cmake index e6ebc6523a2..96310e7f22f 100644 --- a/cmake/create_test.cmake +++ b/cmake/create_test.cmake @@ -45,20 +45,18 @@ function(ginkgo_set_test_target_properties test_target_name) target_link_libraries(${test_target_name} PRIVATE "${GINKGO_CIRCULAR_DEPS_FLAGS}") endif() if(set_properties_MPI_SIZE) - if(NOT TARGET ginkgo_gtest_mpi_main) - ginkgo_create_gtest_mpi_main() - endif() - set(gtest_main ginkgo_gtest_mpi_main MPI::MPI_CXX) + target_sources(${test_target_name} + PRIVATE + ${PROJECT_SOURCE_DIR}/core/test/gtest/ginkgo_mpi_main.cpp) else() - if(NOT TARGET ginkgo_gtest_main) - ginkgo_create_gtest_main() - endif() - set(gtest_main ginkgo_gtest_main) + target_sources(${test_target_name} + PRIVATE + ${PROJECT_SOURCE_DIR}/core/test/gtest/ginkgo_main.cpp) endif() target_compile_features(${test_target_name} PUBLIC cxx_std_14) target_compile_options(${test_target_name} PRIVATE $<$:${GINKGO_COMPILER_FLAGS}>) target_include_directories(${test_target_name} PRIVATE ${Ginkgo_BINARY_DIR} ${set_properties_ADDITIONAL_INCLUDES}) - target_link_libraries(${test_target_name} PRIVATE ginkgo ${gtest_main} GTest::GTest ${set_properties_ADDITIONAL_LIBRARIES}) + target_link_libraries(${test_target_name} PRIVATE ginkgo GTest::GTest ${set_properties_ADDITIONAL_LIBRARIES}) endfunction() function(ginkgo_add_cpu_resource_requirement_internal test_name local_cores mpi_size) From 846bc92f5d30dd48026388b4f55c81e743b197bf Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Thu, 20 Jul 2023 14:15:01 +0200 Subject: [PATCH 05/44] simplify resource group --- cmake/create_test.cmake | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/cmake/create_test.cmake b/cmake/create_test.cmake index 96310e7f22f..1d18d07b516 100644 --- a/cmake/create_test.cmake +++ b/cmake/create_test.cmake @@ -59,16 +59,6 @@ function(ginkgo_set_test_target_properties test_target_name) target_link_libraries(${test_target_name} PRIVATE ginkgo GTest::GTest ${set_properties_ADDITIONAL_LIBRARIES}) endfunction() -function(ginkgo_add_cpu_resource_requirement_internal test_name local_cores mpi_size) - if (mpi_size) - math(EXPR cores "${mpi_size} * ${local_cores}") - else () - set(cores ${local_cores}) - endif () - set_property(TEST ${test_name} PROPERTY - RESOURCE_GROUPS "cpus:${cores}") -endfunction() - function(ginkgo_add_resource_requirement test_name) cmake_parse_arguments(PARSE_ARGV 1 add_rr "${gko_test_option_args}" "${gko_test_single_args}" "") if(add_rr_NO_RESOURCES) @@ -111,12 +101,9 @@ function(ginkgo_add_resource_requirement test_name) if(NOT add_rr_MPI_SIZE) set(add_rr_MPI_SIZE 1) endif() - foreach(unused RANGE ${MPI_SIZE}) - list(APPEND resources "${single_resource}") - endforeach() set_property(TEST ${test_name} PROPERTY - RESOURCE_GROUPS ${resources}) + RESOURCE_GROUPS "${add_rr_MPI_SIZE},${single_resource}") endfunction() From 96eb18fb6673f2d2a42122255428379aaf436b5c Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Thu, 20 Jul 2023 14:37:34 +0200 Subject: [PATCH 06/44] rename cmake parameters --- cmake/create_test.cmake | 201 +++++++++++++++++++++------------------- 1 file changed, 104 insertions(+), 97 deletions(-) diff --git a/cmake/create_test.cmake b/cmake/create_test.cmake index 1d18d07b516..6ce37976f84 100644 --- a/cmake/create_test.cmake +++ b/cmake/create_test.cmake @@ -1,4 +1,4 @@ -set(gko_test_resource_args "LOCAL_CORES;PERCENT;TYPE") +set(gko_test_resource_args "RESOURCE_LOCAL_CORES;RESOURCE_PERCENT;RESOURCE_TYPE") set(gko_test_single_args "MPI_SIZE;${gko_test_resource_args}") set(gko_test_multi_args "DISABLE_EXECUTORS;ADDITIONAL_LIBRARIES;ADDITIONAL_INCLUDES") set(gko_test_option_args "NO_RESOURCES") @@ -34,13 +34,13 @@ function(ginkgo_set_test_target_properties test_target_name) cmake_parse_arguments(PARSE_ARGV 1 set_properties "" "${gko_test_single_args}" "${gko_test_multi_args}") if (GINKGO_FAST_TESTS) target_compile_definitions(${test_target_name} PRIVATE GINKGO_FAST_TESTS) - endif () + endif() if (GINKGO_TEST_NONDEFAULT_STREAM) target_compile_definitions(${test_target_name} PRIVATE GKO_TEST_NONDEFAULT_STREAM) - endif () + endif() if (GINKGO_COMPILING_DPCPP_TEST AND GINKGO_DPCPP_SINGLE_MODE) target_compile_definitions(${test_target_name} PRIVATE GINKGO_DPCPP_SINGLE_MODE=1) - endif () + endif() if(GINKGO_CHECK_CIRCULAR_DEPS) target_link_libraries(${test_target_name} PRIVATE "${GINKGO_CIRCULAR_DEPS_FLAGS}") endif() @@ -65,37 +65,37 @@ function(ginkgo_add_resource_requirement test_name) return() endif() - if (NOT add_rr_TYPE) + if (NOT add_rr_RESOURCE_TYPE) message(FATAL_ERROR "Need to provide resource type used by test.") endif () - if(add_rr_TYPE STREQUAL "ref") + if(add_rr_RESOURCE_TYPE STREQUAL "ref") set(single_resource "cpus:1") - elseif(add_rr_TYPE STREQUAL "cpu") - if(NOT add_rr_CORES) - set(add_rr_CORES 4) # perhaps get this from environment variable? + elseif(add_rr_RESOURCE_TYPE STREQUAL "cpu") + if(NOT add_rr_RESOURCE_LOCAL_CORES) + set(add_rr_RESOURCE_LOCAL_CORES 4) # perhaps get this from environment variable? endif() - if(NOT add_rr_CORES MATCHES "^[0-9]+") - message(FATAL_ERROR "Resource specification is invalid: CORE=${add_rr_CORES}") + if(NOT add_rr_RESOURCE_LOCAL_CORES MATCHES "^[0-9]+") + message(FATAL_ERROR "Resource specification is invalid: RESOURCE_LOCAL_CORE=${add_rr_RESOURCE_LOCAL_CORES}") endif() - set(single_resource "cpus:${add_rr_CORES}") - elseif(add_rr_TYPE STREQUAL "gpu") - if(NOT add_rr_PERCENTAGE) - set(add_rr_PERCENTAGE 50) + set(single_resource "cpus:${add_rr_RESOURCE_LOCAL_CORES}") + elseif(add_rr_RESOURCE_TYPE STREQUAL "gpu") + if(NOT add_rr_RESOURCE_PERCENTAGE) + set(add_rr_RESOURCE_PERCENTAGE 50) endif() if(add_rr_MPI_SIZE GREATER 1) - set(add_rr_PERCENTAGE 100) + set(add_rr_RESOURCE_PERCENTAGE 100) endif() - if(NOT add_rr_PERCENTAGE MATCHES "^[0-9]([0-9][0-9]?)?" - OR add_rr_PERCENTAGE LESS 0 - OR add_rr_PERCENTAGE GREATER 100) - message(FATAL_ERROR "Resource specification is invalid: PERCENTAGE=${add_rr_PERCENTAGE}") + if(NOT add_rr_RESOURCE_PERCENTAGE MATCHES "^[0-9]([0-9][0-9]?)?" + OR add_rr_RESOURCE_PERCENTAGE LESS 0 + OR add_rr_RESOURCE_PERCENTAGE GREATER 100) + message(FATAL_ERROR "Resource specification is invalid: RESOURCE_PERCENTAGE=${add_rr_RESOURCE_PERCENTAGE}") endif() - set(single_resource "gpus:${add_rr_PERCENTAGE}") + set(single_resource "gpus:${add_rr_RESOURCE_PERCENTAGE}") else() - message(FATAL_ERROR "Unrecognized resource type ${add_rr_TYPE}, allowed are: ref, cpu, gpu.") + message(FATAL_ERROR "Unrecognized resource type ${add_rr_RESOURCE_TYPE}, allowed are: ref, cpu, gpu.") endif() if(NOT add_rr_MPI_SIZE) @@ -121,30 +121,30 @@ function(ginkgo_add_test test_name test_target_name) set_target_properties(${test_target_name} PROPERTIES OUTPUT_NAME ${test_name}) if (add_test_MPI_SIZE) add_test(NAME ${REL_BINARY_DIR}/${test_name} - COMMAND - ${MPIEXEC_EXECUTABLE} - ${MPIEXEC_NUMPROC_FLAG} - ${add_test_MPI_SIZE} - "$" - WORKING_DIRECTORY "$") - else () + COMMAND + ${MPIEXEC_EXECUTABLE} + ${MPIEXEC_NUMPROC_FLAG} + ${add_test_MPI_SIZE} + "$" + WORKING_DIRECTORY "$") + else() add_test(NAME ${REL_BINARY_DIR}/${test_name} - COMMAND ${test_target_name} - WORKING_DIRECTORY "$") - endif () + COMMAND ${test_target_name} + WORKING_DIRECTORY "$") + endif() ginkgo_add_resource_requirement(${REL_BINARY_DIR}/${test_name} ${ARGN}) set(test_preload) if (GINKGO_TEST_NONDEFAULT_STREAM AND GINKGO_BUILD_CUDA) set(test_preload $:${test_preload}) - endif () + endif() if (GINKGO_TEST_NONDEFAULT_STREAM AND GINKGO_BUILD_HIP AND GINKGO_HIP_PLATFORM MATCHES "${HIP_PLATFORM_AMD_REGEX}") set(test_preload $:${test_preload}) - endif () - if (test_preload) + endif() + if(test_preload) set_tests_properties(${REL_BINARY_DIR}/${test_name} PROPERTIES ENVIRONMENT LD_PRELOAD=${test_preload}) - endif () + endif() endfunction() ## Normal test @@ -153,7 +153,7 @@ function(ginkgo_create_test test_name) add_executable(${test_target_name} ${test_name}.cpp) target_link_libraries(${test_target_name}) ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) - ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} TYPE ref) + ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} RESOURCE_TYPE ref) endfunction(ginkgo_create_test) ## Test compiled with dpcpp @@ -164,11 +164,11 @@ function(ginkgo_create_dpcpp_test test_name) target_compile_options(${test_target_name} PRIVATE ${GINKGO_DPCPP_FLAGS}) target_link_options(${test_target_name} PRIVATE -fsycl-device-code-split=per_kernel) ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) - ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} TYPE gpu) + ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} RESOURCE_TYPE gpu) # Note: MKL_ENV is empty on linux. Maybe need to apply MKL_ENV to all test. if (MKL_ENV) set_tests_properties(${test_target_name} PROPERTIES ENVIRONMENT "${MKL_ENV}") - endif () + endif() endfunction(ginkgo_create_dpcpp_test) ## Test compiled with CUDA @@ -182,23 +182,23 @@ function(ginkgo_create_cuda_test_internal test_name filename test_target_name) add_executable(${test_target_name} ${filename}) target_compile_definitions(${test_target_name} PRIVATE GKO_COMPILING_CUDA) target_compile_options(${test_target_name} - PRIVATE + PRIVATE $<$:${GINKGO_CUDA_COMPILER_FLAGS}>) - if (MSVC) + if(MSVC) target_compile_options(${test_target_name} - PRIVATE + PRIVATE $<$:--extended-lambda --expt-relaxed-constexpr>) - elseif (CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") + elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") target_compile_options(${test_target_name} - PRIVATE + PRIVATE $<$:--expt-extended-lambda --expt-relaxed-constexpr>) - endif () + endif() # we handle CUDA architecture flags for now, disable CMake handling - if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.18) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.18) set_target_properties(${test_target_name} PROPERTIES CUDA_ARCHITECTURES OFF) - endif () + endif() ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) - ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} TYPE gpu) + ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} RESOURCE_TYPE gpu) endfunction(ginkgo_create_cuda_test_internal) ## Test compiled with HIP @@ -213,48 +213,48 @@ function(ginkgo_create_hip_test_internal test_name filename test_target_name add set(GINKGO_TEST_HIP_DEFINES -DGKO_COMPILING_HIP ${additional_flags}) if (GINKGO_FAST_TESTS) list(APPEND GINKGO_TEST_HIP_DEFINES -DGINKGO_FAST_TESTS) - endif () + endif() if (GINKGO_TEST_NONDEFAULT_STREAM) list(APPEND GINKGO_TEST_HIP_DEFINES -DGKO_TEST_NONDEFAULT_STREAM) - endif () + endif() # NOTE: With how HIP works, passing the flags `HIPCC_OPTIONS` etc. here # creates a redefinition of all flags. This creates some issues with `nvcc`, # but `clang` seems fine with the redefinitions. if (GINKGO_HIP_PLATFORM MATCHES "${HIP_PLATFORM_NVIDIA_REGEX}") hip_add_executable(${test_target_name} ${filename} - # If `FindHIP.cmake`, namely `HIP_PARSE_HIPCC_OPTIONS` macro and - # call gets fixed, uncomment this. - HIPCC_OPTIONS ${GINKGO_TEST_HIP_DEFINES} # ${GINKGO_HIPCC_OPTIONS} - # NVCC_OPTIONS ${GINKGO_TEST_HIP_DEFINES} ${GINKGO_HIP_NVCC_OPTIONS} - # CLANG_OPTIONS ${GINKGO_TEST_HIP_DEFINES} ${GINKGO_HIP_CLANG_OPTIONS} - --expt-relaxed-constexpr --expt-extended-lambda - ) - else () # hcc/clang + # If `FindHIP.cmake`, namely `HIP_PARSE_HIPCC_OPTIONS` macro and + # call gets fixed, uncomment this. + HIPCC_OPTIONS ${GINKGO_TEST_HIP_DEFINES} # ${GINKGO_HIPCC_OPTIONS} + # NVCC_OPTIONS ${GINKGO_TEST_HIP_DEFINES} ${GINKGO_HIP_NVCC_OPTIONS} + # CLANG_OPTIONS ${GINKGO_TEST_HIP_DEFINES} ${GINKGO_HIP_CLANG_OPTIONS} + --expt-relaxed-constexpr --expt-extended-lambda + ) + else() # hcc/clang hip_add_executable(${test_target_name} ${filename} - HIPCC_OPTIONS ${GINKGO_HIPCC_OPTIONS} ${GINKGO_TEST_HIP_DEFINES} - NVCC_OPTIONS ${GINKGO_HIP_NVCC_OPTIONS} - CLANG_OPTIONS ${GINKGO_HIP_CLANG_OPTIONS} - ) - endif () + HIPCC_OPTIONS ${GINKGO_HIPCC_OPTIONS} ${GINKGO_TEST_HIP_DEFINES} + NVCC_OPTIONS ${GINKGO_HIP_NVCC_OPTIONS} + CLANG_OPTIONS ${GINKGO_HIP_CLANG_OPTIONS} + ) + endif() # Let's use a normal compiler for linking set_target_properties(${test_target_name} PROPERTIES LINKER_LANGUAGE CXX) target_include_directories(${test_target_name} - PRIVATE - # Only `math` requires it so far, but it's much easier - # to put these this way. - ${GINKGO_HIP_THRUST_PATH} - # Only `exception_helpers` requires these so far, but it's much easier - # to put these this way. - ${HIPBLAS_INCLUDE_DIRS} - ${HIPFFT_INCLUDE_DIRS} - ${hiprand_INCLUDE_DIRS} - ${HIPSPARSE_INCLUDE_DIRS} - ) + PRIVATE + # Only `math` requires it so far, but it's much easier + # to put these this way. + ${GINKGO_HIP_THRUST_PATH} + # Only `exception_helpers` requires these so far, but it's much easier + # to put these this way. + ${HIPBLAS_INCLUDE_DIRS} + ${HIPFFT_INCLUDE_DIRS} + ${hiprand_INCLUDE_DIRS} + ${HIPSPARSE_INCLUDE_DIRS} + ) ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) - ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} TYPE gpu) + ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} RESOURCE_TYPE gpu) endfunction(ginkgo_create_hip_test_internal) @@ -270,30 +270,30 @@ function(ginkgo_create_omp_test_internal test_name filename test_target_name) target_compile_definitions(${test_target_name} PRIVATE GKO_COMPILING_OMP) target_link_libraries(${test_target_name} PRIVATE OpenMP::OpenMP_CXX) ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) - ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} TYPE cpu) + ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} RESOURCE_TYPE cpu) endfunction() ## Common test compiled with the host compiler, one target for each enabled backend function(ginkgo_create_common_test test_name) - if (GINKGO_BUILD_OMP) + if(GINKGO_BUILD_OMP) ginkgo_create_common_test_internal(${test_name} OmpExecutor omp ${ARGN}) - endif () - if (GINKGO_BUILD_HIP) + endif() + if(GINKGO_BUILD_HIP) ginkgo_create_common_test_internal(${test_name} HipExecutor hip ${ARGN}) - endif () - if (GINKGO_BUILD_CUDA) + endif() + if(GINKGO_BUILD_CUDA) ginkgo_create_common_test_internal(${test_name} CudaExecutor cuda ${ARGN}) - endif () - if (GINKGO_BUILD_DPCPP) + endif() + if(GINKGO_BUILD_DPCPP) ginkgo_create_common_test_internal(${test_name} DpcppExecutor dpcpp ${ARGN}) - endif () + endif() endfunction(ginkgo_create_common_test) function(ginkgo_create_common_test_internal test_name exec_type exec) cmake_parse_arguments(PARSE_ARGV 3 common_test "" "${gko_test_single_args}" "${gko_test_multi_args}") - if (exec IN_LIST common_test_DISABLE_EXECUTORS) + if(exec IN_LIST common_test_DISABLE_EXECUTORS) return() - endif () + endif() if (exec STREQUAL reference) set(test_resource_type ref) elseif (exec STREQUAL omp) @@ -303,45 +303,52 @@ function(ginkgo_create_common_test_internal test_name exec_type exec) endif () ginkgo_build_test_name(${test_name} test_target_name) string(TOUPPER ${exec} exec_upper) + # set up actual test set(test_target_name ${test_target_name}_${exec}) add_executable(${test_target_name} ${test_name}.cpp) + + # also need to add runtime libraries for other backends + if (exec STREQUAL omp) + target_link_libraries(${test_target_name} PRIVATE OpenMP::OpenMP_CXX) + endif () + target_compile_definitions(${test_target_name} PRIVATE EXEC_TYPE=${exec_type} EXEC_NAMESPACE=${exec} GKO_COMPILING_${exec_upper}) target_link_libraries(${test_target_name} PRIVATE ${common_test_ADDITIONAL_LIBRARIES}) # use float for DPC++ if necessary - if ((exec STREQUAL "dpcpp") AND GINKGO_DPCPP_SINGLE_MODE) + if((exec STREQUAL "dpcpp") AND GINKGO_DPCPP_SINGLE_MODE) target_compile_definitions(${test_target_name} PRIVATE GINKGO_COMMON_SINGLE_MODE=1) target_compile_definitions(${test_target_name} PRIVATE GINKGO_DPCPP_SINGLE_MODE=1) - endif () + endif() ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) - ginkgo_add_test(${test_name}_${exec} ${test_target_name} ${ARGN} TYPE ${test_resource_type}) + ginkgo_add_test(${test_name}_${exec} ${test_target_name} ${ARGN} RESOURCE_TYPE ${test_resource_type}) endfunction(ginkgo_create_common_test_internal) ## Common test compiled with the device compiler, one target for each enabled backend function(ginkgo_create_common_device_test test_name) cmake_parse_arguments(PARSE_ARGV 1 common_device_test "" "${gko_test_single_args}" "${gko_test_multi_args}") ginkgo_build_test_name(${test_name} test_target_name) - if (GINKGO_BUILD_DPCPP) + if(GINKGO_BUILD_DPCPP) ginkgo_create_common_test_internal(${test_name} DpcppExecutor dpcpp ${ARGN}) target_compile_features(${test_target_name}_dpcpp PRIVATE cxx_std_17) target_compile_options(${test_target_name}_dpcpp PRIVATE ${GINKGO_DPCPP_FLAGS}) target_link_options(${test_target_name}_dpcpp PRIVATE -fsycl-device-lib=all -fsycl-device-code-split=per_kernel) - endif () - if (GINKGO_BUILD_OMP) + endif() + if(GINKGO_BUILD_OMP) ginkgo_create_common_test_internal(${test_name} OmpExecutor omp ${ARGN}) target_link_libraries(${test_target_name}_omp PUBLIC OpenMP::OpenMP_CXX) - endif () - if (GINKGO_BUILD_CUDA) + endif() + if(GINKGO_BUILD_CUDA) # need to make a separate file for this, since we can't set conflicting properties on the same file configure_file(${test_name}.cpp ${test_name}.cu COPYONLY) ginkgo_create_cuda_test_internal(${test_name}_cuda ${CMAKE_CURRENT_BINARY_DIR}/${test_name}.cu ${test_target_name}_cuda ${ARGN}) target_compile_definitions(${test_target_name}_cuda PRIVATE EXEC_TYPE=CudaExecutor EXEC_NAMESPACE=cuda) - endif () - if (GINKGO_BUILD_HIP) + endif() + if(GINKGO_BUILD_HIP) # need to make a separate file for this, since we can't set conflicting properties on the same file configure_file(${test_name}.cpp ${test_name}.hip.cpp COPYONLY) ginkgo_create_hip_test_internal(${test_name}_hip ${CMAKE_CURRENT_BINARY_DIR}/${test_name}.hip.cpp ${test_target_name}_hip "-std=c++14;-DEXEC_TYPE=HipExecutor;-DEXEC_NAMESPACE=hip" ${ARGN}) - endif () + endif() endfunction(ginkgo_create_common_device_test) ## Common test compiled with the host compiler for all enabled backends and Reference From 5bf2034ad6fc21a8858c2843f5b58fd07a8122a8 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Thu, 20 Jul 2023 14:37:54 +0200 Subject: [PATCH 07/44] simplify parsing --- core/test/gtest/environments.hpp | 48 ++++++++++---------------------- 1 file changed, 14 insertions(+), 34 deletions(-) diff --git a/core/test/gtest/environments.hpp b/core/test/gtest/environments.hpp index 3f93ea95b8a..4cfb2a89959 100644 --- a/core/test/gtest/environments.hpp +++ b/core/test/gtest/environments.hpp @@ -8,24 +8,13 @@ #include -std::vector split(const std::string& s, char delimiter = ',') -{ - std::istringstream iss(s); - std::vector tokens; - std::string token; - while (std::getline(iss, token, delimiter)) { - tokens.push_back(token); - } - return tokens; -} - - struct resource { int id; int slots; }; -resource parse_single_resource(const std::string& resource_string) + +inline resource parse_single_resource(const std::string& resource_string) { std::regex re(R"(id\:(\d+),slots\:(\d+))"); std::smatch match; @@ -37,19 +26,8 @@ resource parse_single_resource(const std::string& resource_string) return resource{std::stoi(match[1]), std::stoi(match[2])}; } -std::vector parse_all_resources(const std::string& resource_string) -{ - auto resource_strings = split(resource_string, ';'); - - std::vector resources; - for (const auto& rs : resource_strings) { - resources.push_back(parse_single_resource(rs)); - } - return resources; -} - -std::vector get_ctest_resources() +inline std::vector get_ctest_resources() { auto rs_count_env = std::getenv("CTEST_RESOURCE_GROUP_COUNT"); @@ -59,17 +37,19 @@ std::vector get_ctest_resources() auto rs_count = std::stoi(rs_count_env); - if (rs_count > 1) { - GKO_INVALID_STATE("Can handle only one resource group."); + std::vector resources; + + for (int i = 0; i < rs_count; ++i) { + std::string rs_group_env = "CTEST_RESOURCE_GROUP_" + std::to_string(i); + std::string rs_type = std::getenv(rs_group_env.c_str()); + std::transform(rs_type.begin(), rs_type.end(), rs_type.begin(), + [](auto c) { return std::toupper(c); }); + std::string rs_env = + std::getenv((rs_group_env + "_" + rs_type).c_str()); + resources.push_back(parse_single_resource(rs_env)); } - std::string rs_type = std::getenv("CTEST_RESOURCE_GROUP_0"); - std::transform(rs_type.begin(), rs_type.end(), rs_type.begin(), - [](auto c) { return std::toupper(c); }); - std::string rs_env = - std::getenv(std::string("CTEST_RESOURCE_GROUP_0_" + rs_type).c_str()); - std::cerr << rs_env << std::endl; - return parse_all_resources(rs_env); + return resources; } From e2f6496f9fcaac3180eaed1bbd886407ecf2a9c3 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Thu, 20 Jul 2023 14:38:13 +0200 Subject: [PATCH 08/44] use ginkgo_create_omp_test --- omp/test/base/CMakeLists.txt | 6 ++---- omp/test/matrix/CMakeLists.txt | 2 +- omp/test/reorder/CMakeLists.txt | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/omp/test/base/CMakeLists.txt b/omp/test/base/CMakeLists.txt index 4c511b6def7..cfd00fe28cf 100644 --- a/omp/test/base/CMakeLists.txt +++ b/omp/test/base/CMakeLists.txt @@ -1,4 +1,2 @@ -ginkgo_create_test(kernel_launch) -target_compile_definitions(omp_test_base_kernel_launch PRIVATE GKO_COMPILING_OMP) -target_link_libraries(omp_test_base_kernel_launch PRIVATE OpenMP::OpenMP_CXX) -ginkgo_create_test(index_set) +ginkgo_create_omp_test(kernel_launch) +ginkgo_create_omp_test(index_set) diff --git a/omp/test/matrix/CMakeLists.txt b/omp/test/matrix/CMakeLists.txt index 88ab52e9c3f..398921ce75a 100644 --- a/omp/test/matrix/CMakeLists.txt +++ b/omp/test/matrix/CMakeLists.txt @@ -1 +1 @@ -ginkgo_create_test(fbcsr_kernels) +ginkgo_create_omp_test(fbcsr_kernels) diff --git a/omp/test/reorder/CMakeLists.txt b/omp/test/reorder/CMakeLists.txt index 8987ae28a48..089e51c67c9 100644 --- a/omp/test/reorder/CMakeLists.txt +++ b/omp/test/reorder/CMakeLists.txt @@ -1 +1 @@ -ginkgo_create_test(rcm_kernels) +ginkgo_create_omp_test(rcm_kernels) From aa144ea6f2bd9eeb7bf4458a3068f4863c92c157 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Mon, 24 Jul 2023 11:53:44 +0200 Subject: [PATCH 09/44] use custom stream by default otherwise, the default stream is used in some places, e.g. initializing cublas. But it is not clear with which device the default stream is associated. Thus, this now sets the device id correctly for the new stream --- test/utils/executor.hpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/test/utils/executor.hpp b/test/utils/executor.hpp index ad4621d5c31..7afd2b0e4d9 100644 --- a/test/utils/executor.hpp +++ b/test/utils/executor.hpp @@ -124,14 +124,12 @@ class CommonTestFixture : public ::testing::Test { CommonTestFixture() : -#if defined(GKO_TEST_NONDEFAULT_STREAM) && \ - (defined(GKO_COMPILING_CUDA) || defined(GKO_COMPILING_HIP)) +#if defined(GKO_COMPILING_CUDA) || defined(GKO_COMPILING_HIP) stream(ResourceEnvironment::rs.id), #endif ref{gko::ReferenceExecutor::create()} { -#if defined(GKO_TEST_NONDEFAULT_STREAM) && \ - (defined(GKO_COMPILING_CUDA) || defined(GKO_COMPILING_HIP)) +#if defined(GKO_COMPILING_CUDA) || defined(GKO_COMPILING_HIP) init_executor(ref, exec, stream.get()); #else init_executor(ref, exec); @@ -145,13 +143,11 @@ class CommonTestFixture : public ::testing::Test { } } -#ifdef GKO_TEST_NONDEFAULT_STREAM #ifdef GKO_COMPILING_CUDA gko::cuda_stream stream; #endif #ifdef GKO_COMPILING_HIP gko::hip_stream stream; -#endif #endif std::shared_ptr ref; std::shared_ptr exec; From 907b35948ae50c9ebb7858fd5aed5c88cb3a060c Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Mon, 24 Jul 2023 13:33:30 +0200 Subject: [PATCH 10/44] set device-id for each test this is necessary, since some test call the kernels directly and not through the executor. In this case, the setting of the device id by the executor is skipped, which leads to these kernel not run. --- cuda/test/utils.hpp | 16 +++++++--------- hip/test/utils.hip.hpp | 16 +++++++--------- test/utils/executor.hpp | 2 ++ test/utils/mpi/executor.hpp | 11 ++++------- 4 files changed, 20 insertions(+), 25 deletions(-) diff --git a/cuda/test/utils.hpp b/cuda/test/utils.hpp index 58d310024bd..f35cb8d4c12 100644 --- a/cuda/test/utils.hpp +++ b/cuda/test/utils.hpp @@ -41,6 +41,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +#include "core/test/gtest/environments.hpp" #include "cuda/base/device.hpp" @@ -51,13 +52,11 @@ class CudaTestFixture : public ::testing::Test { protected: CudaTestFixture() : ref(gko::ReferenceExecutor::create()), -#ifdef GKO_TEST_NONDEFAULT_STREAM - stream(0), - exec(gko::CudaExecutor::create( - 0, ref, std::make_shared(), stream.get())) -#else - exec(gko::CudaExecutor::create(0, ref)) -#endif + stream(ResourceEnvironment::rs.id), + exec(gko::CudaExecutor::create(ResourceEnvironment::rs.id, ref, std::make_shared< + gko::CudaAllocator>(), + stream.get())), + guard(exec->get_scoped_device_id_guard()) {} void TearDown() @@ -68,11 +67,10 @@ class CudaTestFixture : public ::testing::Test { } } -#ifdef GKO_TEST_NONDEFAULT_STREAM gko::cuda_stream stream; -#endif std::shared_ptr ref; std::shared_ptr exec; + gko::scoped_device_id_guard guard; }; diff --git a/hip/test/utils.hip.hpp b/hip/test/utils.hip.hpp index dcecc8d2522..1c57467b451 100644 --- a/hip/test/utils.hip.hpp +++ b/hip/test/utils.hip.hpp @@ -41,6 +41,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +#include "core/test/gtest/environments.hpp" #include "hip/base/device.hpp" @@ -51,13 +52,11 @@ class HipTestFixture : public ::testing::Test { protected: HipTestFixture() : ref(gko::ReferenceExecutor::create()), -#ifdef GKO_TEST_NONDEFAULT_STREAM - stream(0), - exec(gko::HipExecutor::create( - 0, ref, std::make_shared(), stream.get())) -#else - exec(gko::HipExecutor::create(0, ref)) -#endif + stream(ResourceEnvironment::rs.id), + exec(gko::HipExecutor::create(ResourceEnvironment::rs.id, ref, std::make_shared< + gko::HipAllocator>(), + stream.get())), + guard(exec->get_scoped_device_id_guard()) {} void TearDown() @@ -68,11 +67,10 @@ class HipTestFixture : public ::testing::Test { } } -#ifdef GKO_TEST_NONDEFAULT_STREAM gko::hip_stream stream; -#endif std::shared_ptr ref; std::shared_ptr exec; + gko::scoped_device_id_guard guard; }; diff --git a/test/utils/executor.hpp b/test/utils/executor.hpp index 7afd2b0e4d9..d52b8083ac8 100644 --- a/test/utils/executor.hpp +++ b/test/utils/executor.hpp @@ -134,6 +134,7 @@ class CommonTestFixture : public ::testing::Test { #else init_executor(ref, exec); #endif + guard = exec->get_scoped_device_id_guard(); } void TearDown() final @@ -151,6 +152,7 @@ class CommonTestFixture : public ::testing::Test { #endif std::shared_ptr ref; std::shared_ptr exec; + gko::scoped_device_id_guard guard; }; diff --git a/test/utils/mpi/executor.hpp b/test/utils/mpi/executor.hpp index 4eba5593c90..f317f60eb35 100644 --- a/test/utils/mpi/executor.hpp +++ b/test/utils/mpi/executor.hpp @@ -58,18 +58,17 @@ class CommonMpiTestFixture : public ::testing::Test { CommonMpiTestFixture() : comm(MPI_COMM_WORLD), -#if defined(GKO_TEST_NONDEFAULT_STREAM) && \ - (defined(GKO_COMPILING_CUDA) || defined(GKO_COMPILING_HIP)) +#if defined(GKO_COMPILING_CUDA) || defined(GKO_COMPILING_HIP) stream(ResourceEnvironment::rs.id), #endif ref{gko::ReferenceExecutor::create()} { -#if defined(GKO_TEST_NONDEFAULT_STREAM) && \ - (defined(GKO_COMPILING_CUDA) || defined(GKO_COMPILING_HIP)) +#if defined(GKO_COMPILING_CUDA) || defined(GKO_COMPILING_HIP) init_executor(ref, exec, stream.get()); #else init_executor(ref, exec); #endif + guard = exec->get_scoped_device_id_guard(); } void TearDown() final @@ -81,17 +80,15 @@ class CommonMpiTestFixture : public ::testing::Test { gko::experimental::mpi::communicator comm; -#ifdef GKO_TEST_NONDEFAULT_STREAM #ifdef GKO_COMPILING_CUDA gko::cuda_stream stream; #endif #ifdef GKO_COMPILING_HIP gko::hip_stream stream; #endif -#endif - std::shared_ptr ref; std::shared_ptr exec; + gko::scoped_device_id_guard guard; }; From 8174beb5e18009976c4d244fcd6f8ad9b00bea7d Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Mon, 24 Jul 2023 13:33:49 +0200 Subject: [PATCH 11/44] add ctest resource settings to logging output --- core/test/gtest/environments.hpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/core/test/gtest/environments.hpp b/core/test/gtest/environments.hpp index 4cfb2a89959..a7aedbc102c 100644 --- a/core/test/gtest/environments.hpp +++ b/core/test/gtest/environments.hpp @@ -30,6 +30,7 @@ inline resource parse_single_resource(const std::string& resource_string) inline std::vector get_ctest_resources() { auto rs_count_env = std::getenv("CTEST_RESOURCE_GROUP_COUNT"); + std::cerr << "CTEST_RESOURCE_GROUP_COUNT=" << rs_count_env << std::endl; if (!rs_count_env) { return {{0, 1}}; @@ -42,10 +43,14 @@ inline std::vector get_ctest_resources() for (int i = 0; i < rs_count; ++i) { std::string rs_group_env = "CTEST_RESOURCE_GROUP_" + std::to_string(i); std::string rs_type = std::getenv(rs_group_env.c_str()); + std::cerr << rs_group_env << "=" << rs_type << std::endl; + std::transform(rs_type.begin(), rs_type.end(), rs_type.begin(), [](auto c) { return std::toupper(c); }); - std::string rs_env = - std::getenv((rs_group_env + "_" + rs_type).c_str()); + std::string rs_current_group = rs_group_env + "_" + rs_type; + std::string rs_env = std::getenv(rs_current_group.c_str()); + std::cerr << rs_current_group << "=" << rs_env << std::endl; + resources.push_back(parse_single_resource(rs_env)); } From 6870df167f7eb017bc9124280835c7483fbadf5e Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Mon, 24 Jul 2023 14:37:33 +0200 Subject: [PATCH 12/44] fixes schwarz preconditioner test --- test/mpi/preconditioner/schwarz.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/mpi/preconditioner/schwarz.cpp b/test/mpi/preconditioner/schwarz.cpp index 8586711a114..3c9e3a8d69f 100644 --- a/test/mpi/preconditioner/schwarz.cpp +++ b/test/mpi/preconditioner/schwarz.cpp @@ -101,14 +101,14 @@ class SchwarzPreconditioner : public CommonMpiTestFixture { SchwarzPreconditioner() - : size{8, 8}, mat_input{size, {{0, 0, 2}, {0, 1, -1}, {1, 0, -1}, - {1, 1, 2}, {1, 2, -1}, {2, 1, -1}, - {2, 2, 2}, {2, 3, -1}, {3, 2, -1}, - {3, 3, 2}, {3, 4, -1}, {4, 3, -1}, - {4, 4, 2}, {4, 5, -1}, {5, 4, -1}, - {5, 5, 2}, {5, 6, -1}, {6, 5, -1}, - {6, 6, 2}, {6, 7, -1}, {7, 6, -1}, - {7, 7, 2}}} + : CommonMpiTestFixture(), + size{8, 8}, + mat_input{size, + {{0, 0, 2}, {0, 1, -1}, {1, 0, -1}, {1, 1, 2}, {1, 2, -1}, + {2, 1, -1}, {2, 2, 2}, {2, 3, -1}, {3, 2, -1}, {3, 3, 2}, + {3, 4, -1}, {4, 3, -1}, {4, 4, 2}, {4, 5, -1}, {5, 4, -1}, + {5, 5, 2}, {5, 6, -1}, {6, 5, -1}, {6, 6, 2}, {6, 7, -1}, + {7, 6, -1}, {7, 7, 2}}} { row_part = Partition::build_from_contiguous( exec, gko::array( From 8df1afd8c304a08f1a908ceeb2f8d9ce086c6211 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Mon, 24 Jul 2023 14:38:11 +0200 Subject: [PATCH 13/44] use ginkgo_create_cuda_test consistently --- cuda/test/base/CMakeLists.txt | 6 +++--- cuda/test/base/{index_set.cpp => index_set.cu} | 0 cuda/test/base/{memory.cpp => memory.cu} | 0 cuda/test/reorder/CMakeLists.txt | 2 +- cuda/test/reorder/{rcm_kernels.cpp => rcm_kernels.cu} | 0 cuda/test/utils/CMakeLists.txt | 2 +- cuda/test/utils/{assertions_test.cpp => assertions_test.cu} | 0 7 files changed, 5 insertions(+), 5 deletions(-) rename cuda/test/base/{index_set.cpp => index_set.cu} (100%) rename cuda/test/base/{memory.cpp => memory.cu} (100%) rename cuda/test/reorder/{rcm_kernels.cpp => rcm_kernels.cu} (100%) rename cuda/test/utils/{assertions_test.cpp => assertions_test.cu} (100%) diff --git a/cuda/test/base/CMakeLists.txt b/cuda/test/base/CMakeLists.txt index a213e65277a..f78e6e653fe 100644 --- a/cuda/test/base/CMakeLists.txt +++ b/cuda/test/base/CMakeLists.txt @@ -1,13 +1,13 @@ ginkgo_create_cuda_test(array) ginkgo_create_cuda_test(cuda_executor) -ginkgo_create_test(index_set) +ginkgo_create_cuda_test(index_set) if(GINKGO_HAVE_HWLOC) find_package(NUMA REQUIRED) ginkgo_create_cuda_test(cuda_executor_topology ADDITIONAL_LIBRARIES NUMA::NUMA) -endif() +endif () ginkgo_create_cuda_test(exception_helpers) ginkgo_create_cuda_test(kernel_launch) ginkgo_create_cuda_test(lin_op) ginkgo_create_cuda_test(math) -ginkgo_create_test(memory) +ginkgo_create_cuda_test(memory) ginkgo_create_cuda_test(scoped_device_id) diff --git a/cuda/test/base/index_set.cpp b/cuda/test/base/index_set.cu similarity index 100% rename from cuda/test/base/index_set.cpp rename to cuda/test/base/index_set.cu diff --git a/cuda/test/base/memory.cpp b/cuda/test/base/memory.cu similarity index 100% rename from cuda/test/base/memory.cpp rename to cuda/test/base/memory.cu diff --git a/cuda/test/reorder/CMakeLists.txt b/cuda/test/reorder/CMakeLists.txt index 108e3b57dd5..e6cd8c0f5d2 100644 --- a/cuda/test/reorder/CMakeLists.txt +++ b/cuda/test/reorder/CMakeLists.txt @@ -1 +1 @@ -ginkgo_create_test(rcm_kernels) \ No newline at end of file +ginkgo_create_cuda_test(rcm_kernels) diff --git a/cuda/test/reorder/rcm_kernels.cpp b/cuda/test/reorder/rcm_kernels.cu similarity index 100% rename from cuda/test/reorder/rcm_kernels.cpp rename to cuda/test/reorder/rcm_kernels.cu diff --git a/cuda/test/utils/CMakeLists.txt b/cuda/test/utils/CMakeLists.txt index 06dffda5da0..28f5770856f 100644 --- a/cuda/test/utils/CMakeLists.txt +++ b/cuda/test/utils/CMakeLists.txt @@ -1 +1 @@ -ginkgo_create_test(assertions_test) +ginkgo_create_cuda_test(assertions_test) diff --git a/cuda/test/utils/assertions_test.cpp b/cuda/test/utils/assertions_test.cu similarity index 100% rename from cuda/test/utils/assertions_test.cpp rename to cuda/test/utils/assertions_test.cu From b991e1a5752c1b124d71a269de044ce864ee5c1b Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Mon, 24 Jul 2023 14:43:24 +0200 Subject: [PATCH 14/44] without resources, return the default number of omp threads --- core/test/gtest/environments.hpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/core/test/gtest/environments.hpp b/core/test/gtest/environments.hpp index a7aedbc102c..4434185a4e0 100644 --- a/core/test/gtest/environments.hpp +++ b/core/test/gtest/environments.hpp @@ -33,7 +33,17 @@ inline std::vector get_ctest_resources() std::cerr << "CTEST_RESOURCE_GROUP_COUNT=" << rs_count_env << std::endl; if (!rs_count_env) { +#ifdef GKO_COMPILING_OMP + resource rs{}; +#pragma omp parallel +#pragma omp single + { + rs = resource{0, omp_get_num_threads()}; + } + return {rs}; +#else return {{0, 1}}; +#endif } auto rs_count = std::stoi(rs_count_env); From da69ea61d6b8bf8457018b4ed8356eb78a8ea892 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Mon, 24 Jul 2023 15:22:15 +0200 Subject: [PATCH 15/44] fix check for no resources --- core/test/gtest/environments.hpp | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/core/test/gtest/environments.hpp b/core/test/gtest/environments.hpp index 4434185a4e0..a678ce00ffd 100644 --- a/core/test/gtest/environments.hpp +++ b/core/test/gtest/environments.hpp @@ -5,6 +5,21 @@ #include +#ifdef GKO_COMPILING_OMP +#include +#endif + + +#ifdef GKO_COMPILING_CUDA +#include "cuda/base/device.hpp" +#endif + + +#ifdef GKO_COMPILING_HIP +#include "hip/base/device.hpp" +#endif + + #include @@ -32,7 +47,9 @@ inline std::vector get_ctest_resources() auto rs_count_env = std::getenv("CTEST_RESOURCE_GROUP_COUNT"); std::cerr << "CTEST_RESOURCE_GROUP_COUNT=" << rs_count_env << std::endl; - if (!rs_count_env) { + auto rs_count = rs_count_env ? std::stoi(rs_count_env) : 0; + + if (rs_count == 0) { #ifdef GKO_COMPILING_OMP resource rs{}; #pragma omp parallel @@ -46,8 +63,6 @@ inline std::vector get_ctest_resources() #endif } - auto rs_count = std::stoi(rs_count_env); - std::vector resources; for (int i = 0; i < rs_count; ++i) { @@ -81,8 +96,6 @@ class ResourceEnvironment : public ::testing::Environment { #ifdef GKO_COMPILING_OMP -#include - class OmpEnvironment : public ::testing::Environment { public: void SetUp() override @@ -101,8 +114,6 @@ class OmpEnvironment : public ::testing::Environment {}; #ifdef GKO_COMPILING_CUDA -#include "cuda/base/device.hpp" - class CudaEnvironment : public ::testing::Environment { public: void TearDown() override @@ -120,8 +131,6 @@ class CudaEnvironment : public ::testing::Environment {}; #ifdef GKO_COMPILING_HIP -#include "hip/base/device.hpp" - class HipEnvironment : public ::testing::Environment { public: void TearDown() override From 45e9db4d7a783298244bdfb8e011ade5214e1302 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Mon, 24 Jul 2023 15:23:57 +0200 Subject: [PATCH 16/44] fix cmake resource parameters --- cmake/create_test.cmake | 2 +- cuda/test/base/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/create_test.cmake b/cmake/create_test.cmake index 6ce37976f84..34e27529e08 100644 --- a/cmake/create_test.cmake +++ b/cmake/create_test.cmake @@ -1,4 +1,4 @@ -set(gko_test_resource_args "RESOURCE_LOCAL_CORES;RESOURCE_PERCENT;RESOURCE_TYPE") +set(gko_test_resource_args "RESOURCE_LOCAL_CORES;RESOURCE_PERCENTAGE;RESOURCE_TYPE") set(gko_test_single_args "MPI_SIZE;${gko_test_resource_args}") set(gko_test_multi_args "DISABLE_EXECUTORS;ADDITIONAL_LIBRARIES;ADDITIONAL_INCLUDES") set(gko_test_option_args "NO_RESOURCES") diff --git a/cuda/test/base/CMakeLists.txt b/cuda/test/base/CMakeLists.txt index f78e6e653fe..bb99ba858a4 100644 --- a/cuda/test/base/CMakeLists.txt +++ b/cuda/test/base/CMakeLists.txt @@ -10,4 +10,4 @@ ginkgo_create_cuda_test(kernel_launch) ginkgo_create_cuda_test(lin_op) ginkgo_create_cuda_test(math) ginkgo_create_cuda_test(memory) -ginkgo_create_cuda_test(scoped_device_id) +ginkgo_create_cuda_test(scoped_device_id NO_RESOURCES) From 514599d0b14fa387bd8136111dce29597ad5fa65 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Mon, 24 Jul 2023 16:06:20 +0200 Subject: [PATCH 17/44] allow 4 concurrent GPU tests --- cmake/create_test.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/create_test.cmake b/cmake/create_test.cmake index 34e27529e08..76330a26627 100644 --- a/cmake/create_test.cmake +++ b/cmake/create_test.cmake @@ -82,7 +82,7 @@ function(ginkgo_add_resource_requirement test_name) set(single_resource "cpus:${add_rr_RESOURCE_LOCAL_CORES}") elseif(add_rr_RESOURCE_TYPE STREQUAL "gpu") if(NOT add_rr_RESOURCE_PERCENTAGE) - set(add_rr_RESOURCE_PERCENTAGE 50) + set(add_rr_RESOURCE_PERCENTAGE 25) endif() if(add_rr_MPI_SIZE GREATER 1) set(add_rr_RESOURCE_PERCENTAGE 100) From b326ee70d5b7f216efa8e199301379161e8db548 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Mon, 31 Jul 2023 11:08:10 +0200 Subject: [PATCH 18/44] use different resource type per executor Co-authored-by: Tobias Ribizel --- cmake/create_test.cmake | 24 +++-- core/test/gtest/environments.hpp | 139 ++++++++++++++++++---------- core/test/gtest/ginkgo_main.cpp | 12 ++- core/test/gtest/ginkgo_mpi_main.cpp | 13 ++- cuda/test/utils.hpp | 8 +- hip/test/utils.hip.hpp | 4 +- test/utils/executor.hpp | 19 ++-- test/utils/mpi/executor.hpp | 7 +- 8 files changed, 140 insertions(+), 86 deletions(-) diff --git a/cmake/create_test.cmake b/cmake/create_test.cmake index 76330a26627..1d3e041ff2a 100644 --- a/cmake/create_test.cmake +++ b/cmake/create_test.cmake @@ -70,17 +70,17 @@ function(ginkgo_add_resource_requirement test_name) endif () if(add_rr_RESOURCE_TYPE STREQUAL "ref") - set(single_resource "cpus:1") + set(single_resource "cpu:1") elseif(add_rr_RESOURCE_TYPE STREQUAL "cpu") if(NOT add_rr_RESOURCE_LOCAL_CORES) set(add_rr_RESOURCE_LOCAL_CORES 4) # perhaps get this from environment variable? endif() if(NOT add_rr_RESOURCE_LOCAL_CORES MATCHES "^[0-9]+") - message(FATAL_ERROR "Resource specification is invalid: RESOURCE_LOCAL_CORE=${add_rr_RESOURCE_LOCAL_CORES}") + message(FATAL_ERROR "Resource specification is invalid: RESOURCE_LOCAL_CORES=${add_rr_RESOURCE_LOCAL_CORES}") endif() - set(single_resource "cpus:${add_rr_RESOURCE_LOCAL_CORES}") - elseif(add_rr_RESOURCE_TYPE STREQUAL "gpu") + set(single_resource "cpu:${add_rr_RESOURCE_LOCAL_CORES}") + elseif(add_rr_RESOURCE_TYPE MATCHES "^(cuda|hip|sycl)gpu$") if(NOT add_rr_RESOURCE_PERCENTAGE) set(add_rr_RESOURCE_PERCENTAGE 25) endif() @@ -93,9 +93,9 @@ function(ginkgo_add_resource_requirement test_name) message(FATAL_ERROR "Resource specification is invalid: RESOURCE_PERCENTAGE=${add_rr_RESOURCE_PERCENTAGE}") endif() - set(single_resource "gpus:${add_rr_RESOURCE_PERCENTAGE}") + set(single_resource "${add_rr_RESOURCE_TYPE}:${add_rr_RESOURCE_PERCENTAGE}") else() - message(FATAL_ERROR "Unrecognized resource type ${add_rr_RESOURCE_TYPE}, allowed are: ref, cpu, gpu.") + message(FATAL_ERROR "Unrecognized resource type ${add_rr_RESOURCE_TYPE}, allowed are: ref, cpu, cudagpu, hipgpu, syclgpu.") endif() if(NOT add_rr_MPI_SIZE) @@ -164,7 +164,7 @@ function(ginkgo_create_dpcpp_test test_name) target_compile_options(${test_target_name} PRIVATE ${GINKGO_DPCPP_FLAGS}) target_link_options(${test_target_name} PRIVATE -fsycl-device-code-split=per_kernel) ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) - ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} RESOURCE_TYPE gpu) + ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} RESOURCE_TYPE syclgpu) # Note: MKL_ENV is empty on linux. Maybe need to apply MKL_ENV to all test. if (MKL_ENV) set_tests_properties(${test_target_name} PROPERTIES ENVIRONMENT "${MKL_ENV}") @@ -198,7 +198,7 @@ function(ginkgo_create_cuda_test_internal test_name filename test_target_name) set_target_properties(${test_target_name} PROPERTIES CUDA_ARCHITECTURES OFF) endif() ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) - ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} RESOURCE_TYPE gpu) + ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} RESOURCE_TYPE cudagpu) endfunction(ginkgo_create_cuda_test_internal) ## Test compiled with HIP @@ -254,7 +254,7 @@ function(ginkgo_create_hip_test_internal test_name filename test_target_name add ${HIPSPARSE_INCLUDE_DIRS} ) ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) - ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} RESOURCE_TYPE gpu) + ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} RESOURCE_TYPE hipgpu) endfunction(ginkgo_create_hip_test_internal) @@ -298,8 +298,12 @@ function(ginkgo_create_common_test_internal test_name exec_type exec) set(test_resource_type ref) elseif (exec STREQUAL omp) set(test_resource_type cpu) + elseif (exec STREQUAL cuda) + set(test_resource_type cudagpu) + elseif (exec STREQUAL hip) + set(test_resource_type hipgpu) else () - set(test_resource_type gpu) + set(test_resource_type syclgpu) endif () ginkgo_build_test_name(${test_name} test_target_name) string(TOUPPER ${exec} exec_upper) diff --git a/core/test/gtest/environments.hpp b/core/test/gtest/environments.hpp index a678ce00ffd..0d433f1c9d1 100644 --- a/core/test/gtest/environments.hpp +++ b/core/test/gtest/environments.hpp @@ -21,76 +21,113 @@ #include +#include +#include -struct resource { +struct ctest_resource { int id; int slots; }; -inline resource parse_single_resource(const std::string& resource_string) +inline char* get_ctest_group(std::string resource_type, int group_id) { - std::regex re(R"(id\:(\d+),slots\:(\d+))"); - std::smatch match; - - if (!std::regex_match(resource_string, match, re)) { - GKO_INVALID_STATE("Can't parse resource string: " + resource_string); - } - - return resource{std::stoi(match[1]), std::stoi(match[2])}; + std::transform(resource_type.begin(), resource_type.end(), + resource_type.begin(), + [](auto c) { return std::toupper(c); }); + std::string rs_group_env = "CTEST_RESOURCE_GROUP_" + + std::to_string(group_id) + "_" + resource_type; + return std::getenv(rs_group_env.c_str()); } -inline std::vector get_ctest_resources() +inline ctest_resource parse_ctest_resources(std::string resource) { - auto rs_count_env = std::getenv("CTEST_RESOURCE_GROUP_COUNT"); - std::cerr << "CTEST_RESOURCE_GROUP_COUNT=" << rs_count_env << std::endl; - - auto rs_count = rs_count_env ? std::stoi(rs_count_env) : 0; - - if (rs_count == 0) { -#ifdef GKO_COMPILING_OMP - resource rs{}; -#pragma omp parallel -#pragma omp single - { - rs = resource{0, omp_get_num_threads()}; - } - return {rs}; -#else - return {{0, 1}}; -#endif - } - - std::vector resources; - - for (int i = 0; i < rs_count; ++i) { - std::string rs_group_env = "CTEST_RESOURCE_GROUP_" + std::to_string(i); - std::string rs_type = std::getenv(rs_group_env.c_str()); - std::cerr << rs_group_env << "=" << rs_type << std::endl; - - std::transform(rs_type.begin(), rs_type.end(), rs_type.begin(), - [](auto c) { return std::toupper(c); }); - std::string rs_current_group = rs_group_env + "_" + rs_type; - std::string rs_env = std::getenv(rs_current_group.c_str()); - std::cerr << rs_current_group << "=" << rs_env << std::endl; + std::regex re(R"(id\:(\d+),slots\:(\d+))"); + std::smatch match; - resources.push_back(parse_single_resource(rs_env)); + if (!std::regex_match(resource, match, re)) { + GKO_INVALID_STATE("Can't parse ctest_resource string: " + resource); } - return resources; + return ctest_resource{std::stoi(match[1]), std::stoi(match[2])}; } class ResourceEnvironment : public ::testing::Environment { public: - explicit ResourceEnvironment(resource rs_) : ::testing::Environment() + explicit ResourceEnvironment(int rank = 0, int size = 1) { - rs = rs_; +#if GINKGO_BUILD_MPI + if (size > 1) { + cuda_device_id = gko::experimental::mpi::map_rank_to_device_id( + MPI_COMM_WORLD, + std::max(gko::CudaExecutor::get_num_devices(), 1)); + hip_device_id = gko::experimental::mpi::map_rank_to_device_id( + MPI_COMM_WORLD, + std::max(gko::HipExecutor::get_num_devices(), 1)); + sycl_device_id = gko::experimental::mpi::map_rank_to_device_id( + MPI_COMM_WORLD, + std::max(gko::DpcppExecutor::get_num_devices("gpu"), 1)); + } +#endif + + auto rs_count_env = std::getenv("CTEST_RESOURCE_GROUP_COUNT"); + auto rs_count = rs_count_env ? std::stoi(rs_count_env) : 0; + if (rs_count == 0) { + std::cerr << "Running without CTest ctest_resource configuration" + << std::endl; + return; + } + if (rs_count != size) { + GKO_INVALID_STATE("Invalid resource group count: " + + std::to_string(rs_count)); + } + + // parse CTest ctest_resource group descriptions + if (rank == 0) { + std::cerr << "Running with CTest ctest_resource configuration:" + << std::endl; + } + // OpenMP CPU threads + if (auto rs_omp_env = get_ctest_group("cpu", rank)) { + auto resource = parse_ctest_resources(rs_omp_env); + omp_threads = resource.slots; + if (rank == 0) { + std::cerr << omp_threads << " CPU threads" << std::endl; + } + } + // CUDA GPUs + if (auto rs_cuda_env = get_ctest_group("cudagpu", rank)) { + auto resource = parse_ctest_resources(rs_cuda_env); + cuda_device_id = resource.id; + if (rank == 0) { + std::cerr << "CUDA device " << cuda_device_id << std::endl; + } + } + // HIP GPUs + if (auto rs_hip_env = get_ctest_group("hipgpu", rank)) { + auto resource = parse_ctest_resources(rs_hip_env); + hip_device_id = resource.id; + if (rank == 0) { + std::cerr << "HIP device " << hip_device_id << std::endl; + } + } + // SYCL GPUs (no other devices!) + if (auto rs_sycl_env = get_ctest_group("syclgpu", rank)) { + auto resource = parse_ctest_resources(rs_sycl_env); + sycl_device_id = resource.id; + if (rank == 0) { + std::cerr << "SYCL device " << sycl_device_id << std::endl; + } + } } - static resource rs; + static int omp_threads; + static int cuda_device_id; + static int hip_device_id; + static int sycl_device_id; }; @@ -100,7 +137,9 @@ class OmpEnvironment : public ::testing::Environment { public: void SetUp() override { - omp_set_num_threads(ResourceEnvironment::rs.slots); + if (ResourceEnvironment::omp_threads > 0) { + omp_set_num_threads(ResourceEnvironment::omp_threads); + } } }; @@ -118,7 +157,7 @@ class CudaEnvironment : public ::testing::Environment { public: void TearDown() override { - gko::kernels::cuda::reset_device(ResourceEnvironment::rs.id); + gko::kernels::cuda::reset_device(ResourceEnvironment::cuda_device_id); } }; @@ -135,7 +174,7 @@ class HipEnvironment : public ::testing::Environment { public: void TearDown() override { - gko::kernels::hip::reset_device(ResourceEnvironment::rs.id); + gko::kernels::hip::reset_device(ResourceEnvironment::hip_device_id); } }; diff --git a/core/test/gtest/ginkgo_main.cpp b/core/test/gtest/ginkgo_main.cpp index 76a005a66e2..71117f2d73b 100644 --- a/core/test/gtest/ginkgo_main.cpp +++ b/core/test/gtest/ginkgo_main.cpp @@ -3,16 +3,18 @@ #include "core/test/gtest/environments.hpp" -resource ResourceEnvironment::rs = {}; + +int ResourceEnvironment::omp_threads = 0; +int ResourceEnvironment::cuda_device_id = 0; +int ResourceEnvironment::hip_device_id = 0; +int ResourceEnvironment::sycl_device_id = 0; + int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - auto resources = get_ctest_resources(); - - ::testing::AddGlobalTestEnvironment( - new ResourceEnvironment(resources.front())); + ::testing::AddGlobalTestEnvironment(new ResourceEnvironment); ::testing::AddGlobalTestEnvironment(new CudaEnvironment); ::testing::AddGlobalTestEnvironment(new HipEnvironment); ::testing::AddGlobalTestEnvironment(new OmpEnvironment); diff --git a/core/test/gtest/ginkgo_mpi_main.cpp b/core/test/gtest/ginkgo_mpi_main.cpp index 934a3dcd3f5..945ec7ec7cd 100644 --- a/core/test/gtest/ginkgo_mpi_main.cpp +++ b/core/test/gtest/ginkgo_mpi_main.cpp @@ -375,7 +375,11 @@ class MPIWrapperPrinter : public ::testing::TestEventListener { } // namespace GTestMPIListener -resource ResourceEnvironment::rs = {}; +int ResourceEnvironment::omp_threads = 0; +int ResourceEnvironment::cuda_device_id = 0; +int ResourceEnvironment::hip_device_id = 0; +int ResourceEnvironment::sycl_device_id = 0; + int main(int argc, char** argv) { @@ -384,13 +388,12 @@ int main(int argc, char** argv) MPI_Init(&argc, &argv); MPI_Comm comm(MPI_COMM_WORLD); int rank; + int size; MPI_Comm_rank(comm, &rank); - - auto resources = get_ctest_resources(); + MPI_Comm_size(comm, &size); testing::AddGlobalTestEnvironment(new GTestMPIListener::MPIEnvironment); - ::testing::AddGlobalTestEnvironment( - new ResourceEnvironment(resources[rank])); + ::testing::AddGlobalTestEnvironment(new ResourceEnvironment(rank, size)); ::testing::AddGlobalTestEnvironment(new CudaEnvironment); ::testing::AddGlobalTestEnvironment(new HipEnvironment); ::testing::AddGlobalTestEnvironment(new OmpEnvironment); diff --git a/cuda/test/utils.hpp b/cuda/test/utils.hpp index f35cb8d4c12..0410b3a6a22 100644 --- a/cuda/test/utils.hpp +++ b/cuda/test/utils.hpp @@ -52,10 +52,10 @@ class CudaTestFixture : public ::testing::Test { protected: CudaTestFixture() : ref(gko::ReferenceExecutor::create()), - stream(ResourceEnvironment::rs.id), - exec(gko::CudaExecutor::create(ResourceEnvironment::rs.id, ref, std::make_shared< - gko::CudaAllocator>(), - stream.get())), + stream(ResourceEnvironment::cuda_device_id), + exec(gko::CudaExecutor::create( + ResourceEnvironment::cuda_device_id, ref, std::make_shared< + gko::CudaAllocator>(), stream.get())), guard(exec->get_scoped_device_id_guard()) {} diff --git a/hip/test/utils.hip.hpp b/hip/test/utils.hip.hpp index 1c57467b451..38fc3763ece 100644 --- a/hip/test/utils.hip.hpp +++ b/hip/test/utils.hip.hpp @@ -52,8 +52,8 @@ class HipTestFixture : public ::testing::Test { protected: HipTestFixture() : ref(gko::ReferenceExecutor::create()), - stream(ResourceEnvironment::rs.id), - exec(gko::HipExecutor::create(ResourceEnvironment::rs.id, ref, std::make_shared< + stream(ResourceEnvironment::hip_device_id), + exec(gko::HipExecutor::create(ResourceEnvironment::hip_device_id, ref, std::make_shared< gko::HipAllocator>(), stream.get())), guard(exec->get_scoped_device_id_guard()) diff --git a/test/utils/executor.hpp b/test/utils/executor.hpp index d52b8083ac8..082c3556381 100644 --- a/test/utils/executor.hpp +++ b/test/utils/executor.hpp @@ -80,7 +80,8 @@ inline void init_executor(std::shared_ptr ref, throw std::runtime_error{"No suitable CUDA devices"}; } exec = gko::CudaExecutor::create( - ResourceEnvironment::rs.id, ref, std::make_shared(), stream); + ResourceEnvironment::cuda_device_id, + ref, std::make_shared(), stream); } } @@ -93,7 +94,7 @@ inline void init_executor(std::shared_ptr ref, throw std::runtime_error{"No suitable HIP devices"}; } exec = gko::HipExecutor::create( - ResourceEnvironment::rs.id, ref, std::make_shared< + ResourceEnvironment::hip_device_id, ref, std::make_shared< gko::HipAllocator>(), stream); } @@ -102,11 +103,10 @@ inline void init_executor(std::shared_ptr ref, std::shared_ptr& exec) { if (gko::DpcppExecutor::get_num_devices("gpu") > 0) { - exec = - gko::DpcppExecutor::create(ResourceEnvironment::rs.id, ref, "gpu"); + exec = gko::DpcppExecutor::create(ResourceEnvironment::sycl_device_id, + ref, "gpu"); } else if (gko::DpcppExecutor::get_num_devices("cpu") > 0) { - exec = - gko::DpcppExecutor::create(ResourceEnvironment::rs.id, ref, "cpu"); + exec = gko::DpcppExecutor::create(0, ref, "cpu"); } else { throw std::runtime_error{"No suitable DPC++ devices"}; } @@ -124,8 +124,11 @@ class CommonTestFixture : public ::testing::Test { CommonTestFixture() : -#if defined(GKO_COMPILING_CUDA) || defined(GKO_COMPILING_HIP) - stream(ResourceEnvironment::rs.id), +#ifdef GKO_COMPILING_CUDA + stream(ResourceEnvironment::cuda_device_id), +#endif +#ifdef GKO_COMPILING_HIP + stream(ResourceEnvironment::hip_device_id), #endif ref{gko::ReferenceExecutor::create()} { diff --git a/test/utils/mpi/executor.hpp b/test/utils/mpi/executor.hpp index f317f60eb35..f02834a5a1f 100644 --- a/test/utils/mpi/executor.hpp +++ b/test/utils/mpi/executor.hpp @@ -58,8 +58,11 @@ class CommonMpiTestFixture : public ::testing::Test { CommonMpiTestFixture() : comm(MPI_COMM_WORLD), -#if defined(GKO_COMPILING_CUDA) || defined(GKO_COMPILING_HIP) - stream(ResourceEnvironment::rs.id), +#ifdef GKO_COMPILING_CUDA + stream(ResourceEnvironment::cuda_device_id), +#endif +#ifdef GKO_COMPILING_HIP + stream(ResourceEnvironment::hip_device_id), #endif ref{gko::ReferenceExecutor::create()} { From c8692ab6a6201a1ae6bac8d66130c3f66828a320 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Mon, 31 Jul 2023 11:33:24 +0200 Subject: [PATCH 19/44] adds generator for ctest resource file Co-authored-by: Tobias Ribizel --- test/CMakeLists.txt | 1 + test/tools/CMakeLists.txt | 2 + test/tools/resource_file_generator.cpp | 72 ++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 test/tools/CMakeLists.txt create mode 100644 test/tools/resource_file_generator.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8a6eb305b6a..6e72dbdf0aa 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -14,3 +14,4 @@ add_subdirectory(preconditioner) add_subdirectory(reorder) add_subdirectory(solver) add_subdirectory(stop) +add_subdirectory(tools) diff --git a/test/tools/CMakeLists.txt b/test/tools/CMakeLists.txt new file mode 100644 index 00000000000..d3aa14b8ca7 --- /dev/null +++ b/test/tools/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(resource_file_generator resource_file_generator.cpp) +target_link_libraries(resource_file_generator Ginkgo::ginkgo ) diff --git a/test/tools/resource_file_generator.cpp b/test/tools/resource_file_generator.cpp new file mode 100644 index 00000000000..1070a569662 --- /dev/null +++ b/test/tools/resource_file_generator.cpp @@ -0,0 +1,72 @@ +#include + +#include +#include + + +std::vector split(const std::string& s, char delimiter = ',') +{ + std::istringstream iss(s); + std::vector tokens; + std::string token; + while (std::getline(iss, token, delimiter)) { + tokens.push_back(token); + } + return tokens; +} + +std::string create_json(const std::string& resources) +{ + std::string json; + json.append(R"({ + "version": { + "major": 1, + "minor": 0 + }, + "local": [ + { +)"); + for (const auto& line : split(resources, '\n')) { + json.append(R"( )"); + json.append(line); + json.append("\n"); + } + json.append(R"( } + ] +})"); + return json; +} + + +int main() +{ + auto num_cpu_threads = std::max(std::thread::hardware_concurrency(), 1u); + auto num_cuda_gpus = gko::CudaExecutor::get_num_devices(); + auto num_hip_gpus = gko::HipExecutor::get_num_devices(); + auto num_sycl_gpus = gko::DpcppExecutor::get_num_devices("gpu"); + + std::string cpus = R"("cpu": [{"id": "0", "slots": )" + + std::to_string(num_cpu_threads) + "}]"; + + std::string gpus = ""; + auto add_devices = [&](int num_devices, const std::string& name) { + if(num_devices){ + gpus.append(",\n"); + gpus += '"' + name + "\": [\n"; + } + for (int i = 0; i < num_devices; i++) { + if(i > 0){ + gpus.append(",\n"); + } + gpus+= R"( {"id": ")" + std::to_string(i) + R"(", "slots": 100})"; + } + if(num_devices){ + gpus.append("\n]"); + } + }; + add_devices(num_cuda_gpus, "cudagpu"); + add_devices(num_hip_gpus, "hipgpu"); + add_devices(num_sycl_gpus, "syclgpu"); + + std::cout << create_json(cpus + gpus) << std::endl; +} \ No newline at end of file From 89f95b428bff91aea92767bbfcfd62efdfcbd1b3 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Tue, 1 Aug 2023 18:06:03 +0200 Subject: [PATCH 20/44] review updates: - remove test file - small documentation - more verbose device id output Co-authored-by: Tobias Ribizel --- core/test/gtest/environments.hpp | 15 +++----- resources.json | 51 -------------------------- test/tools/CMakeLists.txt | 2 +- test/tools/resource_file_generator.cpp | 2 +- test/utils/executor.hpp | 2 + 5 files changed, 10 insertions(+), 62 deletions(-) delete mode 100644 resources.json diff --git a/core/test/gtest/environments.hpp b/core/test/gtest/environments.hpp index 0d433f1c9d1..6276de9372a 100644 --- a/core/test/gtest/environments.hpp +++ b/core/test/gtest/environments.hpp @@ -102,25 +102,22 @@ class ResourceEnvironment : public ::testing::Environment { if (auto rs_cuda_env = get_ctest_group("cudagpu", rank)) { auto resource = parse_ctest_resources(rs_cuda_env); cuda_device_id = resource.id; - if (rank == 0) { - std::cerr << "CUDA device " << cuda_device_id << std::endl; - } + std::cerr << "Rank " << rank << ": CUDA device " << cuda_device_id + << std::endl; } // HIP GPUs if (auto rs_hip_env = get_ctest_group("hipgpu", rank)) { auto resource = parse_ctest_resources(rs_hip_env); hip_device_id = resource.id; - if (rank == 0) { - std::cerr << "HIP device " << hip_device_id << std::endl; - } + std::cerr << "Rank " << rank << ": HIP device " << cuda_device_id + << std::endl; } // SYCL GPUs (no other devices!) if (auto rs_sycl_env = get_ctest_group("syclgpu", rank)) { auto resource = parse_ctest_resources(rs_sycl_env); sycl_device_id = resource.id; - if (rank == 0) { - std::cerr << "SYCL device " << sycl_device_id << std::endl; - } + std::cerr << "Rank " << rank << ": SYCL device " << cuda_device_id + << std::endl; } } diff --git a/resources.json b/resources.json deleted file mode 100644 index 9d69ada752b..00000000000 --- a/resources.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "version": { - "major": 1, - "minor": 0 - }, - "local": [ - { - "cpus": [ - { - "id": "0", - "slots": 32 - } - ], - - "gpus": [ - { - "id": "0", - "slots": 100 - }, - { - "id": "1", - "slots": 100 - }, - { - "id": "2", - "slots": 100 - }, - { - "id": "3", - "slots": 100 - }, - { - "id": "4", - "slots": 100 - }, - { - "id": "5", - "slots": 100 - }, - { - "id": "6", - "slots": 100 - }, - { - "id": "7", - "slots": 100 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/tools/CMakeLists.txt b/test/tools/CMakeLists.txt index d3aa14b8ca7..21a7a5fc695 100644 --- a/test/tools/CMakeLists.txt +++ b/test/tools/CMakeLists.txt @@ -1,2 +1,2 @@ add_executable(resource_file_generator resource_file_generator.cpp) -target_link_libraries(resource_file_generator Ginkgo::ginkgo ) +target_link_libraries(resource_file_generator Ginkgo::ginkgo) diff --git a/test/tools/resource_file_generator.cpp b/test/tools/resource_file_generator.cpp index 1070a569662..de9464ce82d 100644 --- a/test/tools/resource_file_generator.cpp +++ b/test/tools/resource_file_generator.cpp @@ -69,4 +69,4 @@ int main() add_devices(num_sycl_gpus, "syclgpu"); std::cout << create_json(cpus + gpus) << std::endl; -} \ No newline at end of file +} diff --git a/test/utils/executor.hpp b/test/utils/executor.hpp index 082c3556381..836f70d2352 100644 --- a/test/utils/executor.hpp +++ b/test/utils/executor.hpp @@ -137,6 +137,8 @@ class CommonTestFixture : public ::testing::Test { #else init_executor(ref, exec); #endif + // set device-id test-wide since some test call device + // kernels directly guard = exec->get_scoped_device_id_guard(); } From 2ea40038a5270784092c41c475f37817f7e98994 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Wed, 2 Aug 2023 14:30:21 +0200 Subject: [PATCH 21/44] fixes tests after rebase --- core/test/gtest/environments.hpp | 3 +++ test/utils/executor.hpp | 1 + 2 files changed, 4 insertions(+) diff --git a/core/test/gtest/environments.hpp b/core/test/gtest/environments.hpp index 6276de9372a..ff029995baf 100644 --- a/core/test/gtest/environments.hpp +++ b/core/test/gtest/environments.hpp @@ -5,6 +5,9 @@ #include +#include + + #ifdef GKO_COMPILING_OMP #include #endif diff --git a/test/utils/executor.hpp b/test/utils/executor.hpp index 836f70d2352..419e089f793 100644 --- a/test/utils/executor.hpp +++ b/test/utils/executor.hpp @@ -35,6 +35,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +#include #include From 89906c87e3630c5b0f87e4f15cbc5c7f2f2c5980 Mon Sep 17 00:00:00 2001 From: ginkgo-bot Date: Thu, 3 Aug 2023 07:23:10 +0000 Subject: [PATCH 22/44] Format files Co-authored-by: Marcel Koch --- core/test/gtest/environments.hpp | 32 +++++++++++++++++++ core/test/gtest/ginkgo_main.cpp | 34 +++++++++++++++++++- cuda/test/utils.hpp | 4 +-- hip/test/utils.hip.hpp | 4 +-- test/tools/resource_file_generator.cpp | 43 +++++++++++++++++++++++--- test/utils/executor.hpp | 14 +++++---- test/utils/mpi/executor.hpp | 4 ++- 7 files changed, 118 insertions(+), 17 deletions(-) diff --git a/core/test/gtest/environments.hpp b/core/test/gtest/environments.hpp index ff029995baf..856763d4105 100644 --- a/core/test/gtest/environments.hpp +++ b/core/test/gtest/environments.hpp @@ -1,3 +1,35 @@ +/************************************************************* +Copyright (c) 2017-2023, the Ginkgo authors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. 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. + +3. Neither the name of the copyright holder 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 AND CONTRIBUTORS "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 +HOLDER 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. +*************************************************************/ + #ifndef GINKGO_ENVIRONMENTS_HPP #define GINKGO_ENVIRONMENTS_HPP diff --git a/core/test/gtest/ginkgo_main.cpp b/core/test/gtest/ginkgo_main.cpp index 71117f2d73b..4d69b421875 100644 --- a/core/test/gtest/ginkgo_main.cpp +++ b/core/test/gtest/ginkgo_main.cpp @@ -1,3 +1,35 @@ +/************************************************************* +Copyright (c) 2017-2023, the Ginkgo authors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. 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. + +3. Neither the name of the copyright holder 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 AND CONTRIBUTORS "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 +HOLDER 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. +*************************************************************/ + #include @@ -20,4 +52,4 @@ int main(int argc, char** argv) ::testing::AddGlobalTestEnvironment(new OmpEnvironment); int result = RUN_ALL_TESTS(); return result; -} \ No newline at end of file +} diff --git a/cuda/test/utils.hpp b/cuda/test/utils.hpp index 0410b3a6a22..35f382806ec 100644 --- a/cuda/test/utils.hpp +++ b/cuda/test/utils.hpp @@ -54,8 +54,8 @@ class CudaTestFixture : public ::testing::Test { : ref(gko::ReferenceExecutor::create()), stream(ResourceEnvironment::cuda_device_id), exec(gko::CudaExecutor::create( - ResourceEnvironment::cuda_device_id, ref, std::make_shared< - gko::CudaAllocator>(), stream.get())), + ResourceEnvironment::cuda_device_id, ref, + std::make_shared(), stream.get())), guard(exec->get_scoped_device_id_guard()) {} diff --git a/hip/test/utils.hip.hpp b/hip/test/utils.hip.hpp index 38fc3763ece..d67c8935ab4 100644 --- a/hip/test/utils.hip.hpp +++ b/hip/test/utils.hip.hpp @@ -53,8 +53,8 @@ class HipTestFixture : public ::testing::Test { HipTestFixture() : ref(gko::ReferenceExecutor::create()), stream(ResourceEnvironment::hip_device_id), - exec(gko::HipExecutor::create(ResourceEnvironment::hip_device_id, ref, std::make_shared< - gko::HipAllocator>(), + exec(gko::HipExecutor::create(ResourceEnvironment::hip_device_id, ref, + std::make_shared(), stream.get())), guard(exec->get_scoped_device_id_guard()) {} diff --git a/test/tools/resource_file_generator.cpp b/test/tools/resource_file_generator.cpp index de9464ce82d..7db262cf982 100644 --- a/test/tools/resource_file_generator.cpp +++ b/test/tools/resource_file_generator.cpp @@ -1,9 +1,42 @@ -#include +/************************************************************* +Copyright (c) 2017-2023, the Ginkgo authors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. 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. + +3. Neither the name of the copyright holder 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 AND CONTRIBUTORS "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 +HOLDER 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. +*************************************************************/ #include #include +#include + + std::vector split(const std::string& s, char delimiter = ',') { std::istringstream iss(s); @@ -50,17 +83,17 @@ int main() std::string gpus = ""; auto add_devices = [&](int num_devices, const std::string& name) { - if(num_devices){ + if (num_devices) { gpus.append(",\n"); gpus += '"' + name + "\": [\n"; } for (int i = 0; i < num_devices; i++) { - if(i > 0){ + if (i > 0) { gpus.append(",\n"); } - gpus+= R"( {"id": ")" + std::to_string(i) + R"(", "slots": 100})"; + gpus += R"( {"id": ")" + std::to_string(i) + R"(", "slots": 100})"; } - if(num_devices){ + if (num_devices) { gpus.append("\n]"); } }; diff --git a/test/utils/executor.hpp b/test/utils/executor.hpp index 419e089f793..2a8ace8e39a 100644 --- a/test/utils/executor.hpp +++ b/test/utils/executor.hpp @@ -35,7 +35,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include #include @@ -45,6 +44,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +#include + + #include "core/test/gtest/environments.hpp" @@ -81,8 +83,8 @@ inline void init_executor(std::shared_ptr ref, throw std::runtime_error{"No suitable CUDA devices"}; } exec = gko::CudaExecutor::create( - ResourceEnvironment::cuda_device_id, - ref, std::make_shared(), stream); + ResourceEnvironment::cuda_device_id, ref, + std::make_shared(), stream); } } @@ -94,9 +96,9 @@ inline void init_executor(std::shared_ptr ref, if (gko::HipExecutor::get_num_devices() == 0) { throw std::runtime_error{"No suitable HIP devices"}; } - exec = gko::HipExecutor::create( - ResourceEnvironment::hip_device_id, ref, std::make_shared< - gko::HipAllocator>(), stream); + exec = + gko::HipExecutor::create(ResourceEnvironment::hip_device_id, ref, + std::make_shared(), stream); } diff --git a/test/utils/mpi/executor.hpp b/test/utils/mpi/executor.hpp index f02834a5a1f..504fc5d761c 100644 --- a/test/utils/mpi/executor.hpp +++ b/test/utils/mpi/executor.hpp @@ -35,7 +35,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include #include @@ -44,6 +43,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +#include + + #include "test/utils/executor.hpp" From e6c845bb0029f322fb0bd021937ff8a331b42133 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Thu, 3 Aug 2023 09:57:00 +0200 Subject: [PATCH 23/44] allow using ctest resources in CI runs --- .gitlab/scripts.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab/scripts.yml b/.gitlab/scripts.yml index b007caff35f..15a2004bde6 100644 --- a/.gitlab/scripts.yml +++ b/.gitlab/scripts.yml @@ -100,7 +100,7 @@ - awk '!/^#/ { print ($2 - $1)/1000 " " $4 }' .ninja_log | sort -nr - | (( $(ctest -N | tail -1 | sed 's/Total Tests: //') != 0 )) || exit 1 - - ctest -V --timeout 6000 + - ctest --output-on-failure --timeout 6000 ${CTEST_EXTRA_ARGS} - ninja test_install - pushd test/test_install - ninja install @@ -152,7 +152,7 @@ - cd ${CI_JOB_NAME/test/build} - | (( $(ctest -N | tail -1 | sed 's/Total Tests: //') != 0 )) || exit 1 - - ctest -V --timeout 6000 + - ctest --output-on-failure --timeout 6000 ${CTEST_EXTRA_ARGS} - ninja test_install - pushd test/test_install - ninja install From 552549472e926c798b147643a15153876d03081f Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Thu, 3 Aug 2023 11:00:49 +0200 Subject: [PATCH 24/44] add query for the default number of omp threads --- core/device_hooks/omp_hooks.cpp | 4 +++ include/ginkgo/core/base/executor.hpp | 2 ++ omp/CMakeLists.txt | 1 + omp/base/executor.cpp | 52 +++++++++++++++++++++++++++ 4 files changed, 59 insertions(+) create mode 100644 omp/base/executor.cpp diff --git a/core/device_hooks/omp_hooks.cpp b/core/device_hooks/omp_hooks.cpp index f652a4d4582..f79ddfdeca6 100644 --- a/core/device_hooks/omp_hooks.cpp +++ b/core/device_hooks/omp_hooks.cpp @@ -31,6 +31,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *************************************************************/ #include +#include #include #include @@ -51,6 +52,9 @@ scoped_device_id_guard::scoped_device_id_guard(const OmpExecutor* exec, GKO_NOT_COMPILED(omp); +int OmpExecutor::get_num_omp_threads() { return 1; } + + } // namespace gko diff --git a/include/ginkgo/core/base/executor.hpp b/include/ginkgo/core/base/executor.hpp index 456b69d3d7e..5f0c307bc73 100644 --- a/include/ginkgo/core/base/executor.hpp +++ b/include/ginkgo/core/base/executor.hpp @@ -1398,6 +1398,8 @@ class OmpExecutor : public detail::ExecutorBase, return this->get_exec_info().num_pu_per_cu; } + static int get_num_omp_threads(); + scoped_device_id_guard get_scoped_device_id_guard() const override; protected: diff --git a/omp/CMakeLists.txt b/omp/CMakeLists.txt index c689ffc42f3..7f46feff5da 100644 --- a/omp/CMakeLists.txt +++ b/omp/CMakeLists.txt @@ -5,6 +5,7 @@ target_sources(ginkgo_omp PRIVATE base/batch_multi_vector_kernels.cpp base/device_matrix_data_kernels.cpp + base/executor.cpp base/index_set_kernels.cpp base/scoped_device_id.cpp base/version.cpp diff --git a/omp/base/executor.cpp b/omp/base/executor.cpp new file mode 100644 index 00000000000..3e14270ecdc --- /dev/null +++ b/omp/base/executor.cpp @@ -0,0 +1,52 @@ +/************************************************************* +Copyright (c) 2017-2023, the Ginkgo authors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. 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. + +3. Neither the name of the copyright holder 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 AND CONTRIBUTORS "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 +HOLDER 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. +*************************************************************/ + +#include + + +#include + + +namespace gko { + + +int OmpExecutor::get_num_omp_threads() +{ + int num_threads; +#pragma omp parallel +#pragma omp single + num_threads = omp_get_num_threads(); + return num_threads; +} + + +} // namespace gko \ No newline at end of file From d265e4487d303d92cc27936312ac4ea3296f7bb3 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Thu, 3 Aug 2023 12:42:59 +0200 Subject: [PATCH 25/44] print device used in test environment Co-authored-by: Tobias Ribizel --- core/test/gtest/environments.hpp | 112 ++++++++++++++++++++++------ core/test/gtest/ginkgo_main.cpp | 7 +- core/test/gtest/ginkgo_mpi_main.cpp | 7 +- cuda/base/device.cpp | 8 ++ cuda/base/device.hpp | 4 + dpcpp/base/device.hpp | 3 + dpcpp/base/executor.dp.cpp | 11 +++ hip/base/device.hip.cpp | 8 ++ hip/base/device.hpp | 4 + 9 files changed, 136 insertions(+), 28 deletions(-) diff --git a/core/test/gtest/environments.hpp b/core/test/gtest/environments.hpp index 856763d4105..125fa7b9b8b 100644 --- a/core/test/gtest/environments.hpp +++ b/core/test/gtest/environments.hpp @@ -30,8 +30,8 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *************************************************************/ -#ifndef GINKGO_ENVIRONMENTS_HPP -#define GINKGO_ENVIRONMENTS_HPP +#ifndef GKO_CORE_TEST_GTEST_ENVIRONMENTS_HPP_ +#define GKO_CORE_TEST_GTEST_ENVIRONMENTS_HPP_ #include #include @@ -55,6 +55,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endif +#if GKO_COMPILING_DPCPP +#include "dpcpp/base/device.hpp" +#endif + + #include #include #include @@ -111,8 +116,11 @@ class ResourceEnvironment : public ::testing::Environment { auto rs_count_env = std::getenv("CTEST_RESOURCE_GROUP_COUNT"); auto rs_count = rs_count_env ? std::stoi(rs_count_env) : 0; if (rs_count == 0) { - std::cerr << "Running without CTest ctest_resource configuration" - << std::endl; + if (rank == 0) { + std::cerr + << "Running without CTest ctest_resource configuration" + << std::endl; + } return; } if (rs_count != size) { @@ -121,38 +129,25 @@ class ResourceEnvironment : public ::testing::Environment { } // parse CTest ctest_resource group descriptions - if (rank == 0) { - std::cerr << "Running with CTest ctest_resource configuration:" - << std::endl; - } // OpenMP CPU threads if (auto rs_omp_env = get_ctest_group("cpu", rank)) { auto resource = parse_ctest_resources(rs_omp_env); omp_threads = resource.slots; - if (rank == 0) { - std::cerr << omp_threads << " CPU threads" << std::endl; - } } // CUDA GPUs if (auto rs_cuda_env = get_ctest_group("cudagpu", rank)) { auto resource = parse_ctest_resources(rs_cuda_env); cuda_device_id = resource.id; - std::cerr << "Rank " << rank << ": CUDA device " << cuda_device_id - << std::endl; } // HIP GPUs if (auto rs_hip_env = get_ctest_group("hipgpu", rank)) { auto resource = parse_ctest_resources(rs_hip_env); hip_device_id = resource.id; - std::cerr << "Rank " << rank << ": HIP device " << cuda_device_id - << std::endl; } // SYCL GPUs (no other devices!) if (auto rs_sycl_env = get_ctest_group("syclgpu", rank)) { auto resource = parse_ctest_resources(rs_sycl_env); sycl_device_id = resource.id; - std::cerr << "Rank " << rank << ": SYCL device " << cuda_device_id - << std::endl; } } @@ -167,18 +162,31 @@ class ResourceEnvironment : public ::testing::Environment { class OmpEnvironment : public ::testing::Environment { public: + explicit OmpEnvironment(int rank) : rank_(rank) {} + void SetUp() override { if (ResourceEnvironment::omp_threads > 0) { - omp_set_num_threads(ResourceEnvironment::omp_threads); + omp_set_num_threads(num_threads); } +#pragma omp parallel +#pragma single + std::cerr << "Rank " << rank_ << ": OMP threads " + << omp_get_num_threads(); + << std::endl; } + +private: + int rank_; }; #else -class OmpEnvironment : public ::testing::Environment {}; +class OmpEnvironment : public ::testing::Environment { +public: + explicit OmpEnvironment(int){}; +}; #endif @@ -187,15 +195,31 @@ class OmpEnvironment : public ::testing::Environment {}; class CudaEnvironment : public ::testing::Environment { public: + explicit CudaEnvironment(int rank) : rank_(rank) {} + + void SetUp() override + { + auto device_id = ResourceEnvironment::cuda_device_id; + std::cerr << "Rank " << rank_ << ": CUDA device " + << gko::kernels::cuda::get_device_name(device_id) << " ID " + << device_id << std::endl; + } + void TearDown() override { gko::kernels::cuda::reset_device(ResourceEnvironment::cuda_device_id); } + +private: + int rank_; }; #else -class CudaEnvironment : public ::testing::Environment {}; +class CudaEnvironment : public ::testing::Environment { +public: + explicit CudaEnvironment(int){}; +}; #endif @@ -204,17 +228,61 @@ class CudaEnvironment : public ::testing::Environment {}; class HipEnvironment : public ::testing::Environment { public: + explicit HipEnvironment(int rank) : rank_(rank) {} + + void SetUp() override + { + auto device_id = ResourceEnvironment::hip_device_id; + std::cerr << "Rank " << rank_ << ": HIP device " + << gko::kernels::hip::get_device_name(device_id) << " ID " + << device_id << std::endl; + } + void TearDown() override { gko::kernels::hip::reset_device(ResourceEnvironment::hip_device_id); } + +private: + int rank_; +}; + +#else + +class HipEnvironment : public ::testing::Environment { +public: + explicit HipEnvironment(int){}; +}; + +#endif + + +#ifdef GKO_COMPILING_DPCPP + +class SyclEnvironment : public ::testing::Environment { +public: + explicit SyclEnvironment(int rank) : rank_(rank) {} + + void SetUp() override + { + auto device_id = ResourceEnvironment::sycl_device_id; + std::cerr << "Rank " << rank_ << ": SYCL device " + << gko::kernels::dpcpp::get_device_name(device_id) << " ID " + << device_id << std::endl; + } + +private: + int rank_; }; #else -class HipEnvironment : public ::testing::Environment {}; +class SyclEnvironment : public ::testing::Environment { +public: + explicit SyclEnvironment(int){}; +}; #endif -#endif // GINKGO_ENVIRONMENTS_HPP +#endif // GKO_CORE_TEST_GTEST_ENVIRONMENTS_HPP_ diff --git a/core/test/gtest/ginkgo_main.cpp b/core/test/gtest/ginkgo_main.cpp index 4d69b421875..01d1fc393c3 100644 --- a/core/test/gtest/ginkgo_main.cpp +++ b/core/test/gtest/ginkgo_main.cpp @@ -47,9 +47,10 @@ int main(int argc, char** argv) ::testing::InitGoogleTest(&argc, argv); ::testing::AddGlobalTestEnvironment(new ResourceEnvironment); - ::testing::AddGlobalTestEnvironment(new CudaEnvironment); - ::testing::AddGlobalTestEnvironment(new HipEnvironment); - ::testing::AddGlobalTestEnvironment(new OmpEnvironment); + ::testing::AddGlobalTestEnvironment(new CudaEnvironment(0)); + ::testing::AddGlobalTestEnvironment(new HipEnvironment(0)); + ::testing::AddGlobalTestEnvironment(new SyclEnvironment(0)); + ::testing::AddGlobalTestEnvironment(new OmpEnvironment(0)); int result = RUN_ALL_TESTS(); return result; } diff --git a/core/test/gtest/ginkgo_mpi_main.cpp b/core/test/gtest/ginkgo_mpi_main.cpp index 945ec7ec7cd..f7fe71981d2 100644 --- a/core/test/gtest/ginkgo_mpi_main.cpp +++ b/core/test/gtest/ginkgo_mpi_main.cpp @@ -394,9 +394,10 @@ int main(int argc, char** argv) testing::AddGlobalTestEnvironment(new GTestMPIListener::MPIEnvironment); ::testing::AddGlobalTestEnvironment(new ResourceEnvironment(rank, size)); - ::testing::AddGlobalTestEnvironment(new CudaEnvironment); - ::testing::AddGlobalTestEnvironment(new HipEnvironment); - ::testing::AddGlobalTestEnvironment(new OmpEnvironment); + ::testing::AddGlobalTestEnvironment(new CudaEnvironment(rank)); + ::testing::AddGlobalTestEnvironment(new HipEnvironment(rank)); + ::testing::AddGlobalTestEnvironment(new SyclEnvironment(rank)); + ::testing::AddGlobalTestEnvironment(new OmpEnvironment(rank)); ::testing::TestEventListeners& listeners = ::testing::UnitTest::GetInstance()->listeners(); diff --git a/cuda/base/device.cpp b/cuda/base/device.cpp index 2db0876ca95..32cf6265160 100644 --- a/cuda/base/device.cpp +++ b/cuda/base/device.cpp @@ -58,6 +58,14 @@ void destroy_event(CUevent_st* event) } +std::string get_device_name(int device_id) +{ + cudaDeviceProp prop; + GKO_ASSERT_NO_CUDA_ERRORS(cudaGetDeviceProperties(&prop, device_id)); + return {prop.name}; +} + + } // namespace cuda } // namespace kernels } // namespace gko diff --git a/cuda/base/device.hpp b/cuda/base/device.hpp index 7bd9390c54e..e363f455300 100644 --- a/cuda/base/device.hpp +++ b/cuda/base/device.hpp @@ -50,6 +50,10 @@ void reset_device(int device_id); void destroy_event(CUevent_st* event); +/** returns cudaDeviceProp.name for the given device */ +std::string get_device_name(int device_id); + + } // namespace cuda } // namespace kernels } // namespace gko diff --git a/dpcpp/base/device.hpp b/dpcpp/base/device.hpp index 6047fbed615..658ccbe18f4 100644 --- a/dpcpp/base/device.hpp +++ b/dpcpp/base/device.hpp @@ -46,6 +46,9 @@ namespace dpcpp { void destroy_event(sycl::event* event); +std::string get_device_name(int device_id); + + } // namespace dpcpp } // namespace kernels } // namespace gko diff --git a/dpcpp/base/executor.dp.cpp b/dpcpp/base/executor.dp.cpp index 3d01e271f15..6d6bbbe0388 100644 --- a/dpcpp/base/executor.dp.cpp +++ b/dpcpp/base/executor.dp.cpp @@ -323,6 +323,17 @@ namespace dpcpp { void destroy_event(sycl::event* event) { delete event; } +std::string get_device_name(int device_id) +{ + auto devices = ::gko::detail::get_devices("gpu"); + if (devices.empty()) { + return "CPU"; + } + + return devices[device_id].get_info(); +} + + } // namespace dpcpp } // namespace kernels } // namespace gko diff --git a/hip/base/device.hip.cpp b/hip/base/device.hip.cpp index 9a01d6aacee..d539fa69b43 100644 --- a/hip/base/device.hip.cpp +++ b/hip/base/device.hip.cpp @@ -62,6 +62,14 @@ void destroy_event(GKO_HIP_EVENT_STRUCT* event) } +std::string get_device_name(int device_id) +{ + hipDeviceProp_t prop; + GKO_ASSERT_NO_HIP_ERRORS(hipGetDeviceProperties(&prop, device_id)); + return {prop.name}; +} + + } // namespace hip } // namespace kernels } // namespace gko diff --git a/hip/base/device.hpp b/hip/base/device.hpp index dcc8c3ba0f1..fceffe4a503 100644 --- a/hip/base/device.hpp +++ b/hip/base/device.hpp @@ -49,6 +49,10 @@ void reset_device(int device_id); void destroy_event(GKO_HIP_EVENT_STRUCT* event); +/** returns hipDeviceProp.name for the given device */ +std::string get_device_name(int device_id); + + } // namespace hip } // namespace kernels } // namespace gko From e760d24e0b12fe9f516110dbc982239c74582c0d Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Thu, 3 Aug 2023 12:44:21 +0200 Subject: [PATCH 26/44] use ginkgo_create_dpcpp_test consistently --- dpcpp/test/matrix/CMakeLists.txt | 2 +- dpcpp/test/matrix/{fbcsr_kernels.cpp => fbcsr_kernels.dp.cpp} | 0 dpcpp/test/preconditioner/CMakeLists.txt | 2 +- .../{jacobi_kernels.cpp => jacobi_kernels.dp.cpp} | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename dpcpp/test/matrix/{fbcsr_kernels.cpp => fbcsr_kernels.dp.cpp} (100%) rename dpcpp/test/preconditioner/{jacobi_kernels.cpp => jacobi_kernels.dp.cpp} (100%) diff --git a/dpcpp/test/matrix/CMakeLists.txt b/dpcpp/test/matrix/CMakeLists.txt index 88ab52e9c3f..7ada04882da 100644 --- a/dpcpp/test/matrix/CMakeLists.txt +++ b/dpcpp/test/matrix/CMakeLists.txt @@ -1 +1 @@ -ginkgo_create_test(fbcsr_kernels) +ginkgo_create_dpcpp_test(fbcsr_kernels) diff --git a/dpcpp/test/matrix/fbcsr_kernels.cpp b/dpcpp/test/matrix/fbcsr_kernels.dp.cpp similarity index 100% rename from dpcpp/test/matrix/fbcsr_kernels.cpp rename to dpcpp/test/matrix/fbcsr_kernels.dp.cpp diff --git a/dpcpp/test/preconditioner/CMakeLists.txt b/dpcpp/test/preconditioner/CMakeLists.txt index a0ca5a2e38a..c606e12ac3e 100644 --- a/dpcpp/test/preconditioner/CMakeLists.txt +++ b/dpcpp/test/preconditioner/CMakeLists.txt @@ -1 +1 @@ -ginkgo_create_test(jacobi_kernels) +ginkgo_create_dpcpp_test(jacobi_kernels) diff --git a/dpcpp/test/preconditioner/jacobi_kernels.cpp b/dpcpp/test/preconditioner/jacobi_kernels.dp.cpp similarity index 100% rename from dpcpp/test/preconditioner/jacobi_kernels.cpp rename to dpcpp/test/preconditioner/jacobi_kernels.dp.cpp From cada2ce279f9b641f930f5caab5c796f1571231c Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Thu, 3 Aug 2023 14:21:18 +0200 Subject: [PATCH 27/44] fixup! print device used in test environment --- core/test/gtest/environments.hpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/test/gtest/environments.hpp b/core/test/gtest/environments.hpp index 125fa7b9b8b..2d0d1eac33a 100644 --- a/core/test/gtest/environments.hpp +++ b/core/test/gtest/environments.hpp @@ -167,13 +167,12 @@ class OmpEnvironment : public ::testing::Environment { void SetUp() override { if (ResourceEnvironment::omp_threads > 0) { - omp_set_num_threads(num_threads); + omp_set_num_threads(ResourceEnvironment::omp_threads); } #pragma omp parallel #pragma single std::cerr << "Rank " << rank_ << ": OMP threads " - << omp_get_num_threads(); - << std::endl; + << omp_get_num_threads() << std::endl; } private: From 1602d73cb65fbb29e6a3df591f342c41b3fd1dc0 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Thu, 3 Aug 2023 17:45:28 +0200 Subject: [PATCH 28/44] review updates: - cmake documentation - take omp num thread into account for resource file Co-authored-by: Yu-Hsiang M. Tsai --- cmake/create_test.cmake | 5 +++-- test/tools/resource_file_generator.cpp | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cmake/create_test.cmake b/cmake/create_test.cmake index 1d3e041ff2a..2a905570a4b 100644 --- a/cmake/create_test.cmake +++ b/cmake/create_test.cmake @@ -110,8 +110,9 @@ endfunction() ## Adds a test to the list executed by ctest and sets its output binary name ## Possible additional arguments: ## - `MPI_SIZE size` causes the tests to be run with `size` MPI processes. -## - `CORES` the number of threads used by a test, default is 4 -## - `PERCENTAGE` usage percentage of a single GPU, default is 50 +## - `RESOURCE_LOCAL_CORES` the number of threads used by a test, default is 4 +## - `RESOURCE_PERCENTAGE` usage percentage of a single GPU, default is 25 +## - `RESOURCE_TYPE` the resource type, can be ref, cpu, cudagpu, hipgpu, syclgpu ## - `DISABLE_EXECUTORS exec1 exec2` disables the test for certain backends (if built for multiple) ## - `ADDITIONAL_LIBRARIES lib1 lib2` adds additional target link dependencies ## - `ADDITIONAL_INCLUDES path1 path2` adds additional target include paths diff --git a/test/tools/resource_file_generator.cpp b/test/tools/resource_file_generator.cpp index 7db262cf982..a2b0b9bd5cd 100644 --- a/test/tools/resource_file_generator.cpp +++ b/test/tools/resource_file_generator.cpp @@ -48,6 +48,7 @@ std::vector split(const std::string& s, char delimiter = ',') return tokens; } + std::string create_json(const std::string& resources) { std::string json; @@ -73,7 +74,7 @@ std::string create_json(const std::string& resources) int main() { - auto num_cpu_threads = std::max(std::thread::hardware_concurrency(), 1u); + auto num_cpu_threads = gko::OmpExecutor::get_num_omp_threads(); auto num_cuda_gpus = gko::CudaExecutor::get_num_devices(); auto num_hip_gpus = gko::HipExecutor::get_num_devices(); auto num_sycl_gpus = gko::DpcppExecutor::get_num_devices("gpu"); From b84728e6bd85a9b3f0addc836621e09aed3f01cc Mon Sep 17 00:00:00 2001 From: Tobias Ribizel Date: Sat, 26 Aug 2023 22:50:04 +0200 Subject: [PATCH 29/44] use a single SYCL CPU as fall-back --- CMakeLists.txt | 6 ++++++ cmake/create_test.cmake | 17 ++++++++++------- include/ginkgo/core/base/executor.hpp | 2 +- .../core/base/{fwd_defs.hpp => fwd_decls.hpp} | 6 +++--- include/ginkgo/core/base/memory.hpp | 2 +- include/ginkgo/ginkgo.hpp | 2 +- test/tools/resource_file_generator.cpp | 3 ++- 7 files changed, 24 insertions(+), 14 deletions(-) rename include/ginkgo/core/base/{fwd_defs.hpp => fwd_decls.hpp} (94%) diff --git a/CMakeLists.txt b/CMakeLists.txt index a483f09a0d3..307a015d064 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,6 +89,8 @@ option(GINKGO_INSTALL_RPATH_ORIGIN "Add $ORIGIN (Linux) or @loader_path (MacOS) option(GINKGO_INSTALL_RPATH_DEPENDENCIES "Add dependencies to the installation RPATH." OFF) option(GINKGO_FORCE_GPU_AWARE_MPI "Assert that the MPI library is GPU aware. This forces Ginkgo to assume that GPU aware functionality is available (OFF (default) or ON), but may fail catastrophically in case the MPI implementation is not GPU Aware, and GPU aware functionality has been forced" OFF) +set(GINKGO_TEST_OMP_PARALLELISM "4" CACHE STRING + "The number of OpenMP threads to use for a test binary during CTest resource file-constrained test.") # load executor-specific configuration if(GINKGO_BUILD_CUDA) @@ -307,6 +309,10 @@ configure_file(${Ginkgo_SOURCE_DIR}/include/ginkgo/config.hpp.in # propagated to the other parts of Ginkgo in case of building as static libraries add_subdirectory(devices) # Basic device functionalities. Always compiled. add_subdirectory(common) # Import list of unified kernel source files +if(GINKGO_BUILD_TESTS) + # use custom target `tests` to build only test binaries + add_custom_target(tests) +endif() if(GINKGO_BUILD_CUDA) add_subdirectory(cuda) # High-performance kernels for NVIDIA GPUs endif() diff --git a/cmake/create_test.cmake b/cmake/create_test.cmake index 2a905570a4b..f11657ec324 100644 --- a/cmake/create_test.cmake +++ b/cmake/create_test.cmake @@ -73,14 +73,14 @@ function(ginkgo_add_resource_requirement test_name) set(single_resource "cpu:1") elseif(add_rr_RESOURCE_TYPE STREQUAL "cpu") if(NOT add_rr_RESOURCE_LOCAL_CORES) - set(add_rr_RESOURCE_LOCAL_CORES 4) # perhaps get this from environment variable? + set(add_rr_RESOURCE_LOCAL_CORES ${GINKGO_TEST_OMP_PARALLELISM}) endif() if(NOT add_rr_RESOURCE_LOCAL_CORES MATCHES "^[0-9]+") message(FATAL_ERROR "Resource specification is invalid: RESOURCE_LOCAL_CORES=${add_rr_RESOURCE_LOCAL_CORES}") endif() set(single_resource "cpu:${add_rr_RESOURCE_LOCAL_CORES}") - elseif(add_rr_RESOURCE_TYPE MATCHES "^(cuda|hip|sycl)gpu$") + elseif(add_rr_RESOURCE_TYPE MATCHES "^(cudagpu|hipgpu|sycl)$") if(NOT add_rr_RESOURCE_PERCENTAGE) set(add_rr_RESOURCE_PERCENTAGE 25) endif() @@ -95,7 +95,7 @@ function(ginkgo_add_resource_requirement test_name) set(single_resource "${add_rr_RESOURCE_TYPE}:${add_rr_RESOURCE_PERCENTAGE}") else() - message(FATAL_ERROR "Unrecognized resource type ${add_rr_RESOURCE_TYPE}, allowed are: ref, cpu, cudagpu, hipgpu, syclgpu.") + message(FATAL_ERROR "Unrecognized resource type ${add_rr_RESOURCE_TYPE}, allowed are: ref, cpu, cudagpu, hipgpu, sycl.") endif() if(NOT add_rr_MPI_SIZE) @@ -110,9 +110,10 @@ endfunction() ## Adds a test to the list executed by ctest and sets its output binary name ## Possible additional arguments: ## - `MPI_SIZE size` causes the tests to be run with `size` MPI processes. -## - `RESOURCE_LOCAL_CORES` the number of threads used by a test, default is 4 +## - `RESOURCE_LOCAL_CORES` the number of threads used by a test, default is +## $GINKGO_TEST_OMP_PARALLELISM ## - `RESOURCE_PERCENTAGE` usage percentage of a single GPU, default is 25 -## - `RESOURCE_TYPE` the resource type, can be ref, cpu, cudagpu, hipgpu, syclgpu +## - `RESOURCE_TYPE` the resource type, can be ref, cpu, cudagpu, hipgpu, sycl ## - `DISABLE_EXECUTORS exec1 exec2` disables the test for certain backends (if built for multiple) ## - `ADDITIONAL_LIBRARIES lib1 lib2` adds additional target link dependencies ## - `ADDITIONAL_INCLUDES path1 path2` adds additional target include paths @@ -133,6 +134,8 @@ function(ginkgo_add_test test_name test_target_name) COMMAND ${test_target_name} WORKING_DIRECTORY "$") endif() + # use custom target `tests` to build only test binaries + add_dependencies(tests ${test_target_name}) ginkgo_add_resource_requirement(${REL_BINARY_DIR}/${test_name} ${ARGN}) @@ -165,7 +168,7 @@ function(ginkgo_create_dpcpp_test test_name) target_compile_options(${test_target_name} PRIVATE ${GINKGO_DPCPP_FLAGS}) target_link_options(${test_target_name} PRIVATE -fsycl-device-code-split=per_kernel) ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) - ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} RESOURCE_TYPE syclgpu) + ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} RESOURCE_TYPE sycl) # Note: MKL_ENV is empty on linux. Maybe need to apply MKL_ENV to all test. if (MKL_ENV) set_tests_properties(${test_target_name} PROPERTIES ENVIRONMENT "${MKL_ENV}") @@ -304,7 +307,7 @@ function(ginkgo_create_common_test_internal test_name exec_type exec) elseif (exec STREQUAL hip) set(test_resource_type hipgpu) else () - set(test_resource_type syclgpu) + set(test_resource_type sycl) endif () ginkgo_build_test_name(${test_name} test_target_name) string(TOUPPER ${exec} exec_upper) diff --git a/include/ginkgo/core/base/executor.hpp b/include/ginkgo/core/base/executor.hpp index 5f0c307bc73..c7195501178 100644 --- a/include/ginkgo/core/base/executor.hpp +++ b/include/ginkgo/core/base/executor.hpp @@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include +#include #include #include #include diff --git a/include/ginkgo/core/base/fwd_defs.hpp b/include/ginkgo/core/base/fwd_decls.hpp similarity index 94% rename from include/ginkgo/core/base/fwd_defs.hpp rename to include/ginkgo/core/base/fwd_decls.hpp index 5f0cbd9d960..f99d3a0f90e 100644 --- a/include/ginkgo/core/base/fwd_defs.hpp +++ b/include/ginkgo/core/base/fwd_decls.hpp @@ -30,8 +30,8 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *************************************************************/ -#ifndef GKO_PUBLIC_CORE_BASE_FWD_DEFS_HPP_ -#define GKO_PUBLIC_CORE_BASE_FWD_DEFS_HPP_ +#ifndef GKO_PUBLIC_CORE_BASE_FWD_DECLS_HPP_ +#define GKO_PUBLIC_CORE_BASE_FWD_DECLS_HPP_ #include @@ -87,4 +87,4 @@ class event; #endif -#endif // GKO_PUBLIC_CORE_BASE_FWD_DEFS_HPP_ +#endif // GKO_PUBLIC_CORE_BASE_FWD_DECLS_HPP_ diff --git a/include/ginkgo/core/base/memory.hpp b/include/ginkgo/core/base/memory.hpp index f421abf7da4..6997b6351e5 100644 --- a/include/ginkgo/core/base/memory.hpp +++ b/include/ginkgo/core/base/memory.hpp @@ -34,7 +34,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define GKO_PUBLIC_CORE_BASE_MEMORY_HPP_ -#include +#include #include diff --git a/include/ginkgo/ginkgo.hpp b/include/ginkgo/ginkgo.hpp index 594ad880b8c..bcdaa5d2d20 100644 --- a/include/ginkgo/ginkgo.hpp +++ b/include/ginkgo/ginkgo.hpp @@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include -#include +#include #include #include #include diff --git a/test/tools/resource_file_generator.cpp b/test/tools/resource_file_generator.cpp index a2b0b9bd5cd..f0dbbea0353 100644 --- a/test/tools/resource_file_generator.cpp +++ b/test/tools/resource_file_generator.cpp @@ -100,7 +100,8 @@ int main() }; add_devices(num_cuda_gpus, "cudagpu"); add_devices(num_hip_gpus, "hipgpu"); - add_devices(num_sycl_gpus, "syclgpu"); + // SYCL GPUs, fall back to CPU + add_devices(std::max(1, num_sycl_gpus), "sycl"); std::cout << create_json(cpus + gpus) << std::endl; } From d05da302b8eb6ec1139bcd49176078a37e9710b4 Mon Sep 17 00:00:00 2001 From: Tobias Ribizel Date: Sat, 26 Aug 2023 22:56:33 +0200 Subject: [PATCH 30/44] fix OMP environment --- core/test/gtest/environments.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/test/gtest/environments.hpp b/core/test/gtest/environments.hpp index 2d0d1eac33a..815902d71a8 100644 --- a/core/test/gtest/environments.hpp +++ b/core/test/gtest/environments.hpp @@ -170,7 +170,7 @@ class OmpEnvironment : public ::testing::Environment { omp_set_num_threads(ResourceEnvironment::omp_threads); } #pragma omp parallel -#pragma single +#pragma omp single std::cerr << "Rank " << rank_ << ": OMP threads " << omp_get_num_threads() << std::endl; } From 959618a119aad03e13e50d3ea8505c308880fd76 Mon Sep 17 00:00:00 2001 From: Tobias Ribizel Date: Thu, 31 Aug 2023 11:10:39 +0200 Subject: [PATCH 31/44] create separate GTest main libraries --- cmake/create_test.cmake | 41 ++--- core/test/CMakeLists.txt | 2 + core/test/gtest/CMakeLists.txt | 30 ++++ core/test/gtest/environments.hpp | 231 +++++----------------------- core/test/gtest/ginkgo_main.cpp | 5 +- core/test/gtest/ginkgo_mpi_main.cpp | 7 +- core/test/gtest/resources.cpp | 145 +++++++++++++++++ core/test/gtest/resources.hpp | 51 ++++++ cuda/test/utils.hpp | 2 +- hip/test/utils.hip.hpp | 2 +- test/utils/executor.hpp | 2 +- 11 files changed, 285 insertions(+), 233 deletions(-) create mode 100644 core/test/gtest/CMakeLists.txt create mode 100644 core/test/gtest/resources.cpp create mode 100644 core/test/gtest/resources.hpp diff --git a/cmake/create_test.cmake b/cmake/create_test.cmake index f11657ec324..baaf84f59eb 100644 --- a/cmake/create_test.cmake +++ b/cmake/create_test.cmake @@ -11,26 +11,9 @@ function(ginkgo_build_test_name test_name target_name) set(${target_name} ${TEST_TARGET_NAME} PARENT_SCOPE) endfunction() -function(ginkgo_create_gtest_main) - add_library(ginkgo_gtest_main "") - target_sources(ginkgo_gtest_main - PRIVATE - ${PROJECT_SOURCE_DIR}/core/test/gtest/ginkgo_main.cpp) - target_link_libraries(ginkgo_gtest_main PRIVATE GTest::GTest Ginkgo::ginkgo) -endfunction() - -function(ginkgo_create_gtest_mpi_main) - add_library(ginkgo_gtest_mpi_main "") - target_sources(ginkgo_gtest_mpi_main - PRIVATE - ${PROJECT_SOURCE_DIR}/core/test/gtest/ginkgo_mpi_main.cpp) - find_package(MPI 3.1 COMPONENTS CXX REQUIRED) - target_link_libraries(ginkgo_gtest_mpi_main PRIVATE GTest::GTest MPI::MPI_CXX Ginkgo::ginkgo) -endfunction() - ## Set up shared target properties and handle ADDITIONAL_LIBRARIES/ADDITIONAL_INCLUDES ## `MPI_SIZE size` causes the tests to be run with `size` MPI processes. -function(ginkgo_set_test_target_properties test_target_name) +function(ginkgo_set_test_target_properties test_target_name test_library_suffix) cmake_parse_arguments(PARSE_ARGV 1 set_properties "" "${gko_test_single_args}" "${gko_test_multi_args}") if (GINKGO_FAST_TESTS) target_compile_definitions(${test_target_name} PRIVATE GINKGO_FAST_TESTS) @@ -42,16 +25,12 @@ function(ginkgo_set_test_target_properties test_target_name) target_compile_definitions(${test_target_name} PRIVATE GINKGO_DPCPP_SINGLE_MODE=1) endif() if(GINKGO_CHECK_CIRCULAR_DEPS) - target_link_libraries(${test_target_name} PRIVATE "${GINKGO_CIRCULAR_DEPS_FLAGS}") + target_link_libraries(${test_target_name} PRIVATE "${GINKGO_CIRCULAR_DEPS_FLAGS}") endif() if(set_properties_MPI_SIZE) - target_sources(${test_target_name} - PRIVATE - ${PROJECT_SOURCE_DIR}/core/test/gtest/ginkgo_mpi_main.cpp) + target_link_libraries(${test_target_name} PRIVATE ginkgo_gtest_main_mpi${test_library_suffix}) else() - target_sources(${test_target_name} - PRIVATE - ${PROJECT_SOURCE_DIR}/core/test/gtest/ginkgo_main.cpp) + target_link_libraries(${test_target_name} PRIVATE ginkgo_gtest_main${test_library_suffix}) endif() target_compile_features(${test_target_name} PUBLIC cxx_std_14) target_compile_options(${test_target_name} PRIVATE $<$:${GINKGO_COMPILER_FLAGS}>) @@ -156,7 +135,7 @@ function(ginkgo_create_test test_name) ginkgo_build_test_name(${test_name} test_target_name) add_executable(${test_target_name} ${test_name}.cpp) target_link_libraries(${test_target_name}) - ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) + ginkgo_set_test_target_properties(${test_target_name} "" ${ARGN}) ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} RESOURCE_TYPE ref) endfunction(ginkgo_create_test) @@ -167,7 +146,7 @@ function(ginkgo_create_dpcpp_test test_name) target_compile_features(${test_target_name} PUBLIC cxx_std_17) target_compile_options(${test_target_name} PRIVATE ${GINKGO_DPCPP_FLAGS}) target_link_options(${test_target_name} PRIVATE -fsycl-device-code-split=per_kernel) - ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) + ginkgo_set_test_target_properties(${test_target_name} "_dpcpp" ${ARGN}) ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} RESOURCE_TYPE sycl) # Note: MKL_ENV is empty on linux. Maybe need to apply MKL_ENV to all test. if (MKL_ENV) @@ -201,7 +180,7 @@ function(ginkgo_create_cuda_test_internal test_name filename test_target_name) if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.18) set_target_properties(${test_target_name} PROPERTIES CUDA_ARCHITECTURES OFF) endif() - ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) + ginkgo_set_test_target_properties(${test_target_name} "_cuda" ${ARGN}) ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} RESOURCE_TYPE cudagpu) endfunction(ginkgo_create_cuda_test_internal) @@ -257,7 +236,7 @@ function(ginkgo_create_hip_test_internal test_name filename test_target_name add ${hiprand_INCLUDE_DIRS} ${HIPSPARSE_INCLUDE_DIRS} ) - ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) + ginkgo_set_test_target_properties(${test_target_name} "_hip" ${ARGN}) ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} RESOURCE_TYPE hipgpu) endfunction(ginkgo_create_hip_test_internal) @@ -273,7 +252,7 @@ function(ginkgo_create_omp_test_internal test_name filename test_target_name) add_executable(${test_target_name} ${test_name}.cpp) target_compile_definitions(${test_target_name} PRIVATE GKO_COMPILING_OMP) target_link_libraries(${test_target_name} PRIVATE OpenMP::OpenMP_CXX) - ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) + ginkgo_set_test_target_properties(${test_target_name} "_omp" ${ARGN}) ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} RESOURCE_TYPE cpu) endfunction() @@ -328,7 +307,7 @@ function(ginkgo_create_common_test_internal test_name exec_type exec) target_compile_definitions(${test_target_name} PRIVATE GINKGO_COMMON_SINGLE_MODE=1) target_compile_definitions(${test_target_name} PRIVATE GINKGO_DPCPP_SINGLE_MODE=1) endif() - ginkgo_set_test_target_properties(${test_target_name} ${ARGN}) + ginkgo_set_test_target_properties(${test_target_name} "_${exec}" ${ARGN}) ginkgo_add_test(${test_name}_${exec} ${test_target_name} ${ARGN} RESOURCE_TYPE ${test_resource_type}) endfunction(ginkgo_create_common_test_internal) diff --git a/core/test/CMakeLists.txt b/core/test/CMakeLists.txt index b330a493b38..776d0b72c7d 100644 --- a/core/test/CMakeLists.txt +++ b/core/test/CMakeLists.txt @@ -1,5 +1,7 @@ include(${PROJECT_SOURCE_DIR}/cmake/create_test.cmake) +add_subdirectory(gtest) + add_subdirectory(accessor) add_subdirectory(base) add_subdirectory(components) diff --git a/core/test/gtest/CMakeLists.txt b/core/test/gtest/CMakeLists.txt new file mode 100644 index 00000000000..43bb6863224 --- /dev/null +++ b/core/test/gtest/CMakeLists.txt @@ -0,0 +1,30 @@ +function(add_gtest_main suffix definitions) + add_library(ginkgo_gtest_main${suffix} ginkgo_main.cpp resources.cpp) + target_link_libraries(ginkgo_gtest_main${suffix} PUBLIC Ginkgo::ginkgo GTest::GTest) + target_compile_definitions(ginkgo_gtest_main${suffix} PRIVATE ${definitions}) + ginkgo_compile_features(ginkgo_gtest_main${suffix}) + if (GINKGO_BUILD_MPI) + add_library(ginkgo_gtest_main_mpi${suffix} ginkgo_mpi_main.cpp resources.cpp) + target_link_libraries(ginkgo_gtest_main_mpi${suffix} PUBLIC Ginkgo::ginkgo GTest::GTest MPI::MPI_CXX) + target_compile_definitions(ginkgo_gtest_main_mpi${suffix} PRIVATE ${definitions}) + ginkgo_compile_features(ginkgo_gtest_main_mpi${suffix}) + endif() +endfunction() + +add_gtest_main("" "") +add_library(ginkgo_gtest_main_reference ALIAS ginkgo_gtest_main) +if (GINKGO_BUILD_MPI) + add_library(ginkgo_gtest_main_mpi_reference ALIAS ginkgo_gtest_main_mpi) +endif() +if (GINKGO_BUILD_OMP) + add_gtest_main("_omp" "GKO_COMPILING_OMP") +endif() +if (GINKGO_BUILD_CUDA) + add_gtest_main("_cuda" "GKO_COMPILING_CUDA") +endif() +if (GINKGO_BUILD_HIP) + add_gtest_main("_hip" "GKO_COMPILING_HIP") +endif() +if (GINKGO_BUILD_DPCPP) + add_gtest_main("_dpcpp" "GKO_COMPILING_DPCPP") +endif() diff --git a/core/test/gtest/environments.hpp b/core/test/gtest/environments.hpp index 815902d71a8..89166a0594c 100644 --- a/core/test/gtest/environments.hpp +++ b/core/test/gtest/environments.hpp @@ -35,11 +35,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include #include +#include +#include +#include + + +#include "core/test/gtest/resources.hpp" + + #ifdef GKO_COMPILING_OMP #include #endif @@ -60,228 +69,68 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endif -#include -#include -#include - - -struct ctest_resource { - int id; - int slots; -}; - - -inline char* get_ctest_group(std::string resource_type, int group_id) -{ - std::transform(resource_type.begin(), resource_type.end(), - resource_type.begin(), - [](auto c) { return std::toupper(c); }); - std::string rs_group_env = "CTEST_RESOURCE_GROUP_" + - std::to_string(group_id) + "_" + resource_type; - return std::getenv(rs_group_env.c_str()); -} - - -inline ctest_resource parse_ctest_resources(std::string resource) -{ - std::regex re(R"(id\:(\d+),slots\:(\d+))"); - std::smatch match; - - if (!std::regex_match(resource, match, re)) { - GKO_INVALID_STATE("Can't parse ctest_resource string: " + resource); - } - - return ctest_resource{std::stoi(match[1]), std::stoi(match[2])}; -} - - -class ResourceEnvironment : public ::testing::Environment { +class DeviceEnvironment : public ::testing::Environment { public: - explicit ResourceEnvironment(int rank = 0, int size = 1) - { -#if GINKGO_BUILD_MPI - if (size > 1) { - cuda_device_id = gko::experimental::mpi::map_rank_to_device_id( - MPI_COMM_WORLD, - std::max(gko::CudaExecutor::get_num_devices(), 1)); - hip_device_id = gko::experimental::mpi::map_rank_to_device_id( - MPI_COMM_WORLD, - std::max(gko::HipExecutor::get_num_devices(), 1)); - sycl_device_id = gko::experimental::mpi::map_rank_to_device_id( - MPI_COMM_WORLD, - std::max(gko::DpcppExecutor::get_num_devices("gpu"), 1)); - } -#endif - - auto rs_count_env = std::getenv("CTEST_RESOURCE_GROUP_COUNT"); - auto rs_count = rs_count_env ? std::stoi(rs_count_env) : 0; - if (rs_count == 0) { - if (rank == 0) { - std::cerr - << "Running without CTest ctest_resource configuration" - << std::endl; - } - return; - } - if (rs_count != size) { - GKO_INVALID_STATE("Invalid resource group count: " + - std::to_string(rs_count)); - } - - // parse CTest ctest_resource group descriptions - // OpenMP CPU threads - if (auto rs_omp_env = get_ctest_group("cpu", rank)) { - auto resource = parse_ctest_resources(rs_omp_env); - omp_threads = resource.slots; - } - // CUDA GPUs - if (auto rs_cuda_env = get_ctest_group("cudagpu", rank)) { - auto resource = parse_ctest_resources(rs_cuda_env); - cuda_device_id = resource.id; - } - // HIP GPUs - if (auto rs_hip_env = get_ctest_group("hipgpu", rank)) { - auto resource = parse_ctest_resources(rs_hip_env); - hip_device_id = resource.id; - } - // SYCL GPUs (no other devices!) - if (auto rs_sycl_env = get_ctest_group("syclgpu", rank)) { - auto resource = parse_ctest_resources(rs_sycl_env); - sycl_device_id = resource.id; - } - } - - static int omp_threads; - static int cuda_device_id; - static int hip_device_id; - static int sycl_device_id; -}; - + explicit DeviceEnvironment(int rank) : rank_(rank) { print_environment(); } #ifdef GKO_COMPILING_OMP - -class OmpEnvironment : public ::testing::Environment { -public: - explicit OmpEnvironment(int rank) : rank_(rank) {} - - void SetUp() override + void print_environment() const { if (ResourceEnvironment::omp_threads > 0) { omp_set_num_threads(ResourceEnvironment::omp_threads); } -#pragma omp parallel -#pragma omp single - std::cerr << "Rank " << rank_ << ": OMP threads " - << omp_get_num_threads() << std::endl; + std::stringstream ss; + ss << "Rank " << rank_ << ": OMP threads " << omp_get_max_threads() + << std::endl; + std::cerr << ss.str(); } - -private: - int rank_; -}; - -#else - - -class OmpEnvironment : public ::testing::Environment { -public: - explicit OmpEnvironment(int){}; -}; - -#endif - - -#ifdef GKO_COMPILING_CUDA - -class CudaEnvironment : public ::testing::Environment { -public: - explicit CudaEnvironment(int rank) : rank_(rank) {} - - void SetUp() override +#elif defined(GKO_COMPILING_CUDA) + void print_environment() const { auto device_id = ResourceEnvironment::cuda_device_id; - std::cerr << "Rank " << rank_ << ": CUDA device " - << gko::kernels::cuda::get_device_name(device_id) << " ID " - << device_id << std::endl; + std::stringstream ss; + ss << "Rank " << rank_ << ": CUDA device " + << gko::kernels::cuda::get_device_name(device_id) << " ID " + << device_id << std::endl; + std::cerr << ss.str(); } void TearDown() override { gko::kernels::cuda::reset_device(ResourceEnvironment::cuda_device_id); } - -private: - int rank_; -}; - -#else - -class CudaEnvironment : public ::testing::Environment { -public: - explicit CudaEnvironment(int){}; -}; - -#endif - - -#ifdef GKO_COMPILING_HIP - -class HipEnvironment : public ::testing::Environment { -public: - explicit HipEnvironment(int rank) : rank_(rank) {} - - void SetUp() override +#elif defined(GKO_COMPILING_HIP) + void print_environment() const { auto device_id = ResourceEnvironment::hip_device_id; - std::cerr << "Rank " << rank_ << ": HIP device " - << gko::kernels::hip::get_device_name(device_id) << " ID " - << device_id << std::endl; + std::stringstream ss; + ss << "Rank " << rank_ << ": HIP device " + << gko::kernels::hip::get_device_name(device_id) << " ID " + << device_id << std::endl; + std::cerr << ss.str(); } void TearDown() override { gko::kernels::hip::reset_device(ResourceEnvironment::hip_device_id); } - -private: - int rank_; -}; - -#else - -class HipEnvironment : public ::testing::Environment { -public: - explicit HipEnvironment(int){}; -}; - -#endif - - -#ifdef GKO_COMPILING_DPCPP - -class SyclEnvironment : public ::testing::Environment { -public: - explicit SyclEnvironment(int rank) : rank_(rank) {} - - void SetUp() override +#elif defined(GKO_COMPILING_DPCPP) + void print_environment() const { auto device_id = ResourceEnvironment::sycl_device_id; - std::cerr << "Rank " << rank_ << ": SYCL device " - << gko::kernels::dpcpp::get_device_name(device_id) << " ID " - << device_id << std::endl; + std::stringstream ss; + ss << "Rank " << rank_ << ": SYCL device " + << gko::kernels::dpcpp::get_device_name(device_id) << " ID " + << device_id << std::endl; + std::cerr << ss.str(); } +#else + void print_environment() const {} +#endif private: int rank_; }; -#else - -class SyclEnvironment : public ::testing::Environment { -public: - explicit SyclEnvironment(int){}; -}; - -#endif - #endif // GKO_CORE_TEST_GTEST_ENVIRONMENTS_HPP_ diff --git a/core/test/gtest/ginkgo_main.cpp b/core/test/gtest/ginkgo_main.cpp index 01d1fc393c3..b8458dbc0b0 100644 --- a/core/test/gtest/ginkgo_main.cpp +++ b/core/test/gtest/ginkgo_main.cpp @@ -47,10 +47,7 @@ int main(int argc, char** argv) ::testing::InitGoogleTest(&argc, argv); ::testing::AddGlobalTestEnvironment(new ResourceEnvironment); - ::testing::AddGlobalTestEnvironment(new CudaEnvironment(0)); - ::testing::AddGlobalTestEnvironment(new HipEnvironment(0)); - ::testing::AddGlobalTestEnvironment(new SyclEnvironment(0)); - ::testing::AddGlobalTestEnvironment(new OmpEnvironment(0)); + ::testing::AddGlobalTestEnvironment(new DeviceEnvironment(0)); int result = RUN_ALL_TESTS(); return result; } diff --git a/core/test/gtest/ginkgo_mpi_main.cpp b/core/test/gtest/ginkgo_mpi_main.cpp index f7fe71981d2..c34d3c84693 100644 --- a/core/test/gtest/ginkgo_mpi_main.cpp +++ b/core/test/gtest/ginkgo_mpi_main.cpp @@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +#include #include @@ -394,10 +395,8 @@ int main(int argc, char** argv) testing::AddGlobalTestEnvironment(new GTestMPIListener::MPIEnvironment); ::testing::AddGlobalTestEnvironment(new ResourceEnvironment(rank, size)); - ::testing::AddGlobalTestEnvironment(new CudaEnvironment(rank)); - ::testing::AddGlobalTestEnvironment(new HipEnvironment(rank)); - ::testing::AddGlobalTestEnvironment(new SyclEnvironment(rank)); - ::testing::AddGlobalTestEnvironment(new OmpEnvironment(rank)); + ::testing::AddGlobalTestEnvironment(new DeviceEnvironment(rank)); + MPI_Barrier(comm); ::testing::TestEventListeners& listeners = ::testing::UnitTest::GetInstance()->listeners(); diff --git a/core/test/gtest/resources.cpp b/core/test/gtest/resources.cpp new file mode 100644 index 00000000000..2bd0cdc3496 --- /dev/null +++ b/core/test/gtest/resources.cpp @@ -0,0 +1,145 @@ +/************************************************************* +Copyright (c) 2017-2023, the Ginkgo authors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. 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. + +3. Neither the name of the copyright holder 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 AND CONTRIBUTORS "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 +HOLDER 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. +*************************************************************/ + +#include "core/test/gtest/resources.hpp" + + +#include +#include +#include + + +#ifdef GKO_COMPILING_OMP +#include +#endif + + +#ifdef GKO_COMPILING_CUDA +#include "cuda/base/device.hpp" +#endif + + +#ifdef GKO_COMPILING_HIP +#include "hip/base/device.hpp" +#endif + + +#if GKO_COMPILING_DPCPP +#include "dpcpp/base/device.hpp" +#endif + + +#include +#include +#include + + +struct ctest_resource { + int id; + int slots; +}; + + +char* get_ctest_group(std::string resource_type, int group_id) +{ + std::transform(resource_type.begin(), resource_type.end(), + resource_type.begin(), + [](auto c) { return std::toupper(c); }); + std::string rs_group_env = "CTEST_RESOURCE_GROUP_" + + std::to_string(group_id) + "_" + resource_type; + return std::getenv(rs_group_env.c_str()); +} + + +ctest_resource parse_ctest_resources(std::string resource) +{ + std::regex re(R"(id\:(\d+),slots\:(\d+))"); + std::smatch match; + + if (!std::regex_match(resource, match, re)) { + GKO_INVALID_STATE("Can't parse ctest_resource string: " + resource); + } + + return ctest_resource{std::stoi(match[1]), std::stoi(match[2])}; +} + + +ResourceEnvironment::ResourceEnvironment(int rank, int size) +{ +#if GINKGO_BUILD_MPI + if (size > 1) { + cuda_device_id = gko::experimental::mpi::map_rank_to_device_id( + MPI_COMM_WORLD, std::max(gko::CudaExecutor::get_num_devices(), 1)); + hip_device_id = gko::experimental::mpi::map_rank_to_device_id( + MPI_COMM_WORLD, std::max(gko::HipExecutor::get_num_devices(), 1)); + sycl_device_id = gko::experimental::mpi::map_rank_to_device_id( + MPI_COMM_WORLD, + std::max(gko::DpcppExecutor::get_num_devices("gpu"), 1)); + } +#endif + + auto rs_count_env = std::getenv("CTEST_RESOURCE_GROUP_COUNT"); + auto rs_count = rs_count_env ? std::stoi(rs_count_env) : 0; + if (rs_count == 0) { + if (rank == 0) { + std::cerr << "Running without CTest ctest_resource configuration" + << std::endl; + } + return; + } + if (rs_count != size) { + GKO_INVALID_STATE("Invalid resource group count: " + + std::to_string(rs_count)); + } + + // parse CTest ctest_resource group descriptions + // OpenMP CPU threads + if (auto rs_omp_env = get_ctest_group("cpu", rank)) { + auto resource = parse_ctest_resources(rs_omp_env); + omp_threads = resource.slots; + } + // CUDA GPUs + if (auto rs_cuda_env = get_ctest_group("cudagpu", rank)) { + auto resource = parse_ctest_resources(rs_cuda_env); + cuda_device_id = resource.id; + } + // HIP GPUs + if (auto rs_hip_env = get_ctest_group("hipgpu", rank)) { + auto resource = parse_ctest_resources(rs_hip_env); + hip_device_id = resource.id; + } + // SYCL GPUs (no other devices!) + if (auto rs_sycl_env = get_ctest_group("syclgpu", rank)) { + auto resource = parse_ctest_resources(rs_sycl_env); + sycl_device_id = resource.id; + } +} diff --git a/core/test/gtest/resources.hpp b/core/test/gtest/resources.hpp new file mode 100644 index 00000000000..a88280f29c7 --- /dev/null +++ b/core/test/gtest/resources.hpp @@ -0,0 +1,51 @@ +/************************************************************* +Copyright (c) 2017-2023, the Ginkgo authors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. 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. + +3. Neither the name of the copyright holder 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 AND CONTRIBUTORS "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 +HOLDER 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. +*************************************************************/ + +#ifndef GKO_CORE_TEST_GTEST_RESOURCES_HPP_ +#define GKO_CORE_TEST_GTEST_RESOURCES_HPP_ + + +#include + + +class ResourceEnvironment : public ::testing::Environment { +public: + explicit ResourceEnvironment(int rank = 0, int size = 1); + + static int omp_threads; + static int cuda_device_id; + static int hip_device_id; + static int sycl_device_id; +}; + + +#endif // GKO_CORE_TEST_GTEST_RESOURCES_HPP_ diff --git a/cuda/test/utils.hpp b/cuda/test/utils.hpp index 35f382806ec..6ef808aa1b3 100644 --- a/cuda/test/utils.hpp +++ b/cuda/test/utils.hpp @@ -41,7 +41,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include "core/test/gtest/environments.hpp" +#include "core/test/gtest/resources.hpp" #include "cuda/base/device.hpp" diff --git a/hip/test/utils.hip.hpp b/hip/test/utils.hip.hpp index d67c8935ab4..e1c9f9341fb 100644 --- a/hip/test/utils.hip.hpp +++ b/hip/test/utils.hip.hpp @@ -41,7 +41,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include "core/test/gtest/environments.hpp" +#include "core/test/gtest/resources.hpp" #include "hip/base/device.hpp" diff --git a/test/utils/executor.hpp b/test/utils/executor.hpp index 2a8ace8e39a..e4ce56f3d7a 100644 --- a/test/utils/executor.hpp +++ b/test/utils/executor.hpp @@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include "core/test/gtest/environments.hpp" +#include "core/test/gtest/resources.hpp" #if GINKGO_COMMON_SINGLE_MODE From 5675ceed13e29663bdd755038fb195c057618060 Mon Sep 17 00:00:00 2001 From: ginkgo-bot Date: Thu, 31 Aug 2023 09:20:51 +0000 Subject: [PATCH 32/44] Format files Co-authored-by: Tobias Ribizel --- core/test/gtest/environments.hpp | 1 + core/test/gtest/ginkgo_mpi_main.cpp | 4 +++- core/test/gtest/resources.cpp | 6 +++--- omp/base/executor.cpp | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/core/test/gtest/environments.hpp b/core/test/gtest/environments.hpp index 89166a0594c..78c5a40f8a5 100644 --- a/core/test/gtest/environments.hpp +++ b/core/test/gtest/environments.hpp @@ -33,6 +33,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef GKO_CORE_TEST_GTEST_ENVIRONMENTS_HPP_ #define GKO_CORE_TEST_GTEST_ENVIRONMENTS_HPP_ + #include #include #include diff --git a/core/test/gtest/ginkgo_mpi_main.cpp b/core/test/gtest/ginkgo_mpi_main.cpp index c34d3c84693..12107ca55f8 100644 --- a/core/test/gtest/ginkgo_mpi_main.cpp +++ b/core/test/gtest/ginkgo_mpi_main.cpp @@ -45,10 +45,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include #include +#include + + #include diff --git a/core/test/gtest/resources.cpp b/core/test/gtest/resources.cpp index 2bd0cdc3496..dc8ad7931a9 100644 --- a/core/test/gtest/resources.cpp +++ b/core/test/gtest/resources.cpp @@ -30,14 +30,14 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *************************************************************/ -#include "core/test/gtest/resources.hpp" - - #include #include #include +#include "core/test/gtest/resources.hpp" + + #ifdef GKO_COMPILING_OMP #include #endif diff --git a/omp/base/executor.cpp b/omp/base/executor.cpp index 3e14270ecdc..49fd1332ed5 100644 --- a/omp/base/executor.cpp +++ b/omp/base/executor.cpp @@ -49,4 +49,4 @@ int OmpExecutor::get_num_omp_threads() } -} // namespace gko \ No newline at end of file +} // namespace gko From 4c2defa83bba8b71f53da49a066b95861702e1d0 Mon Sep 17 00:00:00 2001 From: Tobias Ribizel Date: Fri, 1 Sep 2023 16:47:38 +0200 Subject: [PATCH 33/44] link against GTest main statically --- core/test/gtest/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/test/gtest/CMakeLists.txt b/core/test/gtest/CMakeLists.txt index 43bb6863224..c4e9cb52870 100644 --- a/core/test/gtest/CMakeLists.txt +++ b/core/test/gtest/CMakeLists.txt @@ -1,10 +1,10 @@ function(add_gtest_main suffix definitions) - add_library(ginkgo_gtest_main${suffix} ginkgo_main.cpp resources.cpp) + add_library(ginkgo_gtest_main${suffix} STATIC ginkgo_main.cpp resources.cpp) target_link_libraries(ginkgo_gtest_main${suffix} PUBLIC Ginkgo::ginkgo GTest::GTest) target_compile_definitions(ginkgo_gtest_main${suffix} PRIVATE ${definitions}) ginkgo_compile_features(ginkgo_gtest_main${suffix}) if (GINKGO_BUILD_MPI) - add_library(ginkgo_gtest_main_mpi${suffix} ginkgo_mpi_main.cpp resources.cpp) + add_library(ginkgo_gtest_main_mpi${suffix} STATIC ginkgo_mpi_main.cpp resources.cpp) target_link_libraries(ginkgo_gtest_main_mpi${suffix} PUBLIC Ginkgo::ginkgo GTest::GTest MPI::MPI_CXX) target_compile_definitions(ginkgo_gtest_main_mpi${suffix} PRIVATE ${definitions}) ginkgo_compile_features(ginkgo_gtest_main_mpi${suffix}) From 8fad906cf9a20eaff3c3e83f4858a8113ef4f1c9 Mon Sep 17 00:00:00 2001 From: Tobias Ribizel Date: Fri, 1 Sep 2023 16:54:33 +0200 Subject: [PATCH 34/44] use nla-gpu1 for ROCm tests as well --- .gitlab/image.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.gitlab/image.yml b/.gitlab/image.yml index 72fb51ad372..eb1ab5128af 100644 --- a/.gitlab/image.yml +++ b/.gitlab/image.yml @@ -72,15 +72,13 @@ image: ginkgohub/rocm:45-mvapich2-gnu8-llvm8 tags: - private_ci - - amdci - - gpu + - amd-gpu .use_gko-rocm502-nompi-gnu11-llvm11: image: ginkgohub/rocm:502-openmpi-gnu11-llvm11 tags: - private_ci - - amdci - - gpu + - amd-gpu .use_gko-oneapi-cpu: image: ginkgohub/oneapi:2022.1 From 6ff4c3e59a73cbeb52e6fdb3a0c3b54608d892d4 Mon Sep 17 00:00:00 2001 From: Tobias Ribizel Date: Thu, 7 Sep 2023 10:21:07 +0100 Subject: [PATCH 35/44] review updates - formatting - remove remaining occurrences of syclgpu - rename to GINKGO_CI_TEST_OMP_PARALLELISM Co-authored-by: Yuhsiang M. Tsai --- CMakeLists.txt | 2 +- cmake/create_test.cmake | 12 ++++++------ core/test/CMakeLists.txt | 1 - core/test/gtest/resources.cpp | 2 +- cuda/test/base/CMakeLists.txt | 2 +- omp/CMakeLists.txt | 2 +- 6 files changed, 10 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 307a015d064..5a9d901dee8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,7 +89,7 @@ option(GINKGO_INSTALL_RPATH_ORIGIN "Add $ORIGIN (Linux) or @loader_path (MacOS) option(GINKGO_INSTALL_RPATH_DEPENDENCIES "Add dependencies to the installation RPATH." OFF) option(GINKGO_FORCE_GPU_AWARE_MPI "Assert that the MPI library is GPU aware. This forces Ginkgo to assume that GPU aware functionality is available (OFF (default) or ON), but may fail catastrophically in case the MPI implementation is not GPU Aware, and GPU aware functionality has been forced" OFF) -set(GINKGO_TEST_OMP_PARALLELISM "4" CACHE STRING +set(GINKGO_CI_TEST_OMP_PARALLELISM "4" CACHE STRING "The number of OpenMP threads to use for a test binary during CTest resource file-constrained test.") # load executor-specific configuration diff --git a/cmake/create_test.cmake b/cmake/create_test.cmake index baaf84f59eb..50271e12c9c 100644 --- a/cmake/create_test.cmake +++ b/cmake/create_test.cmake @@ -5,10 +5,10 @@ set(gko_test_option_args "NO_RESOURCES") ## Replaces / by _ to create valid target names from relative paths function(ginkgo_build_test_name test_name target_name) - file(RELATIVE_PATH REL_BINARY_DIR - ${PROJECT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}) - string(REPLACE "/" "_" TEST_TARGET_NAME "${REL_BINARY_DIR}/${test_name}") - set(${target_name} ${TEST_TARGET_NAME} PARENT_SCOPE) + file(RELATIVE_PATH REL_BINARY_DIR + ${PROJECT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + string(REPLACE "/" "_" TEST_TARGET_NAME "${REL_BINARY_DIR}/${test_name}") + set(${target_name} ${TEST_TARGET_NAME} PARENT_SCOPE) endfunction() ## Set up shared target properties and handle ADDITIONAL_LIBRARIES/ADDITIONAL_INCLUDES @@ -52,7 +52,7 @@ function(ginkgo_add_resource_requirement test_name) set(single_resource "cpu:1") elseif(add_rr_RESOURCE_TYPE STREQUAL "cpu") if(NOT add_rr_RESOURCE_LOCAL_CORES) - set(add_rr_RESOURCE_LOCAL_CORES ${GINKGO_TEST_OMP_PARALLELISM}) + set(add_rr_RESOURCE_LOCAL_CORES ${GINKGO_CI_TEST_OMP_PARALLELISM}) endif() if(NOT add_rr_RESOURCE_LOCAL_CORES MATCHES "^[0-9]+") message(FATAL_ERROR "Resource specification is invalid: RESOURCE_LOCAL_CORES=${add_rr_RESOURCE_LOCAL_CORES}") @@ -90,7 +90,7 @@ endfunction() ## Possible additional arguments: ## - `MPI_SIZE size` causes the tests to be run with `size` MPI processes. ## - `RESOURCE_LOCAL_CORES` the number of threads used by a test, default is -## $GINKGO_TEST_OMP_PARALLELISM +## $GINKGO_CI_TEST_OMP_PARALLELISM ## - `RESOURCE_PERCENTAGE` usage percentage of a single GPU, default is 25 ## - `RESOURCE_TYPE` the resource type, can be ref, cpu, cudagpu, hipgpu, sycl ## - `DISABLE_EXECUTORS exec1 exec2` disables the test for certain backends (if built for multiple) diff --git a/core/test/CMakeLists.txt b/core/test/CMakeLists.txt index 776d0b72c7d..69f7ddd749e 100644 --- a/core/test/CMakeLists.txt +++ b/core/test/CMakeLists.txt @@ -1,7 +1,6 @@ include(${PROJECT_SOURCE_DIR}/cmake/create_test.cmake) add_subdirectory(gtest) - add_subdirectory(accessor) add_subdirectory(base) add_subdirectory(components) diff --git a/core/test/gtest/resources.cpp b/core/test/gtest/resources.cpp index dc8ad7931a9..0dd427b75ee 100644 --- a/core/test/gtest/resources.cpp +++ b/core/test/gtest/resources.cpp @@ -138,7 +138,7 @@ ResourceEnvironment::ResourceEnvironment(int rank, int size) hip_device_id = resource.id; } // SYCL GPUs (no other devices!) - if (auto rs_sycl_env = get_ctest_group("syclgpu", rank)) { + if (auto rs_sycl_env = get_ctest_group("sycl", rank)) { auto resource = parse_ctest_resources(rs_sycl_env); sycl_device_id = resource.id; } diff --git a/cuda/test/base/CMakeLists.txt b/cuda/test/base/CMakeLists.txt index bb99ba858a4..174f4533c52 100644 --- a/cuda/test/base/CMakeLists.txt +++ b/cuda/test/base/CMakeLists.txt @@ -4,7 +4,7 @@ ginkgo_create_cuda_test(index_set) if(GINKGO_HAVE_HWLOC) find_package(NUMA REQUIRED) ginkgo_create_cuda_test(cuda_executor_topology ADDITIONAL_LIBRARIES NUMA::NUMA) -endif () +endif() ginkgo_create_cuda_test(exception_helpers) ginkgo_create_cuda_test(kernel_launch) ginkgo_create_cuda_test(lin_op) diff --git a/omp/CMakeLists.txt b/omp/CMakeLists.txt index 7f46feff5da..47259feeac0 100644 --- a/omp/CMakeLists.txt +++ b/omp/CMakeLists.txt @@ -5,7 +5,7 @@ target_sources(ginkgo_omp PRIVATE base/batch_multi_vector_kernels.cpp base/device_matrix_data_kernels.cpp - base/executor.cpp + base/executor.cpp base/index_set_kernels.cpp base/scoped_device_id.cpp base/version.cpp From 30b91bbea5ec3da5ddc1e0adb0cba6de97938f8b Mon Sep 17 00:00:00 2001 From: Tobias Ribizel Date: Wed, 13 Sep 2023 10:38:15 +0200 Subject: [PATCH 36/44] use slots instead of percentages for GPUs --- cmake/create_test.cmake | 17 ++--------------- test/tools/resource_file_generator.cpp | 2 +- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/cmake/create_test.cmake b/cmake/create_test.cmake index 50271e12c9c..375135dcb13 100644 --- a/cmake/create_test.cmake +++ b/cmake/create_test.cmake @@ -1,4 +1,4 @@ -set(gko_test_resource_args "RESOURCE_LOCAL_CORES;RESOURCE_PERCENTAGE;RESOURCE_TYPE") +set(gko_test_resource_args "RESOURCE_LOCAL_CORES;RESOURCE_TYPE") set(gko_test_single_args "MPI_SIZE;${gko_test_resource_args}") set(gko_test_multi_args "DISABLE_EXECUTORS;ADDITIONAL_LIBRARIES;ADDITIONAL_INCLUDES") set(gko_test_option_args "NO_RESOURCES") @@ -60,19 +60,7 @@ function(ginkgo_add_resource_requirement test_name) set(single_resource "cpu:${add_rr_RESOURCE_LOCAL_CORES}") elseif(add_rr_RESOURCE_TYPE MATCHES "^(cudagpu|hipgpu|sycl)$") - if(NOT add_rr_RESOURCE_PERCENTAGE) - set(add_rr_RESOURCE_PERCENTAGE 25) - endif() - if(add_rr_MPI_SIZE GREATER 1) - set(add_rr_RESOURCE_PERCENTAGE 100) - endif() - if(NOT add_rr_RESOURCE_PERCENTAGE MATCHES "^[0-9]([0-9][0-9]?)?" - OR add_rr_RESOURCE_PERCENTAGE LESS 0 - OR add_rr_RESOURCE_PERCENTAGE GREATER 100) - message(FATAL_ERROR "Resource specification is invalid: RESOURCE_PERCENTAGE=${add_rr_RESOURCE_PERCENTAGE}") - endif() - - set(single_resource "${add_rr_RESOURCE_TYPE}:${add_rr_RESOURCE_PERCENTAGE}") + set(single_resource "${add_rr_RESOURCE_TYPE}:1") else() message(FATAL_ERROR "Unrecognized resource type ${add_rr_RESOURCE_TYPE}, allowed are: ref, cpu, cudagpu, hipgpu, sycl.") endif() @@ -91,7 +79,6 @@ endfunction() ## - `MPI_SIZE size` causes the tests to be run with `size` MPI processes. ## - `RESOURCE_LOCAL_CORES` the number of threads used by a test, default is ## $GINKGO_CI_TEST_OMP_PARALLELISM -## - `RESOURCE_PERCENTAGE` usage percentage of a single GPU, default is 25 ## - `RESOURCE_TYPE` the resource type, can be ref, cpu, cudagpu, hipgpu, sycl ## - `DISABLE_EXECUTORS exec1 exec2` disables the test for certain backends (if built for multiple) ## - `ADDITIONAL_LIBRARIES lib1 lib2` adds additional target link dependencies diff --git a/test/tools/resource_file_generator.cpp b/test/tools/resource_file_generator.cpp index f0dbbea0353..ca7b09288e8 100644 --- a/test/tools/resource_file_generator.cpp +++ b/test/tools/resource_file_generator.cpp @@ -92,7 +92,7 @@ int main() if (i > 0) { gpus.append(",\n"); } - gpus += R"( {"id": ")" + std::to_string(i) + R"(", "slots": 100})"; + gpus += R"( {"id": ")" + std::to_string(i) + R"(", "slots": 1})"; } if (num_devices) { gpus.append("\n]"); From 6c59ec21e220fab98a3907f299b7cc13b040a2e7 Mon Sep 17 00:00:00 2001 From: Tobias Ribizel Date: Wed, 13 Sep 2023 11:01:37 +0200 Subject: [PATCH 37/44] use non-default stream only if necessary --- test/utils/executor.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/utils/executor.hpp b/test/utils/executor.hpp index e4ce56f3d7a..ea2aef157fd 100644 --- a/test/utils/executor.hpp +++ b/test/utils/executor.hpp @@ -127,10 +127,10 @@ class CommonTestFixture : public ::testing::Test { CommonTestFixture() : -#ifdef GKO_COMPILING_CUDA +#if defined(GKO_TEST_NONDEFAULT_STREAM) && defined(GKO_COMPILING_CUDA) stream(ResourceEnvironment::cuda_device_id), #endif -#ifdef GKO_COMPILING_HIP +#if defined(GKO_TEST_NONDEFAULT_STREAM) && defined(GKO_COMPILING_HIP) stream(ResourceEnvironment::hip_device_id), #endif ref{gko::ReferenceExecutor::create()} From 65061cbca54467935158377d4103039eb02c9fe3 Mon Sep 17 00:00:00 2001 From: Tobias Ribizel Date: Wed, 13 Sep 2023 11:01:50 +0200 Subject: [PATCH 38/44] fix CUDA trisolve regression --- cuda/solver/common_trs_kernels.cuh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cuda/solver/common_trs_kernels.cuh b/cuda/solver/common_trs_kernels.cuh index f42b11f510d..6ee2c7521ff 100644 --- a/cuda/solver/common_trs_kernels.cuh +++ b/cuda/solver/common_trs_kernels.cuh @@ -120,12 +120,13 @@ struct CudaSolveStruct : gko::solver::SolveStruct { const auto rows = matrix->get_size()[0]; // workaround suggested by NVIDIA engineers: for some reason // cusparse needs non-nullptr input vectors even for analysis + // also make sure they are aligned by 16 bytes auto descr_b = cusparse::create_dnmat( dim<2>{matrix->get_size()[0], num_rhs}, matrix->get_size()[1], - reinterpret_cast(0xDEAD)); + reinterpret_cast(0xDEAD0)); auto descr_c = cusparse::create_dnmat( dim<2>{matrix->get_size()[0], num_rhs}, matrix->get_size()[1], - reinterpret_cast(0xDEAF)); + reinterpret_cast(0xDEAF0)); auto work_size = cusparse::spsm_buffer_size( handle, CUSPARSE_OPERATION_NON_TRANSPOSE, From d454a8440234d2862e7d58448287d117a9942ede Mon Sep 17 00:00:00 2001 From: Tobias Ribizel Date: Thu, 14 Sep 2023 18:13:49 +0200 Subject: [PATCH 39/44] fix nondefault stream handling --- cuda/test/utils.hpp | 2 ++ hip/test/utils.hip.hpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/cuda/test/utils.hpp b/cuda/test/utils.hpp index 6ef808aa1b3..d13e364d66a 100644 --- a/cuda/test/utils.hpp +++ b/cuda/test/utils.hpp @@ -52,7 +52,9 @@ class CudaTestFixture : public ::testing::Test { protected: CudaTestFixture() : ref(gko::ReferenceExecutor::create()), +#ifdef GKO_TEST_NONDEFAULT_STREAM stream(ResourceEnvironment::cuda_device_id), +#endif exec(gko::CudaExecutor::create( ResourceEnvironment::cuda_device_id, ref, std::make_shared(), stream.get())), diff --git a/hip/test/utils.hip.hpp b/hip/test/utils.hip.hpp index e1c9f9341fb..9fc3edc3f82 100644 --- a/hip/test/utils.hip.hpp +++ b/hip/test/utils.hip.hpp @@ -52,7 +52,9 @@ class HipTestFixture : public ::testing::Test { protected: HipTestFixture() : ref(gko::ReferenceExecutor::create()), +#ifdef GKO_TEST_NONDEFAULT_STREAM stream(ResourceEnvironment::hip_device_id), +#endif exec(gko::HipExecutor::create(ResourceEnvironment::hip_device_id, ref, std::make_shared(), stream.get())), From 41502923801651c979b8d363af14175625c5ef24 Mon Sep 17 00:00:00 2001 From: Tobias Ribizel Date: Thu, 14 Sep 2023 18:14:24 +0200 Subject: [PATCH 40/44] remove `tests` target --- CMakeLists.txt | 4 ---- cmake/create_test.cmake | 2 -- 2 files changed, 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a9d901dee8..efb3fcc24ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -309,10 +309,6 @@ configure_file(${Ginkgo_SOURCE_DIR}/include/ginkgo/config.hpp.in # propagated to the other parts of Ginkgo in case of building as static libraries add_subdirectory(devices) # Basic device functionalities. Always compiled. add_subdirectory(common) # Import list of unified kernel source files -if(GINKGO_BUILD_TESTS) - # use custom target `tests` to build only test binaries - add_custom_target(tests) -endif() if(GINKGO_BUILD_CUDA) add_subdirectory(cuda) # High-performance kernels for NVIDIA GPUs endif() diff --git a/cmake/create_test.cmake b/cmake/create_test.cmake index 375135dcb13..4dd6bd12125 100644 --- a/cmake/create_test.cmake +++ b/cmake/create_test.cmake @@ -100,8 +100,6 @@ function(ginkgo_add_test test_name test_target_name) COMMAND ${test_target_name} WORKING_DIRECTORY "$") endif() - # use custom target `tests` to build only test binaries - add_dependencies(tests ${test_target_name}) ginkgo_add_resource_requirement(${REL_BINARY_DIR}/${test_name} ${ARGN}) From 498123fcd0596eac917d5369c26f8b75959b3827 Mon Sep 17 00:00:00 2001 From: Tobias Ribizel Date: Thu, 14 Sep 2023 18:15:19 +0200 Subject: [PATCH 41/44] remove `ref` resource type This can be handled by the `-j` flag --- cmake/create_test.cmake | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/cmake/create_test.cmake b/cmake/create_test.cmake index 4dd6bd12125..e66bfb3178c 100644 --- a/cmake/create_test.cmake +++ b/cmake/create_test.cmake @@ -40,17 +40,11 @@ endfunction() function(ginkgo_add_resource_requirement test_name) cmake_parse_arguments(PARSE_ARGV 1 add_rr "${gko_test_option_args}" "${gko_test_single_args}" "") - if(add_rr_NO_RESOURCES) + if(add_rr_NO_RESOURCES OR (NOT add_rr_RESOURCE_TYPE)) return() - endif() - - if (NOT add_rr_RESOURCE_TYPE) - message(FATAL_ERROR "Need to provide resource type used by test.") endif () - if(add_rr_RESOURCE_TYPE STREQUAL "ref") - set(single_resource "cpu:1") - elseif(add_rr_RESOURCE_TYPE STREQUAL "cpu") + if(add_rr_RESOURCE_TYPE STREQUAL "cpu") if(NOT add_rr_RESOURCE_LOCAL_CORES) set(add_rr_RESOURCE_LOCAL_CORES ${GINKGO_CI_TEST_OMP_PARALLELISM}) endif() @@ -79,7 +73,7 @@ endfunction() ## - `MPI_SIZE size` causes the tests to be run with `size` MPI processes. ## - `RESOURCE_LOCAL_CORES` the number of threads used by a test, default is ## $GINKGO_CI_TEST_OMP_PARALLELISM -## - `RESOURCE_TYPE` the resource type, can be ref, cpu, cudagpu, hipgpu, sycl +## - `RESOURCE_TYPE` the resource type, can be cpu, cudagpu, hipgpu, sycl ## - `DISABLE_EXECUTORS exec1 exec2` disables the test for certain backends (if built for multiple) ## - `ADDITIONAL_LIBRARIES lib1 lib2` adds additional target link dependencies ## - `ADDITIONAL_INCLUDES path1 path2` adds additional target include paths @@ -121,7 +115,7 @@ function(ginkgo_create_test test_name) add_executable(${test_target_name} ${test_name}.cpp) target_link_libraries(${test_target_name}) ginkgo_set_test_target_properties(${test_target_name} "" ${ARGN}) - ginkgo_add_test(${test_name} ${test_target_name} ${ARGN} RESOURCE_TYPE ref) + ginkgo_add_test(${test_name} ${test_target_name} ${ARGN}) endfunction(ginkgo_create_test) ## Test compiled with dpcpp @@ -263,7 +257,7 @@ function(ginkgo_create_common_test_internal test_name exec_type exec) return() endif() if (exec STREQUAL reference) - set(test_resource_type ref) + set(test_resource_type "") elseif (exec STREQUAL omp) set(test_resource_type cpu) elseif (exec STREQUAL cuda) From 9071cfb19f32c7c261c87224be0bfbb7e23ad12b Mon Sep 17 00:00:00 2001 From: Tobias Ribizel Date: Thu, 14 Sep 2023 18:15:55 +0200 Subject: [PATCH 42/44] move more tests to host compiler --- cuda/test/base/CMakeLists.txt | 10 +++++----- cuda/test/base/{array.cu => array.cpp} | 0 cuda/test/base/{index_set.cu => index_set.cpp} | 0 cuda/test/base/{lin_op.cu => lin_op.cpp} | 0 cuda/test/base/{memory.cu => memory.cpp} | 0 hip/test/base/CMakeLists.txt | 8 ++++---- hip/test/base/{lin_op.hip.cpp => lin_op.cpp} | 0 hip/test/base/{memory.hip.cpp => memory.cpp} | 0 hip/test/matrix/CMakeLists.txt | 2 +- .../{fbcsr_kernels.hip.cpp => fbcsr_kernels.cpp} | 0 hip/test/solver/CMakeLists.txt | 4 ++-- hip/test/utils/CMakeLists.txt | 2 +- .../{assertions_test.hip.cpp => assertions_test.cpp} | 0 13 files changed, 13 insertions(+), 13 deletions(-) rename cuda/test/base/{array.cu => array.cpp} (100%) rename cuda/test/base/{index_set.cu => index_set.cpp} (100%) rename cuda/test/base/{lin_op.cu => lin_op.cpp} (100%) rename cuda/test/base/{memory.cu => memory.cpp} (100%) rename hip/test/base/{lin_op.hip.cpp => lin_op.cpp} (100%) rename hip/test/base/{memory.hip.cpp => memory.cpp} (100%) rename hip/test/matrix/{fbcsr_kernels.hip.cpp => fbcsr_kernels.cpp} (100%) rename hip/test/utils/{assertions_test.hip.cpp => assertions_test.cpp} (100%) diff --git a/cuda/test/base/CMakeLists.txt b/cuda/test/base/CMakeLists.txt index 174f4533c52..d4260c6e934 100644 --- a/cuda/test/base/CMakeLists.txt +++ b/cuda/test/base/CMakeLists.txt @@ -1,13 +1,13 @@ -ginkgo_create_cuda_test(array) +ginkgo_create_test(array RESOURCE_TYPE cudagpu) ginkgo_create_cuda_test(cuda_executor) -ginkgo_create_cuda_test(index_set) +ginkgo_create_test(index_set RESOURCE_TYPE cudagpu) if(GINKGO_HAVE_HWLOC) find_package(NUMA REQUIRED) ginkgo_create_cuda_test(cuda_executor_topology ADDITIONAL_LIBRARIES NUMA::NUMA) endif() ginkgo_create_cuda_test(exception_helpers) ginkgo_create_cuda_test(kernel_launch) -ginkgo_create_cuda_test(lin_op) +ginkgo_create_test(lin_op RESOURCE_TYPE cudagpu) ginkgo_create_cuda_test(math) -ginkgo_create_cuda_test(memory) -ginkgo_create_cuda_test(scoped_device_id NO_RESOURCES) +ginkgo_create_test(memory RESOURCE_TYPE cudagpu) +ginkgo_create_cuda_test(scoped_device_id) diff --git a/cuda/test/base/array.cu b/cuda/test/base/array.cpp similarity index 100% rename from cuda/test/base/array.cu rename to cuda/test/base/array.cpp diff --git a/cuda/test/base/index_set.cu b/cuda/test/base/index_set.cpp similarity index 100% rename from cuda/test/base/index_set.cu rename to cuda/test/base/index_set.cpp diff --git a/cuda/test/base/lin_op.cu b/cuda/test/base/lin_op.cpp similarity index 100% rename from cuda/test/base/lin_op.cu rename to cuda/test/base/lin_op.cpp diff --git a/cuda/test/base/memory.cu b/cuda/test/base/memory.cpp similarity index 100% rename from cuda/test/base/memory.cu rename to cuda/test/base/memory.cpp diff --git a/hip/test/base/CMakeLists.txt b/hip/test/base/CMakeLists.txt index ed32ab5b6a7..bfe8c8be96a 100644 --- a/hip/test/base/CMakeLists.txt +++ b/hip/test/base/CMakeLists.txt @@ -1,18 +1,18 @@ ginkgo_create_hip_test(hip_executor) -ginkgo_create_test(index_set) +ginkgo_create_test(index_set RESOURCE_TYPE hipgpu) if(GINKGO_HAVE_HWLOC) find_package(NUMA REQUIRED) ginkgo_create_hip_test(hip_executor_topology ADDITIONAL_LIBRARIES NUMA::NUMA) endif() ginkgo_create_hip_test(kernel_launch) # correct flags for kernel_launch.hpp are set in GINKGO_HIPCC_OPTIONS -ginkgo_create_hip_test(lin_op) +ginkgo_create_test(lin_op RESOURCE_TYPE hipgpu) ginkgo_create_hip_test(math) -ginkgo_create_hip_test(memory) +ginkgo_create_test(memory RESOURCE_TYPE hipgpu) # Only hcc needs the libraries. nvcc only requires the headers. if (GINKGO_HIP_PLATFORM MATCHES "${HIP_PLATFORM_AMD_REGEX}") ginkgo_create_hip_test(exception_helpers ADDITIONAL_LIBRARIES roc::hipblas roc::hipsparse hip::hiprand roc::rocrand) else() ginkgo_create_hip_test(exception_helpers) endif() -ginkgo_create_hip_test(scoped_device_id NO_RESOURCES) +ginkgo_create_hip_test(scoped_device_id) diff --git a/hip/test/base/lin_op.hip.cpp b/hip/test/base/lin_op.cpp similarity index 100% rename from hip/test/base/lin_op.hip.cpp rename to hip/test/base/lin_op.cpp diff --git a/hip/test/base/memory.hip.cpp b/hip/test/base/memory.cpp similarity index 100% rename from hip/test/base/memory.hip.cpp rename to hip/test/base/memory.cpp diff --git a/hip/test/matrix/CMakeLists.txt b/hip/test/matrix/CMakeLists.txt index 82db4b8b376..a52069daea0 100644 --- a/hip/test/matrix/CMakeLists.txt +++ b/hip/test/matrix/CMakeLists.txt @@ -1,4 +1,4 @@ -ginkgo_create_hip_test(fbcsr_kernels) +ginkgo_create_test(fbcsr_kernels RESOURCE_TYPE hipgpu) if (hipfft_FOUND) ginkgo_create_hip_test(fft_kernels) endif() diff --git a/hip/test/matrix/fbcsr_kernels.hip.cpp b/hip/test/matrix/fbcsr_kernels.cpp similarity index 100% rename from hip/test/matrix/fbcsr_kernels.hip.cpp rename to hip/test/matrix/fbcsr_kernels.cpp diff --git a/hip/test/solver/CMakeLists.txt b/hip/test/solver/CMakeLists.txt index a3b86589410..fcbb3de0c47 100644 --- a/hip/test/solver/CMakeLists.txt +++ b/hip/test/solver/CMakeLists.txt @@ -1,2 +1,2 @@ -ginkgo_create_test(lower_trs_kernels) -ginkgo_create_test(upper_trs_kernels) +ginkgo_create_test(lower_trs_kernels RESOURCE_TYPE hipgpu) +ginkgo_create_test(upper_trs_kernels RESOURCE_TYPE hipgpu) diff --git a/hip/test/utils/CMakeLists.txt b/hip/test/utils/CMakeLists.txt index a6c52f65d9c..d9ec2ff29a7 100644 --- a/hip/test/utils/CMakeLists.txt +++ b/hip/test/utils/CMakeLists.txt @@ -1 +1 @@ -ginkgo_create_hip_test(assertions_test) +ginkgo_create_test(assertions_test RESOURCE_TYPE hipgpu) diff --git a/hip/test/utils/assertions_test.hip.cpp b/hip/test/utils/assertions_test.cpp similarity index 100% rename from hip/test/utils/assertions_test.hip.cpp rename to hip/test/utils/assertions_test.cpp From 6e4bc33d2f64acccd5a300d96c77d3efd4c7b997 Mon Sep 17 00:00:00 2001 From: Tobias Ribizel Date: Fri, 15 Sep 2023 18:03:07 +0200 Subject: [PATCH 43/44] Update cmake/create_test.cmake Co-authored-by: Yu-Hsiang M. Tsai <19565938+yhmtsai@users.noreply.github.com> --- cmake/create_test.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/create_test.cmake b/cmake/create_test.cmake index e66bfb3178c..1911276f61d 100644 --- a/cmake/create_test.cmake +++ b/cmake/create_test.cmake @@ -56,7 +56,7 @@ function(ginkgo_add_resource_requirement test_name) elseif(add_rr_RESOURCE_TYPE MATCHES "^(cudagpu|hipgpu|sycl)$") set(single_resource "${add_rr_RESOURCE_TYPE}:1") else() - message(FATAL_ERROR "Unrecognized resource type ${add_rr_RESOURCE_TYPE}, allowed are: ref, cpu, cudagpu, hipgpu, sycl.") + message(FATAL_ERROR "Unrecognized resource type ${add_rr_RESOURCE_TYPE}, allowed are: cpu, cudagpu, hipgpu, sycl.") endif() if(NOT add_rr_MPI_SIZE) From 95240dcf12820dbfdfa6a9ae94631dd4837d9e50 Mon Sep 17 00:00:00 2001 From: Tobias Ribizel Date: Thu, 21 Sep 2023 11:34:23 +0200 Subject: [PATCH 44/44] review updates - make more tests host-compiled - make GTest main library suffix more descriptive - more consistent formatting --- cmake/create_test.cmake | 2 +- core/test/gtest/CMakeLists.txt | 2 ++ core/test/gtest/ginkgo_mpi_main.cpp | 2 +- cuda/test/reorder/CMakeLists.txt | 2 +- cuda/test/reorder/{rcm_kernels.cu => rcm_kernels.cpp} | 0 omp/test/reorder/CMakeLists.txt | 2 +- 6 files changed, 6 insertions(+), 4 deletions(-) rename cuda/test/reorder/{rcm_kernels.cu => rcm_kernels.cpp} (100%) diff --git a/cmake/create_test.cmake b/cmake/create_test.cmake index 1911276f61d..cec47fced74 100644 --- a/cmake/create_test.cmake +++ b/cmake/create_test.cmake @@ -114,7 +114,7 @@ function(ginkgo_create_test test_name) ginkgo_build_test_name(${test_name} test_target_name) add_executable(${test_target_name} ${test_name}.cpp) target_link_libraries(${test_target_name}) - ginkgo_set_test_target_properties(${test_target_name} "" ${ARGN}) + ginkgo_set_test_target_properties(${test_target_name} "_cpu" ${ARGN}) ginkgo_add_test(${test_name} ${test_target_name} ${ARGN}) endfunction(ginkgo_create_test) diff --git a/core/test/gtest/CMakeLists.txt b/core/test/gtest/CMakeLists.txt index c4e9cb52870..6d77b663e84 100644 --- a/core/test/gtest/CMakeLists.txt +++ b/core/test/gtest/CMakeLists.txt @@ -13,8 +13,10 @@ endfunction() add_gtest_main("" "") add_library(ginkgo_gtest_main_reference ALIAS ginkgo_gtest_main) +add_library(ginkgo_gtest_main_cpu ALIAS ginkgo_gtest_main) if (GINKGO_BUILD_MPI) add_library(ginkgo_gtest_main_mpi_reference ALIAS ginkgo_gtest_main_mpi) + add_library(ginkgo_gtest_main_mpi_cpu ALIAS ginkgo_gtest_main_mpi) endif() if (GINKGO_BUILD_OMP) add_gtest_main("_omp" "GKO_COMPILING_OMP") diff --git a/core/test/gtest/ginkgo_mpi_main.cpp b/core/test/gtest/ginkgo_mpi_main.cpp index 12107ca55f8..6853a12c940 100644 --- a/core/test/gtest/ginkgo_mpi_main.cpp +++ b/core/test/gtest/ginkgo_mpi_main.cpp @@ -395,7 +395,7 @@ int main(int argc, char** argv) MPI_Comm_rank(comm, &rank); MPI_Comm_size(comm, &size); - testing::AddGlobalTestEnvironment(new GTestMPIListener::MPIEnvironment); + ::testing::AddGlobalTestEnvironment(new GTestMPIListener::MPIEnvironment); ::testing::AddGlobalTestEnvironment(new ResourceEnvironment(rank, size)); ::testing::AddGlobalTestEnvironment(new DeviceEnvironment(rank)); MPI_Barrier(comm); diff --git a/cuda/test/reorder/CMakeLists.txt b/cuda/test/reorder/CMakeLists.txt index e6cd8c0f5d2..79deba957b3 100644 --- a/cuda/test/reorder/CMakeLists.txt +++ b/cuda/test/reorder/CMakeLists.txt @@ -1 +1 @@ -ginkgo_create_cuda_test(rcm_kernels) +ginkgo_create_test(rcm_kernels RESOURCE_TYPE cudagpu) diff --git a/cuda/test/reorder/rcm_kernels.cu b/cuda/test/reorder/rcm_kernels.cpp similarity index 100% rename from cuda/test/reorder/rcm_kernels.cu rename to cuda/test/reorder/rcm_kernels.cpp diff --git a/omp/test/reorder/CMakeLists.txt b/omp/test/reorder/CMakeLists.txt index 089e51c67c9..65aea4a0fdb 100644 --- a/omp/test/reorder/CMakeLists.txt +++ b/omp/test/reorder/CMakeLists.txt @@ -1 +1 @@ -ginkgo_create_omp_test(rcm_kernels) +ginkgo_create_test(rcm_kernels RESOURCE_TYPE cpu)