From e07ea3dd956a26a248894f3010b145f0e5a8f294 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 18 May 2025 00:24:23 +0200 Subject: [PATCH 001/141] Remove keys --- .github/workflows/main.yml | 15 +-- CMakeLists.txt | 1 - cmake/configure.cmake | 2 + cmake/gtest.cmake | 5 - cmake/mpi.cmake | 15 ++- cmake/onetbb.cmake | 61 ++++++------ cmake/openmp.cmake | 25 ++--- cmake/threads.cmake | 4 - .../locale/en/LC_MESSAGES/user_guide/build.po | 22 ----- .../locale/ru/LC_MESSAGES/user_guide/build.po | 23 ----- docs/user_guide/build.rst | 8 +- modules/CMakeLists.txt | 4 - tasks/CMakeLists.txt | 95 +++++-------------- 13 files changed, 74 insertions(+), 206 deletions(-) delete mode 100644 cmake/threads.cmake diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7e0151860..80358208d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -57,8 +57,7 @@ jobs: run: > cmake -S . -B build -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -G Ninja -D USE_SEQ=ON -D USE_MPI=ON -D USE_OMP=ON -D USE_TBB=ON -D USE_STL=ON - -D USE_FUNC_TESTS=ON -D USE_PERF_TESTS=ON + -G Ninja -D USE_FUNC_TESTS=ON -D USE_PERF_TESTS=ON -D CMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=install env: CC: gcc-14 @@ -211,8 +210,7 @@ jobs: run: > cmake -S . -B build -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -G Ninja -D USE_SEQ=ON -D USE_MPI=ON -D USE_OMP=ON -D USE_TBB=ON -D USE_STL=ON - -D USE_FUNC_TESTS=ON -D USE_PERF_TESTS=ON + -G Ninja -D USE_FUNC_TESTS=ON -D USE_PERF_TESTS=ON -D CMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=install env: CC: clang-20 @@ -363,8 +361,7 @@ jobs: run: > cmake -S . -B build -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -G Ninja -D USE_SEQ=ON -D USE_MPI=ON -D USE_OMP=ON -D USE_TBB=ON -D USE_STL=ON - -D USE_FUNC_TESTS=ON -D USE_PERF_TESTS=ON + -G Ninja -D USE_FUNC_TESTS=ON -D USE_PERF_TESTS=ON -D CMAKE_BUILD_TYPE=RELEASE -D ENABLE_ADDRESS_SANITIZER=ON -D ENABLE_UB_SANITIZER=ON -D CMAKE_INSTALL_PREFIX=install env: @@ -518,8 +515,7 @@ jobs: run: > cmake -S . -B build -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -G Ninja -D USE_SEQ=ON -D USE_MPI=ON -D USE_OMP=ON -D USE_TBB=ON -D USE_STL=ON - -DCMAKE_C_FLAGS="-I$(brew --prefix)/opt/libomp/include" + -G Ninja -DCMAKE_C_FLAGS="-I$(brew --prefix)/opt/libomp/include" -DCMAKE_CXX_FLAGS="-I$(brew --prefix)/opt/libomp/include" -D CMAKE_BUILD_TYPE=RELEASE -D USE_FUNC_TESTS=ON -D USE_PERF_TESTS=ON -DCMAKE_INSTALL_PREFIX=install @@ -666,7 +662,6 @@ jobs: run: > cmake -S . -B build -G Ninja -D CMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -D USE_SEQ=ON -D USE_MPI=ON -D USE_OMP=ON -D USE_TBB=ON -D USE_STL=ON -D USE_FUNC_TESTS=ON -D USE_PERF_TESTS=ON -D CMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=install - name: Build project @@ -816,7 +811,6 @@ jobs: run: > cmake -S . -B build -G Ninja -D CMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -D USE_SEQ=ON -D USE_MPI=ON -D USE_OMP=ON -D USE_TBB=ON -D USE_STL=ON -D USE_FUNC_TESTS=ON -D USE_PERF_TESTS=ON -D CMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=install env: @@ -944,7 +938,6 @@ jobs: run: > cmake -S . -B build -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -G Ninja -D USE_SEQ=ON -D USE_MPI=ON -D USE_OMP=ON -D USE_TBB=ON -D USE_STL=ON -D USE_FUNC_TESTS=ON -D USE_PERF_TESTS=ON -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_VERBOSE_MAKEFILE=ON diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ac7c3976..1c5a9426e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,6 @@ include(cmake/sanitizers.cmake) message( STATUS "PPC step: Setup parallel programming technologies" ) include(cmake/mpi.cmake) include(cmake/openmp.cmake) -include(cmake/threads.cmake) include(cmake/onetbb.cmake) ######################### External projects ######################### diff --git a/cmake/configure.cmake b/cmake/configure.cmake index 5f5a73b01..c548b8e77 100644 --- a/cmake/configure.cmake +++ b/cmake/configure.cmake @@ -83,3 +83,5 @@ if( MSVC ) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COMMON_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_FLAGS}" ) endif( MSVC ) + +find_package( Threads ) diff --git a/cmake/gtest.cmake b/cmake/gtest.cmake index dced69310..d20e815b7 100644 --- a/cmake/gtest.cmake +++ b/cmake/gtest.cmake @@ -1,8 +1,3 @@ -# Build googletest components -if(NOT USE_SEQ AND NOT USE_MPI AND NOT USE_OMP AND NOT USE_TBB AND NOT USE_STL) - return() -endif() - include_directories(${CMAKE_SOURCE_DIR}/3rdparty/googletest/googletest/include) include(ExternalProject) ExternalProject_Add(ppc_googletest diff --git a/cmake/mpi.cmake b/cmake/mpi.cmake index 3a26e000e..b38727cf3 100644 --- a/cmake/mpi.cmake +++ b/cmake/mpi.cmake @@ -1,9 +1,6 @@ -option(USE_MPI OFF) -if( USE_MPI ) - find_package( MPI ) - if( MPI_FOUND ) - include_directories( ${MPI_INCLUDE_PATH} ) - else( MPI_FOUND ) - set( USE_MPI OFF ) - endif( MPI_FOUND ) -endif( USE_MPI ) +find_package( MPI ) +if( MPI_FOUND ) + include_directories( ${MPI_INCLUDE_PATH} ) +else( MPI_FOUND ) + message(FATAL_ERROR "MPI NOT FOUND") +endif( MPI_FOUND ) diff --git a/cmake/onetbb.cmake b/cmake/onetbb.cmake index 84be4835e..750a42c79 100644 --- a/cmake/onetbb.cmake +++ b/cmake/onetbb.cmake @@ -1,33 +1,30 @@ -option(USE_TBB OFF) -if( USE_TBB ) - # Build Core OneTBB components - include_directories(${CMAKE_SOURCE_DIR}/3rdparty/onetbb/include) +# Build Core OneTBB components +include_directories(${CMAKE_SOURCE_DIR}/3rdparty/onetbb/include) - include(ExternalProject) - if(WIN32) - ExternalProject_Add(ppc_onetbb - SOURCE_DIR "${CMAKE_SOURCE_DIR}/3rdparty/onetbb" - PREFIX "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb" - BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" - INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install" - CONFIGURE_COMMAND "${CMAKE_COMMAND}" -S "${CMAKE_SOURCE_DIR}/3rdparty/onetbb/" -B "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build/" -DCMAKE_CXX_FLAGS="-w" -DCMAKE_C_FLAGS="-w" - -DCMAKE_CXX_COMPILER=cl -DCMAKE_C_COMPILER=cl -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} - -G${CMAKE_GENERATOR} -DTBB_TEST=OFF -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" --config ${CMAKE_BUILD_TYPE} --parallel - INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install" - TEST_COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install/bin" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") - else() - ExternalProject_Add(ppc_onetbb - SOURCE_DIR "${CMAKE_SOURCE_DIR}/3rdparty/onetbb" - PREFIX "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb" - BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" - INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install" - CONFIGURE_COMMAND "${CMAKE_COMMAND}" -S "${CMAKE_SOURCE_DIR}/3rdparty/onetbb/" -B "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build/" -DCMAKE_CXX_FLAGS="-w" -DCMAKE_C_FLAGS="-w" - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} - -G${CMAKE_GENERATOR} -DTBB_TEST=OFF -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" --config ${CMAKE_BUILD_TYPE} --parallel - INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install") - endif() - install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install/" - DESTINATION "${CMAKE_INSTALL_PREFIX}") -endif( USE_TBB ) +include(ExternalProject) +if(WIN32) + ExternalProject_Add(ppc_onetbb + SOURCE_DIR "${CMAKE_SOURCE_DIR}/3rdparty/onetbb" + PREFIX "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb" + BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" + INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install" + CONFIGURE_COMMAND "${CMAKE_COMMAND}" -S "${CMAKE_SOURCE_DIR}/3rdparty/onetbb/" -B "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build/" -DCMAKE_CXX_FLAGS="-w" -DCMAKE_C_FLAGS="-w" + -DCMAKE_CXX_COMPILER=cl -DCMAKE_C_COMPILER=cl -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} + -G${CMAKE_GENERATOR} -DTBB_TEST=OFF -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" --config ${CMAKE_BUILD_TYPE} --parallel + INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install" + TEST_COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install/bin" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") +else() + ExternalProject_Add(ppc_onetbb + SOURCE_DIR "${CMAKE_SOURCE_DIR}/3rdparty/onetbb" + PREFIX "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb" + BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" + INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install" + CONFIGURE_COMMAND "${CMAKE_COMMAND}" -S "${CMAKE_SOURCE_DIR}/3rdparty/onetbb/" -B "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build/" -DCMAKE_CXX_FLAGS="-w" -DCMAKE_C_FLAGS="-w" + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} + -G${CMAKE_GENERATOR} -DTBB_TEST=OFF -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" --config ${CMAKE_BUILD_TYPE} --parallel + INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install") +endif() +install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install/" + DESTINATION "${CMAKE_INSTALL_PREFIX}") diff --git a/cmake/openmp.cmake b/cmake/openmp.cmake index e94fd3e64..e09d04312 100644 --- a/cmake/openmp.cmake +++ b/cmake/openmp.cmake @@ -1,16 +1,9 @@ -option(USE_OMP OFF) -if( USE_OMP ) - find_package( OpenMP ) - if( OpenMP_FOUND ) - include_directories( ${OpenMP_C_INCLUDE_DIRS} ${OpenMP_CXX_INCLUDE_DIRS} ) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") - else( OpenMP_FOUND ) - if (WIN32) - message(WARNING "OpenMP NOT FOUND") - else() - message(FATAL_ERROR "OpenMP NOT FOUND") - endif() - endif( OpenMP_FOUND ) -endif( USE_OMP ) +find_package( OpenMP ) +if( OpenMP_FOUND ) + include_directories( ${OpenMP_C_INCLUDE_DIRS} ${OpenMP_CXX_INCLUDE_DIRS} ) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") +else( OpenMP_FOUND ) + message(FATAL_ERROR "OpenMP NOT FOUND") +endif( OpenMP_FOUND ) diff --git a/cmake/threads.cmake b/cmake/threads.cmake deleted file mode 100644 index be534ffd9..000000000 --- a/cmake/threads.cmake +++ /dev/null @@ -1,4 +0,0 @@ -option(USE_STL OFF) -if( USE_STL ) - find_package( Threads ) -endif( USE_STL ) diff --git a/docs/locale/en/LC_MESSAGES/user_guide/build.po b/docs/locale/en/LC_MESSAGES/user_guide/build.po index 6a5120f5c..37e40f0f4 100644 --- a/docs/locale/en/LC_MESSAGES/user_guide/build.po +++ b/docs/locale/en/LC_MESSAGES/user_guide/build.po @@ -36,28 +36,6 @@ msgstr "" msgid "*Help on CMake keys:*" msgstr "" -#: ../../user_guide/build.rst:15 -msgid "" -"``-D USE_SEQ=ON`` enable ``Sequential`` labs (based on OpenMP's " -"CMakeLists.txt)." -msgstr "" - -#: ../../user_guide/build.rst:16 -msgid "``-D USE_MPI=ON`` enable ``MPI`` labs." -msgstr "" - -#: ../../user_guide/build.rst:17 -msgid "``-D USE_OMP=ON`` enable ``OpenMP`` labs." -msgstr "" - -#: ../../user_guide/build.rst:18 -msgid "``-D USE_TBB=ON`` enable ``TBB`` labs." -msgstr "" - -#: ../../user_guide/build.rst:19 -msgid "``-D USE_STL=ON`` enable ``std::thread`` labs." -msgstr "" - #: ../../user_guide/build.rst:20 msgid "``-D USE_FUNC_TESTS=ON`` enable functional tests." msgstr "" diff --git a/docs/locale/ru/LC_MESSAGES/user_guide/build.po b/docs/locale/ru/LC_MESSAGES/user_guide/build.po index a51a67133..13b2384c3 100644 --- a/docs/locale/ru/LC_MESSAGES/user_guide/build.po +++ b/docs/locale/ru/LC_MESSAGES/user_guide/build.po @@ -37,29 +37,6 @@ msgstr "**Конфигурация проекта**: ``Makefile``, ``.sln``, и msgid "*Help on CMake keys:*" msgstr "*Важные CMake ключи для конфигурации проекта:*" -#: ../../user_guide/build.rst:15 -msgid "" -"``-D USE_SEQ=ON`` enable ``Sequential`` labs (based on OpenMP's " -"CMakeLists.txt)." -msgstr "" -"``-D USE_SEQ=ON`` включает ``последовательные`` лабораторные работы." - -#: ../../user_guide/build.rst:16 -msgid "``-D USE_MPI=ON`` enable ``MPI`` labs." -msgstr "``-D USE_MPI=ON`` включает ``MPI`` лабораторные работы." - -#: ../../user_guide/build.rst:17 -msgid "``-D USE_OMP=ON`` enable ``OpenMP`` labs." -msgstr "``-D USE_OMP=ON`` включает ``OpenMP`` лабораторные работы." - -#: ../../user_guide/build.rst:18 -msgid "``-D USE_TBB=ON`` enable ``TBB`` labs." -msgstr "``-D USE_TBB=ON`` включает ``TBB`` лабораторные работы." - -#: ../../user_guide/build.rst:19 -msgid "``-D USE_STL=ON`` enable ``std::thread`` labs." -msgstr "``-D USE_STL=ON`` включает ``std::thread`` лабораторные работы." - #: ../../user_guide/build.rst:20 msgid "``-D USE_FUNC_TESTS=ON`` enable functional tests." msgstr "``-D USE_FUNC_TESTS=ON`` включает функциональные тесты." diff --git a/docs/user_guide/build.rst b/docs/user_guide/build.rst index 217e9af5c..29d27fc28 100644 --- a/docs/user_guide/build.rst +++ b/docs/user_guide/build.rst @@ -8,15 +8,11 @@ Navigate to a source code folder. .. code-block:: bash mkdir build && cd build - cmake -D USE_SEQ=ON -D USE_MPI=ON -D USE_OMP=ON -D USE_TBB=ON -D USE_STL=ON -D USE_FUNC_TESTS=ON -D USE_PERF_TESTS=ON -D CMAKE_BUILD_TYPE=Release .. + cmake -D USE_FUNC_TESTS=ON -D USE_PERF_TESTS=ON -D CMAKE_BUILD_TYPE=Release .. *Help on CMake keys:* - - ``-D USE_SEQ=ON`` enable ``Sequential`` labs (based on OpenMP's CMakeLists.txt). - - ``-D USE_MPI=ON`` enable ``MPI`` labs. - - ``-D USE_OMP=ON`` enable ``OpenMP`` labs. - - ``-D USE_TBB=ON`` enable ``TBB`` labs. - - ``-D USE_STL=ON`` enable ``std::thread`` labs. + - ``-D USE_FUNC_TESTS=ON`` enable functional tests. - ``-D USE_PERF_TESTS=ON`` enable performance tests. - ``-D CMAKE_BUILD_TYPE=Release`` required parameter for stable work of repo. diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index cf528c534..d745c11c4 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -1,7 +1,3 @@ -if(NOT USE_SEQ AND NOT USE_MPI AND NOT USE_OMP AND NOT USE_TBB AND NOT USE_STL) - return() -endif() - message(STATUS "Modules") SUBDIRLIST(subdirs ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/tasks/CMakeLists.txt b/tasks/CMakeLists.txt index 9175a53aa..4ae9df094 100644 --- a/tasks/CMakeLists.txt +++ b/tasks/CMakeLists.txt @@ -1,40 +1,11 @@ message(STATUS "Student's tasks") -if (USE_MPI) - list(APPEND LIST_OF_TASKS "mpi") -else () - message(WARNING "MPI tasks not build!") -endif () - -if (USE_OMP) - list(APPEND LIST_OF_TASKS "omp") -else () - message(WARNING "OpenMP tasks not build!") -endif () - -if (USE_SEQ) - list(APPEND LIST_OF_TASKS "seq") -else () - message(WARNING "Sequential tasks not build!") -endif () - -if (USE_STL) - list(APPEND LIST_OF_TASKS "stl") -else () - message(WARNING "STL tasks not build!") -endif () - -if (USE_TBB) - list(APPEND LIST_OF_TASKS "tbb") -else () - message(WARNING "TBB tasks not build!") -endif () - -if (USE_MPI AND USE_OMP AND USE_SEQ AND USE_STL AND USE_TBB) - list(APPEND LIST_OF_TASKS "all") -else () - message(WARNING "ALL tasks not build!") -endif () +list(APPEND LIST_OF_TASKS "mpi") +list(APPEND LIST_OF_TASKS "omp") +list(APPEND LIST_OF_TASKS "seq") +list(APPEND LIST_OF_TASKS "stl") +list(APPEND LIST_OF_TASKS "tbb") +list(APPEND LIST_OF_TASKS "all") add_compile_definitions(PATH_TO_PPC_PROJECT="${CMAKE_SOURCE_DIR}") @@ -93,44 +64,22 @@ foreach(TASK_TYPE ${LIST_OF_TASKS}) foreach (EXEC_FUNC ${LIST_OF_EXEC_TESTS}) target_link_libraries(${EXEC_FUNC} PUBLIC ${exec_func_lib} core_module_lib) - - if ("${MODULE_NAME}" STREQUAL "stl") - target_link_libraries(${EXEC_FUNC} PUBLIC Threads::Threads) - elseif ("${MODULE_NAME}" STREQUAL "omp") - target_link_libraries(${EXEC_FUNC} PUBLIC ${OpenMP_libomp_LIBRARY}) - elseif ("${MODULE_NAME}" STREQUAL "mpi") - if( MPI_COMPILE_FLAGS ) - set_target_properties(${EXEC_FUNC} PROPERTIES COMPILE_FLAGS "${MPI_COMPILE_FLAGS}") - endif( MPI_COMPILE_FLAGS ) - - if( MPI_LINK_FLAGS ) - set_target_properties(${EXEC_FUNC} PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}") - endif( MPI_LINK_FLAGS ) - target_link_libraries(${EXEC_FUNC} PUBLIC ${MPI_LIBRARIES}) - elseif ("${MODULE_NAME}" STREQUAL "tbb") - add_dependencies(${EXEC_FUNC} ppc_onetbb) - target_link_directories(${EXEC_FUNC} PUBLIC ${CMAKE_BINARY_DIR}/ppc_onetbb/install/lib) - if(NOT MSVC) - target_link_libraries(${EXEC_FUNC} PUBLIC tbb) - endif() - elseif ("${MODULE_NAME}" STREQUAL "all") - target_link_libraries(${EXEC_FUNC} PUBLIC Threads::Threads) - target_link_libraries(${EXEC_FUNC} PUBLIC ${OpenMP_libomp_LIBRARY}) - if( MPI_COMPILE_FLAGS ) - set_target_properties(${EXEC_FUNC} PROPERTIES COMPILE_FLAGS "${MPI_COMPILE_FLAGS}") - endif( MPI_COMPILE_FLAGS ) - - if( MPI_LINK_FLAGS ) - set_target_properties(${EXEC_FUNC} PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}") - endif( MPI_LINK_FLAGS ) - target_link_libraries(${EXEC_FUNC} PUBLIC ${MPI_LIBRARIES}) - - add_dependencies(${EXEC_FUNC} ppc_onetbb) - target_link_directories(${EXEC_FUNC} PUBLIC ${CMAKE_BINARY_DIR}/ppc_onetbb/install/lib) - if(NOT MSVC) - target_link_libraries(${EXEC_FUNC} PUBLIC tbb) - endif() - endif () + target_link_libraries(${EXEC_FUNC} PUBLIC Threads::Threads) + target_link_libraries(${EXEC_FUNC} PUBLIC ${OpenMP_libomp_LIBRARY}) + if( MPI_COMPILE_FLAGS ) + set_target_properties(${EXEC_FUNC} PROPERTIES COMPILE_FLAGS "${MPI_COMPILE_FLAGS}") + endif( MPI_COMPILE_FLAGS ) + + if( MPI_LINK_FLAGS ) + set_target_properties(${EXEC_FUNC} PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}") + endif( MPI_LINK_FLAGS ) + target_link_libraries(${EXEC_FUNC} PUBLIC ${MPI_LIBRARIES}) + + add_dependencies(${EXEC_FUNC} ppc_onetbb) + target_link_directories(${EXEC_FUNC} PUBLIC ${CMAKE_BINARY_DIR}/ppc_onetbb/install/lib) + if(NOT MSVC) + target_link_libraries(${EXEC_FUNC} PUBLIC tbb) + endif() target_link_directories(stb_image INTERFACE ${CMAKE_SOURCE_DIR}/3rdparty/stb) target_link_libraries(${EXEC_FUNC} PUBLIC stb_image) From a0e20fcd8a993c02c70725aebf1b393c05f6ee74 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 18 May 2025 00:36:27 +0200 Subject: [PATCH 002/141] Fix docs and reports --- .github/workflows/codeql.yml | 3 +-- .github/workflows/static-analysis-pr.yml | 10 ++------- CMakeLists.txt | 28 ++++++++++++++---------- 3 files changed, 19 insertions(+), 22 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index a92545fc1..1f3db0d88 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -41,8 +41,7 @@ jobs: run: > cmake -S . -B build -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -G Ninja -D USE_SEQ=ON -D USE_MPI=ON -D USE_OMP=ON -D USE_TBB=ON -D USE_STL=ON - -D USE_FUNC_TESTS=ON -D USE_PERF_TESTS=ON + -G Ninja -D USE_FUNC_TESTS=ON -D USE_PERF_TESTS=ON -D CMAKE_BUILD_TYPE=RELEASE env: CC: gcc-14 diff --git a/.github/workflows/static-analysis-pr.yml b/.github/workflows/static-analysis-pr.yml index 251431684..acc1a1372 100644 --- a/.github/workflows/static-analysis-pr.yml +++ b/.github/workflows/static-analysis-pr.yml @@ -26,10 +26,7 @@ jobs: cmake -S . -B build -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache -D USE_FUNC_TESTS=ON -D USE_PERF_TESTS=ON - -G Ninja - -D USE_SEQ=ON -D USE_MPI=ON - -D USE_OMP=ON -D USE_TBB=ON -D USE_STL=ON - -D CMAKE_BUILD_TYPE=RELEASE -DCMAKE_EXPORT_COMPILE_COMMANDS=ON + -G Ninja -D CMAKE_BUILD_TYPE=RELEASE -DCMAKE_EXPORT_COMPILE_COMMANDS=ON config_file: .clang-tidy exclude: 3rdparty split_workflow: true @@ -62,10 +59,7 @@ jobs: cmake_command: > cmake -S . -B build -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -G Ninja - -D USE_FUNC_TESTS=ON -D USE_PERF_TESTS=ON - -D USE_SEQ=ON -D USE_MPI=ON - -D USE_OMP=ON -D USE_TBB=ON -D USE_STL=ON + -G Ninja -D USE_FUNC_TESTS=ON -D USE_PERF_TESTS=ON -D CMAKE_BUILD_TYPE=RELEASE -DCMAKE_EXPORT_COMPILE_COMMANDS=ON config_file: .clang-tidy exclude: 3rdparty diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c5a9426e..3481f4079 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,22 @@ include(cmake/configure.cmake) include(cmake/modes.cmake) include(cmake/sanitizers.cmake) +############################ Scoreboard ############################# + +message( STATUS "PPC step: Setup scoreboard generator" ) +include(cmake/scoreboard.cmake) +add_subdirectory(scoreboard) + +########################### Documentation ########################### + +message( STATUS "PPC step: Setup documentation generation" ) +include(cmake/sphinx.cmake) +add_subdirectory(docs) + +if( USE_SCOREBOARD OR USE_DOCS ) + return() +endif() + ################# Parallel programming technologies ################# message( STATUS "PPC step: Setup parallel programming technologies" ) @@ -22,18 +38,6 @@ include(cmake/onetbb.cmake) message( STATUS "PPC step: Setup external projects" ) include(cmake/gtest.cmake) -########################### Documentation ########################### - -message( STATUS "PPC step: Setup documentation generation" ) -include(cmake/sphinx.cmake) -add_subdirectory(docs) - -############################ Scoreboard ############################# - -message( STATUS "PPC step: Setup scoreboard generator" ) -include(cmake/scoreboard.cmake) -add_subdirectory(scoreboard) - ############################## Headers ############################## message( STATUS "PPC step: Setup headers" ) From 018b6853171dba500b28dbd2bc86954d99492e31 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 18 May 2025 00:52:19 +0200 Subject: [PATCH 003/141] Change mpi libs --- .github/workflows/main.yml | 12 ++++++------ CMakeLists.txt | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 80358208d..f24e3157b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -396,7 +396,8 @@ jobs: - name: Setup environment run: | sudo apt-get update - sudo apt-get install --no-install-recommends -y ninja-build libmpich-dev python3-pip valgrind + sudo apt-get install --no-install-recommends -y ninja-build python3-pip valgrind \ + openmpi-bin openmpi-common libopenmpi-dev wget https://apt.llvm.org/llvm.sh chmod u+x llvm.sh sudo ./llvm.sh 20 all @@ -456,7 +457,8 @@ jobs: - name: Setup environment run: | sudo apt-get update - sudo apt-get install --no-install-recommends -y ninja-build libmpich-dev python3-pip valgrind + sudo apt-get install --no-install-recommends -y ninja-build python3-pip valgrind \ + openmpi-bin openmpi-common libopenmpi-dev wget https://apt.llvm.org/llvm.sh chmod u+x llvm.sh sudo ./llvm.sh 20 all @@ -938,10 +940,8 @@ jobs: run: > cmake -S . -B build -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -D USE_FUNC_TESTS=ON -D USE_PERF_TESTS=ON - -D CMAKE_BUILD_TYPE=RELEASE - -D CMAKE_VERBOSE_MAKEFILE=ON - -D USE_COVERAGE=ON + -D USE_FUNC_TESTS=ON -D USE_PERF_TESTS=ON -D CMAKE_BUILD_TYPE=RELEASE + -D CMAKE_VERBOSE_MAKEFILE=ON -D USE_COVERAGE=ON - name: Build project run: | cmake --build build --parallel diff --git a/CMakeLists.txt b/CMakeLists.txt index 3481f4079..4bf136dfb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,13 +3,6 @@ cmake_minimum_required( VERSION 3.25 ) message( STATUS "Parallel Programming Course (PPC)" ) project(parallel_programming_course) -############################ Configures ############################# - -message( STATUS "PPC step: First configures" ) -include(cmake/configure.cmake) -include(cmake/modes.cmake) -include(cmake/sanitizers.cmake) - ############################ Scoreboard ############################# message( STATUS "PPC step: Setup scoreboard generator" ) @@ -26,6 +19,13 @@ if( USE_SCOREBOARD OR USE_DOCS ) return() endif() +############################ Configures ############################# + +message( STATUS "PPC step: First configures" ) +include(cmake/configure.cmake) +include(cmake/modes.cmake) +include(cmake/sanitizers.cmake) + ################# Parallel programming technologies ################# message( STATUS "PPC step: Setup parallel programming technologies" ) From 37c1842e90eedf4b2b4147c2cbc478d954502404 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 18 May 2025 12:01:58 +0200 Subject: [PATCH 004/141] Unite libs --- CMakeLists.txt | 6 +- tasks-1/CMakeLists.txt | 26 ++++++ tasks-1/example/CMakeLists.txt | 90 +++++++++++++++++++++ tasks-1/example/all/include/ops_all.hpp | 27 +++++++ tasks-1/example/all/src/ops_all.cpp | 68 ++++++++++++++++ tasks-1/example/mpi/include/ops_mpi.hpp | 29 +++++++ tasks-1/example/mpi/src/ops_mpi.cpp | 60 ++++++++++++++ tasks-1/example/omp/include/ops_omp.hpp | 24 ++++++ tasks-1/example/omp/src/ops_omp.cpp | 39 +++++++++ tasks-1/example/seq/include/ops_seq.hpp | 24 ++++++ tasks-1/example/seq/src/ops_seq.cpp | 32 ++++++++ tasks-1/example/stl/include/ops_stl.hpp | 24 ++++++ tasks-1/example/stl/src/ops_stl.cpp | 47 +++++++++++ tasks-1/example/tbb/include/ops_tbb.hpp | 24 ++++++ tasks-1/example/tbb/src/ops_tbb.cpp | 44 ++++++++++ tasks-1/example/tests/data/pic_all.jpg | Bin 0 -> 15356 bytes tasks-1/example/tests/func_tests/main.cpp | 74 +++++++++++++++++ tasks-1/example/tests/perf_tests/main.cpp | 56 +++++++++++++ tasks-1/example/tests/runner.cpp | 93 ++++++++++++++++++++++ 19 files changed, 785 insertions(+), 2 deletions(-) create mode 100644 tasks-1/CMakeLists.txt create mode 100644 tasks-1/example/CMakeLists.txt create mode 100644 tasks-1/example/all/include/ops_all.hpp create mode 100644 tasks-1/example/all/src/ops_all.cpp create mode 100644 tasks-1/example/mpi/include/ops_mpi.hpp create mode 100644 tasks-1/example/mpi/src/ops_mpi.cpp create mode 100644 tasks-1/example/omp/include/ops_omp.hpp create mode 100644 tasks-1/example/omp/src/ops_omp.cpp create mode 100644 tasks-1/example/seq/include/ops_seq.hpp create mode 100644 tasks-1/example/seq/src/ops_seq.cpp create mode 100644 tasks-1/example/stl/include/ops_stl.hpp create mode 100644 tasks-1/example/stl/src/ops_stl.cpp create mode 100644 tasks-1/example/tbb/include/ops_tbb.hpp create mode 100644 tasks-1/example/tbb/src/ops_tbb.cpp create mode 100644 tasks-1/example/tests/data/pic_all.jpg create mode 100644 tasks-1/example/tests/func_tests/main.cpp create mode 100644 tasks-1/example/tests/perf_tests/main.cpp create mode 100644 tasks-1/example/tests/runner.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4bf136dfb..b1042cbb5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,10 +43,12 @@ include(cmake/gtest.cmake) message( STATUS "PPC step: Setup headers" ) include_directories(3rdparty) include_directories(modules) -include_directories(tasks) +#include_directories(tasks) +include_directories(tasks-1) ############################## Modules ############################## message( STATUS "PPC step: Setup modules" ) add_subdirectory(modules) -add_subdirectory(tasks) +#add_subdirectory(tasks) +add_subdirectory(tasks-1) diff --git a/tasks-1/CMakeLists.txt b/tasks-1/CMakeLists.txt new file mode 100644 index 000000000..ba7e09610 --- /dev/null +++ b/tasks-1/CMakeLists.txt @@ -0,0 +1,26 @@ +message(STATUS "Student's tasks") + +set(list_of_reverts "") + +SUBDIRLIST(subdirs ${CMAKE_CURRENT_LIST_DIR}) +foreach(subd ${subdirs}) + add_subdirectory(${subd}) + foreach (dir_type "all" "mpi" "omp" "seq" "stl" "tbb") + set(base_dir "${CMAKE_CURRENT_SOURCE_DIR}/${subd}/${dir_type}_disabled") + if (NOT EXISTS "${base_dir}") + continue() + else () + list(APPEND list_of_reverts "${subd}_${dir_type}") + endif () + endforeach () +endforeach() + +set(output_file "${CMAKE_BINARY_DIR}/revert-list.txt") +file(WRITE ${output_file} "${CONTENT}") +message(STATUS "revert list") +foreach (dir_name ${list_of_reverts}) + message(STATUS "-- ${dir_name}") + file(APPEND ${output_file} "${dir_name}\n") +endforeach() + +add_compile_definitions(PATH_TO_PPC_PROJECT="${CMAKE_SOURCE_DIR}") diff --git a/tasks-1/example/CMakeLists.txt b/tasks-1/example/CMakeLists.txt new file mode 100644 index 000000000..1885e09ed --- /dev/null +++ b/tasks-1/example/CMakeLists.txt @@ -0,0 +1,90 @@ +# Print student task name +get_filename_component(TASK_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) +message(STATUS "-- ${TASK_NAME}") + +# Init project +project(${TASK_NAME}) +set(exec_func_tests "${TASK_NAME}_func_tests") +set(exec_perf_tests "${TASK_NAME}_perf_tests") +set(test_base_dir "${CMAKE_CURRENT_SOURCE_DIR}/tests") + +# Init func tests executable files +set(list_of_exec_tests "") +if (USE_FUNC_TESTS) + file(GLOB_RECURSE func_tests_source_files "${test_base_dir}/func_tests/*") + add_executable(${exec_func_tests} ${func_tests_source_files} "${test_base_dir}/runner.cpp") + list(APPEND list_of_exec_tests ${exec_func_tests}) +endif (USE_FUNC_TESTS) + +# Init perf tests executable files +if (USE_PERF_TESTS) + file(GLOB_RECURSE perf_tests_source_files "${test_base_dir}/perf_tests/*") + add_executable(${exec_perf_tests} ${perf_tests_source_files} "${test_base_dir}/runner.cpp") + list(APPEND list_of_exec_tests ${exec_perf_tests}) +endif (USE_PERF_TESTS) + +# Create lib +foreach (dir_type "all" "mpi" "omp" "seq" "stl" "tbb") + # Check directory existing + set(base_dir "${CMAKE_CURRENT_SOURCE_DIR}/${dir_type}") + if (NOT EXISTS "${base_dir}") + continue() + endif () + + # Print type of directories + message(STATUS "-- -- ${dir_type}") + + # Create task library + file(GLOB_RECURSE lib_source_files "${base_dir}/include/*" "${base_dir}/src/*") + file(GLOB source_files "${base_dir}/src/*") + + list(LENGTH source_files result_length) + set(name_lib "${TASK_NAME}_${dir_type}") + if(result_length EQUAL 0) + add_library(${name_lib} INTERFACE ${lib_source_files}) + else() + add_library(${name_lib} STATIC ${lib_source_files}) + endif() + set_target_properties(${name_lib} PROPERTIES LINKER_LANGUAGE CXX) + + # Link core library + target_link_libraries(${exec_func_tests} PUBLIC ${name_lib} core_module_lib) + target_link_libraries(${exec_perf_tests} PUBLIC ${name_lib} core_module_lib) +endforeach () + +# Link 3rdparty libraries +add_library(stb_image INTERFACE) + +foreach (exec_func ${list_of_exec_tests}) + target_link_libraries(${exec_func} PUBLIC Threads::Threads) + target_link_libraries(${exec_func} PUBLIC ${OpenMP_libomp_LIBRARY}) + if( MPI_COMPILE_FLAGS ) + set_target_properties(${exec_func} PROPERTIES COMPILE_FLAGS "${MPI_COMPILE_FLAGS}") + endif( MPI_COMPILE_FLAGS ) + + if( MPI_LINK_FLAGS ) + set_target_properties(${exec_func} PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}") + endif( MPI_LINK_FLAGS ) + target_link_libraries(${exec_func} PUBLIC ${MPI_LIBRARIES}) + + add_dependencies(${exec_func} ppc_onetbb) + target_link_directories(${exec_func} PUBLIC ${CMAKE_BINARY_DIR}/ppc_onetbb/install/lib) + if(NOT MSVC) + target_link_libraries(${exec_func} PUBLIC tbb) + endif() + + target_link_directories(stb_image INTERFACE ${CMAKE_SOURCE_DIR}/3rdparty/stb) + target_link_libraries(${exec_func} PUBLIC stb_image) + + add_dependencies(${exec_func} ppc_googletest) + target_link_directories(${exec_func} PUBLIC "${CMAKE_BINARY_DIR}/ppc_googletest/install/lib") + target_link_libraries(${exec_func} PUBLIC gtest gtest_main) + enable_testing() + add_test(NAME ${exec_func} COMMAND ${exec_func}) + + # Install the executable + install(TARGETS ${exec_func} RUNTIME DESTINATION bin) +endforeach () + +# Install the library +install(TARGETS ${name_lib} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) diff --git a/tasks-1/example/all/include/ops_all.hpp b/tasks-1/example/all/include/ops_all.hpp new file mode 100644 index 000000000..fab463ee8 --- /dev/null +++ b/tasks-1/example/all/include/ops_all.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include +#include + +#include "core/task/include/task.hpp" + +namespace nesterov_a_test_task_all { + +void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_vec); +void MatMulTBB(const std::vector &in_vec, int rc_size, std::vector &out_vec); + +class TestTaskALL : public ppc::core::Task { + public: + explicit TestTaskALL(const std::vector &in) : input_(in) {} + bool ValidationImpl() override; + bool PreProcessingImpl() override; + bool RunImpl() override; + bool PostProcessingImpl() override; + std::vector Get(); + + private: + std::vector input_, output_; + int rc_size_{}; +}; + +} // namespace nesterov_a_test_task_all diff --git a/tasks-1/example/all/src/ops_all.cpp b/tasks-1/example/all/src/ops_all.cpp new file mode 100644 index 000000000..f89b24f37 --- /dev/null +++ b/tasks-1/example/all/src/ops_all.cpp @@ -0,0 +1,68 @@ +#include "example/all/include/ops_all.hpp" + +#include + +#include +#include +#include +#include +#include + +#include "core/util/include/util.hpp" +#include "oneapi/tbb/parallel_for.h" + +void nesterov_a_test_task_all::MatMul(const std::vector &in_vec, int rc_size, std::vector &out_vec) { + for (int i = 0; i < rc_size; ++i) { + for (int j = 0; j < rc_size; ++j) { + out_vec[(i * rc_size) + j] = 0; + for (int k = 0; k < rc_size; ++k) { + out_vec[(i * rc_size) + j] += in_vec[(i * rc_size) + k] * in_vec[(k * rc_size) + j]; + } + } + } +} + +void nesterov_a_test_task_all::MatMulTBB(const std::vector &in_vec, int rc_size, std::vector &out_vec) { + tbb::parallel_for(0, ppc::util::GetPPCNumThreads(), [&](int i) { MatMul(in_vec, rc_size - i, out_vec); }); + MatMul(in_vec, rc_size, out_vec); +} + +bool nesterov_a_test_task_all::TestTaskALL::ValidationImpl() { + auto sqrt_size = static_cast(std::sqrt(input_.size())); + return sqrt_size * sqrt_size == static_cast(input_.size()); +} + +bool nesterov_a_test_task_all::TestTaskALL::PreProcessingImpl() { + // Init value for input and output + rc_size_ = static_cast(std::sqrt(input_.size())); + output_ = std::vector(input_.size(), 0); + return true; +} + +bool nesterov_a_test_task_all::TestTaskALL::RunImpl() { + int rank = -1; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + if (rank == 0) { +#pragma omp parallel default(none) + { +#pragma omp critical + MatMul(input_, rc_size_, output_); + } + } else { + MatMulTBB(input_, rc_size_, output_); + } + + const int num_threads = ppc::util::GetPPCNumThreads(); + std::vector threads(num_threads); + for (int i = 0; i < num_threads; i++) { + threads[i] = std::thread(MatMul, std::cref(input_), rc_size_, std::ref(output_)); + threads[i].join(); + } + + MPI_Barrier(MPI_COMM_WORLD); + return true; +} + +bool nesterov_a_test_task_all::TestTaskALL::PostProcessingImpl() { return true; } + +std::vector nesterov_a_test_task_all::TestTaskALL::Get() { return output_; } diff --git a/tasks-1/example/mpi/include/ops_mpi.hpp b/tasks-1/example/mpi/include/ops_mpi.hpp new file mode 100644 index 000000000..31b1f0424 --- /dev/null +++ b/tasks-1/example/mpi/include/ops_mpi.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +#include "core/task/include/task.hpp" + +namespace nesterov_a_test_task_mpi { + +void MultiplyRowMajor(const std::vector &in, std::vector &out, int rc_size); +void MultiplyColumnMajor(const std::vector &in, std::vector &out, int rc_size); + +class TestTaskMPI : public ppc::core::Task { + public: + explicit TestTaskMPI(const std::vector &in) : input_(in) {} + bool ValidationImpl() override; + bool PreProcessingImpl() override; + bool RunImpl() override; + bool PostProcessingImpl() override; + std::vector Get(); + + private: + std::vector input_, output_; + int rc_size_{}; + + void MultiplyMatrixBasedOnRank(); +}; + +} // namespace nesterov_a_test_task_mpi diff --git a/tasks-1/example/mpi/src/ops_mpi.cpp b/tasks-1/example/mpi/src/ops_mpi.cpp new file mode 100644 index 000000000..01f7d39b2 --- /dev/null +++ b/tasks-1/example/mpi/src/ops_mpi.cpp @@ -0,0 +1,60 @@ +#include "example/mpi/include/ops_mpi.hpp" + +#include + +#include +#include +#include + +bool nesterov_a_test_task_mpi::TestTaskMPI::ValidationImpl() { + auto sqrt_size = static_cast(std::sqrt(input_.size())); + return sqrt_size * sqrt_size == static_cast(input_.size()); +} + +bool nesterov_a_test_task_mpi::TestTaskMPI::PreProcessingImpl() { + // Init value for input and output + rc_size_ = static_cast(std::sqrt(input_.size())); + output_ = std::vector(input_.size(), 0); + return true; +} + +bool nesterov_a_test_task_mpi::TestTaskMPI::RunImpl() { + MultiplyMatrixBasedOnRank(); + return true; +} + +void nesterov_a_test_task_mpi::TestTaskMPI::MultiplyMatrixBasedOnRank() { + int rank = -1; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + if (rank == 0) { + MultiplyRowMajor(input_, output_, rc_size_); + } else { + MultiplyColumnMajor(input_, output_, rc_size_); + } + MPI_Barrier(MPI_COMM_WORLD); +} + +void nesterov_a_test_task_mpi::MultiplyRowMajor(const std::vector &in, std::vector &out, int rc_size) { + for (int i = 0; i < rc_size; ++i) { + for (int j = 0; j < rc_size; ++j) { + for (int k = 0; k < rc_size; ++k) { + out[(i * rc_size) + j] += in[(i * rc_size) + k] * in[(k * rc_size) + j]; + } + } + } +} + +void nesterov_a_test_task_mpi::MultiplyColumnMajor(const std::vector &in, std::vector &out, int rc_size) { + for (int j = 0; j < rc_size; ++j) { + for (int k = 0; k < rc_size; ++k) { + for (int i = 0; i < rc_size; ++i) { + out[(i * rc_size) + j] += in[(i * rc_size) + k] * in[(k * rc_size) + j]; + } + } + } +} + +bool nesterov_a_test_task_mpi::TestTaskMPI::PostProcessingImpl() { return true; } + +std::vector nesterov_a_test_task_mpi::TestTaskMPI::Get() { return output_; } diff --git a/tasks-1/example/omp/include/ops_omp.hpp b/tasks-1/example/omp/include/ops_omp.hpp new file mode 100644 index 000000000..87209c39e --- /dev/null +++ b/tasks-1/example/omp/include/ops_omp.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +#include "core/task/include/task.hpp" + +namespace nesterov_a_test_task_omp { + +class TestTaskOpenMP : public ppc::core::Task { + public: + explicit TestTaskOpenMP(const std::vector& in) : input_(in) {} + bool ValidationImpl() override; + bool PreProcessingImpl() override; + bool RunImpl() override; + bool PostProcessingImpl() override; + std::vector Get(); + + private: + std::vector input_, output_; + int rc_size_{}; +}; + +} // namespace nesterov_a_test_task_omp \ No newline at end of file diff --git a/tasks-1/example/omp/src/ops_omp.cpp b/tasks-1/example/omp/src/ops_omp.cpp new file mode 100644 index 000000000..e7aa92fcb --- /dev/null +++ b/tasks-1/example/omp/src/ops_omp.cpp @@ -0,0 +1,39 @@ +#include "example/omp/include/ops_omp.hpp" + +#include +#include +#include + +bool nesterov_a_test_task_omp::TestTaskOpenMP::ValidationImpl() { + auto sqrt_size = static_cast(std::sqrt(input_.size())); + return sqrt_size * sqrt_size == static_cast(input_.size()); +} + +bool nesterov_a_test_task_omp::TestTaskOpenMP::PreProcessingImpl() { + rc_size_ = static_cast(std::sqrt(input_.size())); + output_ = std::vector(input_.size(), 0); + return true; +} + +bool nesterov_a_test_task_omp::TestTaskOpenMP::RunImpl() { +#pragma omp parallel default(none) + { +#pragma omp critical + { + // Multiply matrices + for (int i = 0; i < rc_size_; ++i) { + for (int j = 0; j < rc_size_; ++j) { + output_[(i * rc_size_) + j] = 0; + for (int k = 0; k < rc_size_; ++k) { + output_[(i * rc_size_) + j] += input_[(i * rc_size_) + k] * input_[(k * rc_size_) + j]; + } + } + } + } + } + return true; +} + +bool nesterov_a_test_task_omp::TestTaskOpenMP::PostProcessingImpl() { return true; } + +std::vector nesterov_a_test_task_omp::TestTaskOpenMP::Get() { return output_; } diff --git a/tasks-1/example/seq/include/ops_seq.hpp b/tasks-1/example/seq/include/ops_seq.hpp new file mode 100644 index 000000000..f03fc7fb8 --- /dev/null +++ b/tasks-1/example/seq/include/ops_seq.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +#include "core/task/include/task.hpp" + +namespace nesterov_a_test_task_seq { + +class TestTaskSequential : public ppc::core::Task { + public: + explicit TestTaskSequential(const std::vector& in) : input_(in) {} + bool ValidationImpl() override; + bool PreProcessingImpl() override; + bool RunImpl() override; + bool PostProcessingImpl() override; + std::vector Get(); + + private: + std::vector input_, output_; + int rc_size_{}; +}; + +} // namespace nesterov_a_test_task_seq \ No newline at end of file diff --git a/tasks-1/example/seq/src/ops_seq.cpp b/tasks-1/example/seq/src/ops_seq.cpp new file mode 100644 index 000000000..d172feb5c --- /dev/null +++ b/tasks-1/example/seq/src/ops_seq.cpp @@ -0,0 +1,32 @@ +#include "example/seq/include/ops_seq.hpp" + +#include +#include +#include + +bool nesterov_a_test_task_seq::TestTaskSequential::ValidationImpl() { + auto sqrt_size = static_cast(std::sqrt(input_.size())); + return sqrt_size * sqrt_size == static_cast(input_.size()); +} + +bool nesterov_a_test_task_seq::TestTaskSequential::PreProcessingImpl() { + rc_size_ = static_cast(std::sqrt(input_.size())); + output_ = std::vector(input_.size(), 0); + return true; +} + +bool nesterov_a_test_task_seq::TestTaskSequential::RunImpl() { + // Multiply matrices + for (int i = 0; i < rc_size_; ++i) { + for (int j = 0; j < rc_size_; ++j) { + for (int k = 0; k < rc_size_; ++k) { + output_[(i * rc_size_) + j] += input_[(i * rc_size_) + k] * input_[(k * rc_size_) + j]; + } + } + } + return true; +} + +bool nesterov_a_test_task_seq::TestTaskSequential::PostProcessingImpl() { return true; } + +std::vector nesterov_a_test_task_seq::TestTaskSequential::Get() { return output_; } diff --git a/tasks-1/example/stl/include/ops_stl.hpp b/tasks-1/example/stl/include/ops_stl.hpp new file mode 100644 index 000000000..1461d8ca2 --- /dev/null +++ b/tasks-1/example/stl/include/ops_stl.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +#include "core/task/include/task.hpp" + +namespace nesterov_a_test_task_stl { + +class TestTaskSTL : public ppc::core::Task { + public: + explicit TestTaskSTL(const std::vector& in) : input_(in) {} + bool ValidationImpl() override; + bool PreProcessingImpl() override; + bool RunImpl() override; + bool PostProcessingImpl() override; + std::vector Get(); + + private: + std::vector input_, output_; + int rc_size_{}; +}; + +} // namespace nesterov_a_test_task_stl diff --git a/tasks-1/example/stl/src/ops_stl.cpp b/tasks-1/example/stl/src/ops_stl.cpp new file mode 100644 index 000000000..fb3c2b464 --- /dev/null +++ b/tasks-1/example/stl/src/ops_stl.cpp @@ -0,0 +1,47 @@ +#include "example/stl/include/ops_stl.hpp" + +#include +#include +#include +#include +#include + +#include "core/util/include/util.hpp" + +namespace { +void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_vec) { + for (int i = 0; i < rc_size; ++i) { + for (int j = 0; j < rc_size; ++j) { + out_vec[(i * rc_size) + j] = 0; + for (int k = 0; k < rc_size; ++k) { + out_vec[(i * rc_size) + j] += in_vec[(i * rc_size) + k] * in_vec[(k * rc_size) + j]; + } + } + } +} +} // namespace + +bool nesterov_a_test_task_stl::TestTaskSTL::ValidationImpl() { + auto sqrt_size = static_cast(std::sqrt(input_.size())); + return sqrt_size * sqrt_size == static_cast(input_.size()); +} + +bool nesterov_a_test_task_stl::TestTaskSTL::PreProcessingImpl() { + rc_size_ = static_cast(std::sqrt(input_.size())); + output_ = std::vector(input_.size(), 0); + return true; +} + +bool nesterov_a_test_task_stl::TestTaskSTL::RunImpl() { + const int num_threads = ppc::util::GetPPCNumThreads(); + std::vector threads(num_threads); + for (int i = 0; i < num_threads; i++) { + threads[i] = std::thread(MatMul, std::cref(input_), rc_size_, std::ref(output_)); + threads[i].join(); + } + return true; +} + +bool nesterov_a_test_task_stl::TestTaskSTL::PostProcessingImpl() { return true; } + +std::vector nesterov_a_test_task_stl::TestTaskSTL::Get() { return output_; } diff --git a/tasks-1/example/tbb/include/ops_tbb.hpp b/tasks-1/example/tbb/include/ops_tbb.hpp new file mode 100644 index 000000000..4df85defb --- /dev/null +++ b/tasks-1/example/tbb/include/ops_tbb.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +#include "core/task/include/task.hpp" + +namespace nesterov_a_test_task_tbb { + +class TestTaskTBB : public ppc::core::Task { + public: + explicit TestTaskTBB(const std::vector& in) : input_(in) {} + bool ValidationImpl() override; + bool PreProcessingImpl() override; + bool RunImpl() override; + bool PostProcessingImpl() override; + std::vector Get(); + + private: + std::vector input_, output_; + int rc_size_{}; +}; + +} // namespace nesterov_a_test_task_tbb diff --git a/tasks-1/example/tbb/src/ops_tbb.cpp b/tasks-1/example/tbb/src/ops_tbb.cpp new file mode 100644 index 000000000..2f0b12b9b --- /dev/null +++ b/tasks-1/example/tbb/src/ops_tbb.cpp @@ -0,0 +1,44 @@ +#include "example/tbb/include/ops_tbb.hpp" + +#include + +#include +#include +#include +#include + +#include "oneapi/tbb/parallel_for.h" + +namespace { +void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_vec) { + for (int i = 0; i < rc_size; ++i) { + for (int j = 0; j < rc_size; ++j) { + out_vec[(i * rc_size) + j] = 0; + for (int k = 0; k < rc_size; ++k) { + out_vec[(i * rc_size) + j] += in_vec[(i * rc_size) + k] * in_vec[(k * rc_size) + j]; + } + } + } +} +} // namespace + +bool nesterov_a_test_task_tbb::TestTaskTBB::ValidationImpl() { + auto sqrt_size = static_cast(std::sqrt(input_.size())); + return sqrt_size * sqrt_size == static_cast(input_.size()); +} + +bool nesterov_a_test_task_tbb::TestTaskTBB::PreProcessingImpl() { + rc_size_ = static_cast(std::sqrt(input_.size())); + output_ = std::vector(input_.size(), 0); + return true; +} + +bool nesterov_a_test_task_tbb::TestTaskTBB::RunImpl() { + tbb::parallel_for(0, ppc::util::GetPPCNumThreads(), [&](int i) { MatMul(input_, rc_size_ - i, output_); }); + MatMul(input_, rc_size_, output_); + return true; +} + +bool nesterov_a_test_task_tbb::TestTaskTBB::PostProcessingImpl() { return true; } + +std::vector nesterov_a_test_task_tbb::TestTaskTBB::Get() { return output_; } diff --git a/tasks-1/example/tests/data/pic_all.jpg b/tasks-1/example/tests/data/pic_all.jpg new file mode 100644 index 0000000000000000000000000000000000000000..34458023494a39d66880a98aa5dcad18eb14b249 GIT binary patch literal 15356 zcmb7r1ymeM+h(J|Lh#^jgS!(nxH}|3!r<;sAOsKYPH>0dE6e&6od zf6v*P!%WfLQ`J@7_0Ic9Kg~R?0BAB2(h>j^6aYX$Ucl2D)Qq&4n7)#VqJ*^E>wk89 z2OtHO1put99qm;lMM<@^bx5DB{PT@p``&{cY=3?J4+YZh<mpyF;3wpd(jL+|a@S=2LIFre$`zZZ5<)UDE+G2tEq@V>V}Xyt;v7Y z4gRYRwzdCtd?@4?0V_+VUw!>5zs?xN$XZ<$@`(WXBLo}(6+jXY{WX5b|Bzyn1pqu3 z000yDpKS(708r--0JwAi*+%&V0ABb3K<&tXw*6;LY~S0z|J@uc}B7ywT50pPhd z0AT(A0Him+_d(wNhjSx^>>`Ammks1)0$2h@04X31SOZ{y2~uMNSO8Xl>uDYk17M(k zm0#~LkOB)2`>PgAVo71sMPU1NFQ79WC$- z0Uiz!76ux!R|O4nIS^rBkx>xfV4>h3hd=?)FmUkC&@nJ!u~@NjUXmf;vT=)OeDcew z8Y8Em`noY_Uo!DAF1^Q*^SP5kQd-wxrQ0dNSA z4iO=HHP8Vl7-(2nXlTUe$S5$7gP@>c(BUuuSa`B$n5-h?%2?P4IBZ-h_Kp=*FL5b2 zMBm$e^!*e)Hcrhc_F7dfDyFidlaiL5TODi^o0UDfMrE*``7{UoY6==11|1Lr5SWE7 z$Aqi}Jt})ogXX0k>MxE4Ncus+5yA){#z7(OyeXs56>}TSH!UPkRd@`O)C&{{JxaZU z3dWq3W;mr(;ooeu)rI48wv;6---WI|e`ktH3MX~p!O-Jqs1~P7Du-|)?vnnfWirkq zuT!)eXP&2P%7V6bNT>UAR7v9-9GfNUT6naiu^sHoj5{-uI^vdD@Xc!%{{T>6;JR;T z^j;`v*-$g){&*Ef-QYewdTJ(m*~XkMUlwtsK|2hxS~#IuPyl4LqqfP=%$ygw_UiQc zKS7h}-j(sJdB&`MoTB8y`*}^$BTQvCa9?wAF>@$7VkekE2za z;EYQl*-~;cz?RzQ6w3M%sJ9|g1_RQ#y@IW5*{M#5NQqP_2EFW|$h;O7+Eh;8tls6j zRBK4ZOON4)9&M8K;zV<`(fUFFBp@5_T8aBalZI^xpNIM)8q9LZlNaXHYB3PXAF0^`<4(kgxJ*8aN~9k5zUxXXSPA zY6b(w)}kNKg3=#Y+ZT$F~iWgw2P|?BJ(Xx*NT=ZdxE^l>#b&d5egtiwlOi- zS2CLJ(zcNVsL1cTd}KaGItNjkFbi`r9%BriEl<%f3-wppmBvUFITgvmeKeAWrXLJY zmT;snllkZR1Q-1u*GI~<6kBQ932wY_KvW|ZJG$}WuJOm8g4^Xqu;9Grc|e^SxM6}A?Yk` zIX0_Gh(E*u%jttk$rNHyV|hw5qKyx`DzhZ^d7b)fg)-!;TC&EY9$9=pHqw4F*omK99fTb zK0=SyYR6mM7XsEy=hZ}&#;il1dD^SuC8SHW7I3DJ5kY`|4p+-E-|^yDn}xUsUh3q%LRVW;`k6fxz@O2+FXIuJ#m@ zT9}$EYR*MrpT$0K{N>#PbJJL~^b^238v0m*Sad94t9ja@yiqic+_3&qTychxy~ab~ zc4D4BlGK!1VDATVmTf3nx&SrWXNC!)0`8Qd+H%L}T&zd{*4h~W;J5Lqvz5nqi71lC z=R7$2;`PMj$u{b17`w_aqTJ(iLFRrr(v&{WL_*%?%4aVS|i6|A1IPccJ`s zbPYl!Y`-umdXJ_4D`)ojT5qnSx+1UJ8-dCkj)%dIxC1Dz(#HA*X$qD4C6PtgIOdnt zXR4CCc|)Kq+kGBk7$t-?9jm`r7i6fqv%5hhEq)BAAL7D3kDwEi+!-_+Qhd;qOiS4G zW6%eRuI|7TG0O9}8GVlBdVci2>}vUX^Rub5(&lD&rd8quec#e)>W|nT-1s7d0^R9z zwGZ{5kNHW4sP0q-m=kj^3X{xAxH;p(Wp?NiqooHq&OEYV<#8dmPJydzK5rEG)refOr( zW6+CaofzxqxT5cRhu=_lSC|lN*-!Pc$r9YoEh`+GWJO_}QgV_lj)}>0keUUeR-g!M zv<;8maPp&#qCh9TqPP0!@_C>nX&(Ph?gV$Dnmfms{jjJgZ>ffD#iGEX5kLh!kT@tNi4N}25OvU3x(lq^q&@q87} zle8LkPsu5Pa@~zH)YG!M`@}q^&n=y1N!3n?VNI*4`_8nxAU_SR*}Is^FdO(jr^0bL zcfmz47>~jS{6gEj_VW|K;nnvjVw$?X?t)snK!?k9lHF%9sk?S%*pRQNkmVRGcQlG? z_X!gNmoFSw0;U8OF?qO+TWd;>-K(%g*RXVjD~2kW?P$~wOuM>8@BeCyU>hV%Gc0a1 z{vl=6afmuIX*k(|fl<*{l7Z^AeNw#++*l$Txj5c#@I&Uz_Ln%p%)RaKx8Lnu;T4-S zN^D8*Wby})s;nj0I@JttTPpN=?>g^Z%f2d>c^P|?zxP!pV^C} zF`0M5ov1_xxWb(6NZSA2NOaSM=W`tmdr)@O{v@3QxW}J#tjnfSc}>R>RZcTak__gg zC?hdlX3^B)zt5XJYhKT+nVx^)@&q^*Jk!}MV<4{_NUiF7)7a3#D(AW?R8sFZ41Pmx zr8YEkfO8Q?xl^QIgcT?XLPeW`4|+!`iZvHen#Q2M0QZ$rj;5RRd6zSdSx@j(BhSyv z^pK1f_Mau}ES?v9VLa;xsl+nqvp~5kuT`VHlfytoUpsg^a*%PcwQ5^@ZKS;&^DzD% zQP4F3FMMV^(>VP5>De@cp?f-9jP-?iHt&l$^;cTzDfW=eMS^tFG$WsdT&MbVxyr&8cMO8(9`#HyS)ZX^63;m!7Gx z09!P3V$(2Ra(wMsk-Xr+uRVoQuH_q7zfX4bZWAp6TD~1ti`T9#&<5+Or&xAr#IbEg zgzUWI$hCVE^AdryO>2*t>Iu*g(!{rzvw?pCVh12`vG{Uk7Hjz0rRUArhfF+G*d3R2 zn&KP1>eFPQ!_9lKvwX~1qGL_wQ$H_)`ZJDN1rJXnNuE87mpMkMt{-Shc$um@_=>!; zuDUb_?cyA1T8m8j@ovRenbfou{9i}reSRc4^==7#0xC_e%g>&Gl~tyn_qJO0y2}3i z2O+24Y4_yK2=s4TGtS+EN6u)Ra3lN$x2td7L09#>c(XIH%Pd+;VAN{D<~@pqR~0Wf znZ`8dp13^ppG=O9!8a~UXy2rBVc?y(_!Z5d+nViqD2eK=YV3&Uw%)4!kx>*#)PUFg znw@<)Zw7hfAvWcXV`1Rj6md@>&~44VEpA^CBsoD`>sd8W3p+SsD-f7YgMKY^A(YFl zdcNdz1b?_WixF33l34x;o#^&3f?d{dyRJvgAv}}JT|&DzaLv6ldS8y-Jb#Ya^R;I$ z@&n>=QPOF^hbSJ|ND+ygx~x$zJMZv$aP{EGGO^ZNs{ESG#P+CnpWFT2|2{@~3LRnm4_iGoa88nO5jpz;Ki$f0yIkAXVL zJT0SGe}b#8A_NTaxf(AdDm6;aJ#u?fHGxkq#(Zfm zBF!aE*o#NzUZggr_)2UtfEjeVzxPqyI)CRrh2Z(T*BO#do|R%pQ23%tcdUp+?hbr+ z%bIq&$8FaJ?;-QU6YwB(_kR3h@CoR60*;@6>ovn!?2RXY|5`kmS)BN4RiLetl7Dq+ z6Eci*qvNjisAZmXn!fE-aSJt(4# z@{^4wGfmA9b#P*7bETD}Kq^vjbg*c`q{Fz40^kSqF^tR45+Y31EeBV!4}M+VtO{A( zE8H&8?!Dba`EBW}HEdxe^-12@g@eoFG>JdC^aXi~iT8#MPci37*bQenLh_<#-+g5$ zBz>(QMw`utE@2v8!6Au`v9|mC>v@~x>sdx(Q;{ctSOHOY*}=DTP8|1@Y0bscX1@B;}ivRTs=vn1FQS%pgad& zV{8>s7;DPSZvs=Jmr8FLXR?sg>6-n~Ns}<=AR#x(d`#9TfOz?DuAwUi&m1YQbEw$3&zG^Gwn|js+AUNu=3E0+V2yk#m@p z8E$GvKQA9KW*qHA0T5#+z9Z^tz#}=Ke)}hw!4rQ!c5m>GrPx{QY+0|S_eWLeVtDM8N z_m(1u>JV$-U);mkLehWi^#p_~SfSmCjS9KBYZNwQniQ#;yeTEa9HX%lTpu`Dj|tG3 z^V`n#QX)BzupHLmD{|t>D(1 zwnz+Z+qE7}1n!VtjAcYx^-AH@nbq^Z%<$ltk(c0)L|B27Hw~O44!-MmnYI6JoM-Mu z;ohR(2DyiR+;`#*JppiiQhgda!(?ui#jt~Al41mJJ$ev$f(u>El*YAFYcs?sIEoo) z2jVBIg6RC?V~EiT7o?(=Sn6y;EB$Lc=%|hIzAj_e4oo^?D@qE)8|J4h;*vt(pFCvs zX~0j`VRq@e&A&2x%~aDkTI^h6RjH@kH`$Eef**&L9^nG|;djz*8(32C{O>GD%nagg z?YJ$Rxa8&^#z4jEGR)*Yk4rMP;^wppcSoS)q>M?o+jf!kNoD0(57hdZ&>_p!eYTY% zX<>3^ec_b9TplgY#;&;VoyG4*uTN|PchT$>vbKwc6z0+Q`ID&ah#zT^@;~rp=~53( zs1mGdXh}&VWtzn?V99ETgZaCxrt=5}0{m@Tv*SwRcH|XXk}a!5e^2ALx1h=53v(mU zr6IlV={iB%JhQnxsLzdq5G(*fS+=8eCU2t`nMW^?^j(Vu&K^~NWg79{>(9)FjH+nH z5VwMs49{V0XsTVlF{L|y(#awnjrWO zv0wQ7RtSY<Tgaz$cC_g*vDyqCtjhFYR%<+_Y2giI<3R!w6DHOU>(kLB7w7GML~lOPnslo8oj#s(#AFrn#z6fD5%c5p zfn<-erIC!EdHOa8SF{#wG>Zf`$1fwW{O|N056LdQXuj6qX7_<6&c3 zLh&mGP*gjgcHk$Knq!s9m8$il>C@XeM;254_)_ZY`$Z4jEl8RE1k5umuniU6_77Ik z%dYj$3c_MxP^62Y3LNd63IF(*m&(`clZY>1DTqFX?i^w=Q`c6-KH@Er+5*rin%$5D zwC$1<2Y62t6?vy@J^>;lb8C*Ew4cYJbz2XjY@SqSG#r@D{nA|rb=LBd??z`eB0mUhjVh7%KWCL=Kk)&5zNbAo~L2rf5nKgLUZWaa_ z{HYl>yL9~SDcA)Y!DB}J^DdAzgWZ_W`Cu(TcKi)zQ}s z&~Z!Azi36@89Q;GNWf$rIHN&+0t{VROWOKI&%;+Bw7!bX!MFqS=odP$lvN-kzA^PN&&3nP zTWL<^CFQ9v<7o8J=a)qhp5mGXTu~Fk`#tCQF+m6?Sa0|N`U&{*p_XQ9y~sP&=n0S? znKe*hj7eX{Qy%8?^PlrPaDW6e&t*+r8_kf#8%Quy(4Fl>kmGUtJ~LBRQL3-X`>rmt z=p*B)12rZXnf(3pcceT%*!6ClA?~p~)49Tm>jYg_9lQM&&Ad}673yRrbo=!BOj4v; z+W{-VT!~AtS7ARN=@_b#|IK#QZ$E@T&?F6$E}~=3dA6T@3&iD#kXd_{>0VKX-nXSY zh=}RUL_S%(l9YHjjp*`6I$&5e{kv=$nO4(P%PYe*DyB0fGCX-^jnny~5LRF@F69Rw zv=^Ghp*31txF{iTg~9CBI=g?D5h}W5TP2rkNuQYvz;=zEgN0V%D^OTByT|R0R0tzx zeGJ+~^bj{ai8z;(lAWVxHoG|vh}ab>_9-vpm-Xfz{P4-UrYAJ|_(d;VAk`$U>Z>`) z!`^adtw&`pT<2WRxymW(q`W$P9F6|C@iA7yQ%asrj~L)N0=`*h0T0rZmRD9p_$#CL z>IZgLlZiKck5MH&i@(<+HHa+s5NTEH4dpzoW_-Q}$8K&Yw=heWZ0xDte1{UN?5{|d zX(1w!ESm+Bn*<67&kjW+5+(a+r(`i}jB7!jQ?wiWk(dhiSn&Rbx(XJ!V2S%rdy-a&lS`FrD2^xW ztt)*yd{pLjpagnCWqdG!#C_lfET>EDW(VO=oobd^5bqXFd%)rg?^t>VwIzZpOz`+y zZ5gcV3U{tz1BV!>7w}p9zD1)+(1)>RjnP2!NuBmIJscGuT53zy?36 zcrDzV*m@-MS5y}FCZ)_ts*g7Pwd*Kw#ncRt1^;HV@-HXNL{HPAH$w~}`ss7SmJW@5 zG7A-cgpobWNy{PNzV9p%Lx8V`lI7P}u0!|Q2H)h`$eU1hzUIYXOj}uOMm_bAcA?`END>8x?kVwHKD zM&_F$teS)1t-R>dAV{hzPb5hQjo&T?UFz;HF_5<%jUmt<`^xFvR7&>;Dh*u*)r>a- z&@xJ$7Nk;`h^C3ru;PJJ;r+o2Wj<7jKPM0$Oly4u(QdhDXBe%g`5b0(6#BUd>KqY^RLg~CgMavK zt)n>E#!y}8C^hFBHW(ykpN8y$U7EDN(3-1OQ%HF`N2@}^mFNDLXJCp;ai`(I~HYG_7_XH9d~+ z?H&FAR`LIkmte`Tz$`vdrcup3lx|7pfpfqm$!~F!DAeU!;Io}MuJYa1d9|6kgn=yq zo&CX9GSj9klM<^jm(i_&4_=m#fm|)_OhzkQH73sVNUh+;2S*yRt6ZIj?OiBdv&k|n zCxY?XRvHG+MDvZXE`PyNr@C1a2rTU#VD0z?OQ}QUc_6SfK1|_9;q+vsd}Rxwxl2`8 zylJN+6d`ObJF~(T*{Ng>I^BtD8AbPMT7))wU1ZnPMVcX-TagOJc42g}jzHAFMkY8? zY)U3t_;qpfa$T@$8}=@@4(EFut6EtIrjGcenXQrqMnBr*LrdpDMZ1W70_w7FbdTFk z`noGwAyPy`p1)E-m1a$T<8Lj3u@JGdWEG+iQUr@P{s}Ec&X*313F_rMu^HsTH$Ths zc8eyBvL5)U_rJp1riFIK?tH8nZb`)x)p;C67AK_5;dio zZ?U-`D%xv9Gs85z??Xq*sdk;15geSr`W9Viyewsp6we9_2NWrWXc_G6N_q>a#GR!H zimq}ICq(C`2gRzSX7c2X)#O$eM)ya5Or&8!dr$rrS<6-%>4bW*iC@?2>y`JF6k~d# z?g(xp`G;?CefvbOH`?}k_f|gr@60Zma-k}!hewlXv5Yr@c zZ*zTzuB4NK4xS~Q_Pkts)p+|w{Y~Mm5Oq(d^Rj10d|`^}&n${M-JjSj+jR{PTDFDE zGKkc?=gUPERJ!h0V`C5W4S|y)SG#XdK;eUWe@5O}xn-RV)Au+sRe^3#+@RxWOStU6 z$=GNkNq57Gptlf~xT|_$;35dQF);su3}yQ!s=3P(+ik@4w7ndg=i6TBkeIYP_SmdV z(qP1SDGZnWNJCrhe6KP;rxY_?5H%_rJk#`_%!QF4^Zrfbwg0vouk$|$3Vy5bL%x^O z=ObVF3gVq!Z9%5fCDvS8o&CKinE~77(VLgG0XNgjgnofE3Fg#~YLe`oj(tH~7JqVg zjJLiBDivxMRjd1qAJN$tGRU?e3_B_Z^TcE9Ci@ugbp6}L0df_;uD9i%*adH`LKu8c z3w*8D&#H)n1dlu1yaS|MI$QdeQ!aM;P5#XV{Xi;NJ!a|_4_$OK`|k+kuEHzomOGyS z@e}SOQE=en=gaOvhw`geku}IS&Ne3O3rkGlg=rNz*s&tEcaBeh9b^eT*3;e2wykAc z3O!WR&eg8DLUcltAyC{&HL{Dw$il%nf0oSL~cz zrApa+`uVSFHN>&WWJJhCf~DapVTdSSFuc3ut?G9b;p%Eb^Ng49Owo>N8$z^m!+t9GFa;_>@5uGp8(rS$oCc2L^`<(u z9y?^ZWSmhZn?L@NdUbI8*Ecr>GgYGsG-F!zsQvPxW@OMiht<^a^CU?J8n`A6I^+NZ zU-6)iFeR(S*^b0TlQjbI*~2Ujct(xBHT7#)YJLnTyF>HtIK3xQsdG`_U_!8#v`Wp&KTfyocy{gJUeYLAkE>jBf!ngphgH`*>(_ zACWTD7IjH*xH<35G+)}FG1%S1m->Ne*0xf=LT0mZX&X-a4(gifs{-$Uk|V(V9MO(|ogKK$Ymvt*a%TBSP9 zsWYxiqncaDdl5~5OUVO4 z$51{{p0{L|fmt6;+1pqi3pe&JdXKRS6@@$(`W?vxSP2nSQWP#^b8nm8afu`PyXK&O zO>aNO_1@PtaP?Pw%^uiLQ_kZbh=r!{Z4p3R-FHySwkAf&0eKLXFWz74*=VZ>9Nio(<(NoLT+uto&GVjhRzt(#5 z^yXu}y909&eO-}B&fyf-5o;3xVbNqt#r)xcuG+4-!UyG=l;0Cg1+)Y4Zz%9K`GbcJ zv9(T#-?l8@txhFRn2z7sL4;E220!CzTv&dthqyV;nj8ZMWZI1#R|U0fl`qip-I$q( zt3j(I%AQZa-Pk2Rds~5Cx%VTRtn>Y7hA;l0y_A9l=?_m`klgUuSN;**s~+2lktWf} zq>HgwEymWLB9^gOpC=OKD@^M;p<%7Yk)|zA->Bc2m#HyMs~-gKtNk|MWc|t{zL1pw zb~I5R7@Rv($4w8y;G=9bb<(yer8&M2vpca!%U$R%^JFq#4wM67NYXF?Umce~{qo~c=y5seijy3sz&Q-nP zzhdm!Si|5jm?x)sEtZiVL(%bOy*MJ-{IkTkrI12jb^pLFoRk#;rTro+20776;mmztLJZ?4rR`zofEK&D+$G* z_cv9N+dzBtkl$oKE@s(_MGW_oXn#Sm8SogtuI??ZqLXcyWF%kbh@ESsM+GvLvZE*p zwd9KE3<3WIl4%5Hgo+Sbqvg%(?HjmBx$Fw*wrJ@_YH;-p)ON^or!Mz$G(i%`Z&$ed zG?!x5X%f^8yE zQBTXAQ<~d^2LrLc=lyoXaQ?fB?m)FP6!QMGt>V&I_awLSR*elBn|kV=N&?}a(FQ46 z22zT!k4%Jk@WQdsC#-L#=l>-HAda6q(=80!k=P2J350#hU&Tv097m_`o7uY2JS^(AE&vzLVvgp;&}z#kt4ZMVh0FZLzE+mXPNnlT z!>O0bh6mYpO|B|flc4F0gAqQo)P?uqWf)%&s8vz&nZ~pg#eJTwp@+(A6!L2q2q}94 zb@90ch&~!w*%;En{L<9?srJe7xuV^)R`Trf)(yp$_L_=P=MYUUk6H%qH-*%AhF4^0ys1Mwzd)Ph%LkKq4T_KbryH5(pF048|Dyq3JRx^*2`;B8=#7p zf~AExV8h#QRx>)REEIpl<(qS2F-ob*2qPd;%ls&BR1p_dbW5B^IsI4irzGq&7_CVH z^Wbn7mo7!PNf=hCrP!KEutB73^Wu1}ZuJVH*7oFRN9D*H;T>_xqP&p^)R*@faqaaAW8mt;5QKcu(ZA|F2vd%k z0K#ECdly{Q*4X5Q+&PfcWaBhOe(Y%b$vAbHd|7=_L>W1590%G8$QFhK26)&x7nIX9uUPw<@D?PFyVafn zj+2ETNq|hltgJ1K7c0s!ioZ9&r26u-b1%Qt?7WmMP3;s%i`L57CuMakGA+c{P>-gY z=w15#w%fXITijj*jR;6zJqfwSSvGz$gq?;dZrY|f>jf5FQ&&|e! zq{p`V#26T(Pk;^c8c7<@kN+rM-2zu_h?|diWXpdH$joWeE!2mbMgo_5n}lf+hbsk2 zAb>r9-9?oRaU-<$vU1#6Gv~2%Q z9BD=uhTZ#4cZ-^IZ1U7^P&S-NqSA?Q7Ea{vFfm+wV? zc*r>aU2)xyW`Ty3+ACdhrfX{VcbIZdK*|%qJaPV%Ho?qbmgDmqd|9{_BXwx4-{uc!NPzr7D2yB;+jt>e zlxM`uh5$usLu`0SGeSV)H%FJ5Nn18vL@yejul7|*O&p6%$T2o4HhmPmm9|p0`H%A) z|Br)RHl#vp9;db|9wHY1@}FduAbQW7dN%>S~*=S3TDWpANFMQBo0^n^k6A z0()Kd!q=>JtGDQFH8FATlz{Rlk~CQ|{YXoojOvKBtFe6yr3rdx{v%MK=@E~gEk7q2 z^VY;^`!8WC^eCYveb@VI{#DNYdF*1zyk!H#5=sK!q>(R=73g4;(3gX=!9^Vd90 z4a1PDU0XyzFE=<_9x`uujyY`3yCJZSdZdWPLu!`~|8)iQmm^y9kY8CoP4d2}`7lrT z5@+pH@6GMFM(O+!TL-rH0tqi?^*^aC8;R1f+w2PWo{RU|2<5m}>TjA=R-?=^siw4o z$hW<+D2>68Ekq0qpc5IG!UI%xG5v<@-(~jfc9HgwN;S0<{m==-t=jaibz0>$SZf(pJ&DPOQ1gZ3SrUa3atBJ1YbQH;GR#EYN)UKKN_qxJb{OOm0+b7o;^ z>JXj!gUkQT8`|m;a^hSA@vLQ@MeyuBtZj=P(`-s}Og<!foQEPYD(A_GcokyEFn zT0h@#(GB>fLZH*mf+8b=35&ZA>$bKu`l4D8^D5S)^0{K9-syv?Yq{wDGG#owwla~Q z1n$kiC`QEcyq^bS@vL6;-~h-|W1guRbGhXEcJyFSXH(4B-wf8la2HSDlm9{^X%vz4 z{7KB_=N8E>dD&w7!afZLfu6B1Um2`kks`n=`K5>O%h`vO3n3mI;v@M zZcr4A)#j%i{U?nY5t>bRB;&2`BzjBLNVSyvaPD&IUCCPMN_C7$akHG~0HtiihmE7z z$b9YH_jrk|*O#%@Hu3~~3VztNR31}xuCl7SqA|jM^*nlCHP5fhqp_!lO%muKuGHo{ z2$=N9ALAWKy%73j-?W%}-$#?&R)q1hR~>(%txm3+xm0dIZgOEtgO~nG{hW$4Z$P?@ zqX8?2fmu&@<|-xe_a1+RhboWP8iNgy$1abTPRU{B9FGeq$sEzvU__@5GK_;WHy14x zcDwh%F)#&T8!n+HR*b17<9kEKj@QaV)cerrgBrU^YNWZUt8{6hh=Tbf?4|DbGS-u! z3Sxb;5_Nt{7Lb!ZPYHe=Y8XHk>h)UqkL^m`A@p`}ve`+@bxE5|Cs@<9Wo{2YJxv@D z9dCggGXgg~vVFp|gOx~_Ty1Jj5)-0RzImmr#x9y|jOhSEB7QF;#P+qj&`v*C%|s0Q z$?%luf|Mi-j(@=IKm857&fyXodmv&qtfCK#3O5t3lq+~s%fV<$ zRS-cl7ak85UYRl{gPI`aNl4*v$9b<&iIKg5qc~XNq*fo*t-~&I8?tBw+pco@U6>j% zSXEdK8e9Ui84jcO-8grAmtb-)|EFQRwl_-;yZ1NLKTpl*^Gls4O2#=4#vLj5jW2m( zv*A0D(ahmmg2`qipL@cc|7D4hjoF3__X~`o5Rt{7kGxUzd{v0u{FuF}VUVwCf0d9h z^tM38c*$I%5Awj}a|lVgz=uHUYqE|E?$0`hF<3fb7!iChutxv|hkyF*I5JB8%LF4( zwMZ_bT_4`}^-PSm?OBb)Y&`+hmqf5=B5bT7C)lxV7$ zSdd3Re)}sR94(?v$*U#FE)u?q8o}^a7Y-z}`lB@vE*61Wf>rOOqQ}p4{nh9VUqsbH zZ!eRW + +#include +#include +#include +#include + +#include "example/all/include/ops_all.hpp" +#include "core/util/include/util.hpp" + +class NesterovATestTaskAll : public ::testing::TestWithParam { + protected: + void SetUp() override { + width = height = channels = -1; + std::string abs_path = ppc::util::GetAbsolutePath("all/example/data/pic_all.jpg"); + data = stbi_load(abs_path.c_str(), &width, &height, &channels, 0); + ASSERT_TRUE(data != nullptr) << "Failed to load image: " << stbi_failure_reason(); + img = std::vector(data, data + (width * height * channels)); + stbi_image_free(data); + + ASSERT_EQ(width, height); + } + + int width = -1, height = -1, channels = -1; + unsigned char* data = nullptr; + std::vector img; +}; + +TEST_P(NesterovATestTaskAll, MatmulFromPic) { + int divider = GetParam(); + const int k_count = (width + height) / divider; + + std::vector in(k_count * k_count, 0); + for (int i = 0; i < k_count; i++) { + in[(i * k_count) + i] = 1; + } + + nesterov_a_test_task_all::TestTaskALL test_task_all(in); + ASSERT_TRUE(test_task_all.Validation()); + test_task_all.PreProcessing(); + test_task_all.Run(); + test_task_all.PostProcessing(); + EXPECT_EQ(in, test_task_all.Get()); +} + +TEST_P(NesterovATestTaskAll, MatMulUtilFromPic) { + int divider = GetParam(); + const int k_count = (width + height) / divider; + + std::vector in(k_count * k_count, 0); + for (int i = 0; i < k_count; i++) { + in[(i * k_count) + i] = 1; + } + std::vector out(k_count * k_count, 0); + nesterov_a_test_task_all::MatMul(in, static_cast(k_count), out); + + EXPECT_EQ(in, out); +} + +TEST_P(NesterovATestTaskAll, MatMulTBBUtilFromPic) { + int divider = GetParam(); + const int k_count = (width + height) / divider; + + std::vector in(k_count * k_count, 0); + for (int i = 0; i < k_count; i++) { + in[(i * k_count) + i] = 1; + } + std::vector out(k_count * k_count, 0); + nesterov_a_test_task_all::MatMulTBB(in, static_cast(k_count), out); + + EXPECT_EQ(in, out); +} + +INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovATestTaskAll, ::testing::Values(5, 10)); diff --git a/tasks-1/example/tests/perf_tests/main.cpp b/tasks-1/example/tests/perf_tests/main.cpp new file mode 100644 index 000000000..ea9baf472 --- /dev/null +++ b/tasks-1/example/tests/perf_tests/main.cpp @@ -0,0 +1,56 @@ +#include +#include + +#include +#include +#include + +#include "example/all/include/ops_all.hpp" +#include "core/perf/include/perf.hpp" +#include "core/util/include/util.hpp" + +class NesterovAllRunTest : public ::testing::TestWithParam { + protected: + static constexpr int kCount = 400; + std::vector input_data; + + void SetUp() override { + input_data.assign(kCount * kCount, 0); + for (int i = 0; i < kCount; ++i) { + input_data[(i * kCount) + i] = 1; + } + } + + void ExecuteTest(ppc::core::PerfResults::TypeOfRunning mode) { + auto task = std::make_shared(input_data); + ppc::core::Perf perf(task); + + ppc::core::PerfAttr perf_attr; + const auto t0 = std::chrono::high_resolution_clock::now(); + perf_attr.current_timer = [&] { + auto now = std::chrono::high_resolution_clock::now(); + auto ns = std::chrono::duration_cast(now - t0).count(); + return static_cast(ns) * 1e-9; + }; + + if (mode == ppc::core::PerfResults::TypeOfRunning::kPipeline) { + perf.PipelineRun(perf_attr); + } else { + perf.TaskRun(perf_attr); + } + + int rank = -1; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + if (rank == 0) { + perf.PrintPerfStatistic(); + } + + ASSERT_EQ(input_data, task->Get()); + } +}; + +TEST_P(NesterovAllRunTest, RunModes) { ExecuteTest(GetParam()); } + +INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, NesterovAllRunTest, + ::testing::Values(ppc::core::PerfResults::TypeOfRunning::kPipeline, + ppc::core::PerfResults::TypeOfRunning::kTaskRun)); diff --git a/tasks-1/example/tests/runner.cpp b/tasks-1/example/tests/runner.cpp new file mode 100644 index 000000000..5ea930ad8 --- /dev/null +++ b/tasks-1/example/tests/runner.cpp @@ -0,0 +1,93 @@ +#include +#include + +#include +#include +#include +#include +#include + +#include "core/util/include/util.hpp" +#include "oneapi/tbb/global_control.h" + +class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { + public: + UnreadMessagesDetector() = default; + + void OnTestEnd(const ::testing::TestInfo& /*test_info*/) override { + int rank = -1; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + MPI_Barrier(MPI_COMM_WORLD); + + int flag = -1; + MPI_Status status; + + MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status); + + if (flag != 0) { + fprintf( + stderr, + "[ PROCESS %d ] [ FAILED ] %s.%s: MPI message queue has an unread message from process %d with tag %d\n", + rank, "test_suite_name", "test_name", status.MPI_SOURCE, status.MPI_TAG); + MPI_Finalize(); + exit(2); + } + + MPI_Barrier(MPI_COMM_WORLD); + } + + private: +}; + +class WorkerTestFailurePrinter : public ::testing::EmptyTestEventListener { + public: + explicit WorkerTestFailurePrinter(std::shared_ptr<::testing::TestEventListener> base) : base_(std::move(base)) {} + + void OnTestEnd(const ::testing::TestInfo& test_info) override { + if (test_info.result()->Passed()) { + return; + } + PrintProcessRank(); + base_->OnTestEnd(test_info); + } + + void OnTestPartResult(const ::testing::TestPartResult& test_part_result) override { + if (test_part_result.passed() || test_part_result.skipped()) { + return; + } + PrintProcessRank(); + base_->OnTestPartResult(test_part_result); + } + + private: + static void PrintProcessRank() { + int rank = -1; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + printf(" [ PROCESS %d ] ", rank); + } + + std::shared_ptr<::testing::TestEventListener> base_; +}; + +int main(int argc, char** argv) { + MPI_Init(&argc, &argv); + + // Limit the number of threads in TBB + tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetPPCNumThreads()); + + ::testing::InitGoogleTest(&argc, argv); + + auto& listeners = ::testing::UnitTest::GetInstance()->listeners(); + int rank = -1; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + if (rank != 0 && (argc < 2 || argv[1] != std::string("--print-workers"))) { + auto* listener = listeners.Release(listeners.default_result_printer()); + listeners.Append(new WorkerTestFailurePrinter(std::shared_ptr<::testing::TestEventListener>(listener))); + } + listeners.Append(new UnreadMessagesDetector()); + auto status = RUN_ALL_TESTS(); + + MPI_Finalize(); + return status; +} From e93c1040da2ee1a532e30470d4e6c503eb007e8b Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 18 May 2025 13:33:22 +0200 Subject: [PATCH 005/141] first uniting tests --- modules/core/task/include/task.hpp | 5 +++ tasks-1/CMakeLists.txt | 2 +- tasks-1/example/all/include/ops_all.hpp | 4 +- tasks-1/example/all/src/ops_all.cpp | 2 - tasks-1/example/tests/perf_tests/main.cpp | 48 ++++++++++++++++++----- 5 files changed, 46 insertions(+), 15 deletions(-) diff --git a/modules/core/task/include/task.hpp b/modules/core/task/include/task.hpp index 630912060..cbc95b1bf 100644 --- a/modules/core/task/include/task.hpp +++ b/modules/core/task/include/task.hpp @@ -31,6 +31,11 @@ class Task { // get state of testing StateOfTesting &GetStateOfTesting() { return state_of_testing_; } + template + static T Get(const Class& obj, T Class::* member) { + return obj.*member; + } + virtual ~Task(); protected: diff --git a/tasks-1/CMakeLists.txt b/tasks-1/CMakeLists.txt index ba7e09610..9467d6cfa 100644 --- a/tasks-1/CMakeLists.txt +++ b/tasks-1/CMakeLists.txt @@ -17,7 +17,7 @@ endforeach() set(output_file "${CMAKE_BINARY_DIR}/revert-list.txt") file(WRITE ${output_file} "${CONTENT}") -message(STATUS "revert list") +message(STATUS "Revert list") foreach (dir_name ${list_of_reverts}) message(STATUS "-- ${dir_name}") file(APPEND ${output_file} "${dir_name}\n") diff --git a/tasks-1/example/all/include/ops_all.hpp b/tasks-1/example/all/include/ops_all.hpp index fab463ee8..9dd5f5b7b 100644 --- a/tasks-1/example/all/include/ops_all.hpp +++ b/tasks-1/example/all/include/ops_all.hpp @@ -17,10 +17,8 @@ class TestTaskALL : public ppc::core::Task { bool PreProcessingImpl() override; bool RunImpl() override; bool PostProcessingImpl() override; - std::vector Get(); - - private: std::vector input_, output_; + private: int rc_size_{}; }; diff --git a/tasks-1/example/all/src/ops_all.cpp b/tasks-1/example/all/src/ops_all.cpp index f89b24f37..6c95809a8 100644 --- a/tasks-1/example/all/src/ops_all.cpp +++ b/tasks-1/example/all/src/ops_all.cpp @@ -64,5 +64,3 @@ bool nesterov_a_test_task_all::TestTaskALL::RunImpl() { } bool nesterov_a_test_task_all::TestTaskALL::PostProcessingImpl() { return true; } - -std::vector nesterov_a_test_task_all::TestTaskALL::Get() { return output_; } diff --git a/tasks-1/example/tests/perf_tests/main.cpp b/tasks-1/example/tests/perf_tests/main.cpp index ea9baf472..60e3dd336 100644 --- a/tasks-1/example/tests/perf_tests/main.cpp +++ b/tasks-1/example/tests/perf_tests/main.cpp @@ -9,7 +9,11 @@ #include "core/perf/include/perf.hpp" #include "core/util/include/util.hpp" -class NesterovAllRunTest : public ::testing::TestWithParam { +using TestParam = std::tuple(std::vector)>, + std::function(std::shared_ptr)>>; + +class NesterovAllRunTest : public ::testing::TestWithParam { protected: static constexpr int kCount = 400; std::vector input_data; @@ -21,8 +25,10 @@ class NesterovAllRunTest : public ::testing::TestWithParam(input_data); + void ExecuteTest(ppc::core::PerfResults::TypeOfRunning mode, + std::function(std::vector)> task_getter, + std::function(std::shared_ptr)> data_getter) { + auto task = task_getter(input_data); ppc::core::Perf perf(task); ppc::core::PerfAttr perf_attr; @@ -44,13 +50,37 @@ class NesterovAllRunTest : public ::testing::TestWithParamGet()); + ASSERT_EQ(input_data, data_getter(task)); } }; -TEST_P(NesterovAllRunTest, RunModes) { ExecuteTest(GetParam()); } +TEST_P(NesterovAllRunTest, RunModes) { + ExecuteTest(std::get<0>(GetParam()), std::get<1>(GetParam()), std::get<2>(GetParam())); +} -INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, NesterovAllRunTest, - ::testing::Values(ppc::core::PerfResults::TypeOfRunning::kPipeline, - ppc::core::PerfResults::TypeOfRunning::kTaskRun)); +INSTANTIATE_TEST_SUITE_P_NOLINT( + RunModeTests, + NesterovAllRunTest, + ::testing::Values( + std::make_tuple( + ppc::core::PerfResults::TypeOfRunning::kPipeline, + [](std::vector in) -> std::shared_ptr { + return std::make_shared(in); + }, + [](std::shared_ptr current_task) -> std::vector { + auto inheritance_task = std::dynamic_pointer_cast(current_task); + return ppc::core::Task::Get(*inheritance_task, &nesterov_a_test_task_all::TestTaskALL::output_); + } + ), + std::make_tuple( + ppc::core::PerfResults::TypeOfRunning::kTaskRun, + [](std::vector in) -> std::shared_ptr { + return std::make_shared(in); + }, + [](std::shared_ptr current_task) -> std::vector { + auto inheritance_task = std::dynamic_pointer_cast(current_task); + return ppc::core::Task::Get(*inheritance_task, &nesterov_a_test_task_all::TestTaskALL::output_); + } + ) + ) +); From 1c9da2e76d846f0166be29596209a9f03e5cdb3d Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Mon, 19 May 2025 00:19:27 +0200 Subject: [PATCH 006/141] second part uniting tests --- modules/core/task/include/task.hpp | 13 ++++ tasks-1/example/mpi/include/ops_mpi.hpp | 2 +- tasks-1/example/omp/include/ops_omp.hpp | 2 +- tasks-1/example/seq/include/ops_seq.hpp | 2 +- tasks-1/example/stl/include/ops_stl.hpp | 2 +- tasks-1/example/tbb/include/ops_tbb.hpp | 2 +- tasks-1/example/tests/perf_tests/main.cpp | 82 +++++++++++++++-------- 7 files changed, 71 insertions(+), 34 deletions(-) diff --git a/modules/core/task/include/task.hpp b/modules/core/task/include/task.hpp index cbc95b1bf..eee2ca410 100644 --- a/modules/core/task/include/task.hpp +++ b/modules/core/task/include/task.hpp @@ -66,4 +66,17 @@ class Task { bool IsFullPipelineStage(); }; +using TaskPtr = std::shared_ptr; + +template +std::shared_ptr task_getter(OutputType in) { + return std::make_shared(in); +} + +template +OutputType data_getter(TaskPtr current_task) { + auto inheritance_task = std::dynamic_pointer_cast(current_task); + return ppc::core::Task::Get(*inheritance_task, &TaskType::output_); +} + } // namespace ppc::core diff --git a/tasks-1/example/mpi/include/ops_mpi.hpp b/tasks-1/example/mpi/include/ops_mpi.hpp index 31b1f0424..1e158a5bd 100644 --- a/tasks-1/example/mpi/include/ops_mpi.hpp +++ b/tasks-1/example/mpi/include/ops_mpi.hpp @@ -19,8 +19,8 @@ class TestTaskMPI : public ppc::core::Task { bool PostProcessingImpl() override; std::vector Get(); - private: std::vector input_, output_; + private: int rc_size_{}; void MultiplyMatrixBasedOnRank(); diff --git a/tasks-1/example/omp/include/ops_omp.hpp b/tasks-1/example/omp/include/ops_omp.hpp index 87209c39e..ca8cfd90a 100644 --- a/tasks-1/example/omp/include/ops_omp.hpp +++ b/tasks-1/example/omp/include/ops_omp.hpp @@ -15,9 +15,9 @@ class TestTaskOpenMP : public ppc::core::Task { bool RunImpl() override; bool PostProcessingImpl() override; std::vector Get(); + std::vector input_, output_; private: - std::vector input_, output_; int rc_size_{}; }; diff --git a/tasks-1/example/seq/include/ops_seq.hpp b/tasks-1/example/seq/include/ops_seq.hpp index f03fc7fb8..aedc0350c 100644 --- a/tasks-1/example/seq/include/ops_seq.hpp +++ b/tasks-1/example/seq/include/ops_seq.hpp @@ -15,9 +15,9 @@ class TestTaskSequential : public ppc::core::Task { bool RunImpl() override; bool PostProcessingImpl() override; std::vector Get(); + std::vector input_, output_; private: - std::vector input_, output_; int rc_size_{}; }; diff --git a/tasks-1/example/stl/include/ops_stl.hpp b/tasks-1/example/stl/include/ops_stl.hpp index 1461d8ca2..72aafed8c 100644 --- a/tasks-1/example/stl/include/ops_stl.hpp +++ b/tasks-1/example/stl/include/ops_stl.hpp @@ -15,9 +15,9 @@ class TestTaskSTL : public ppc::core::Task { bool RunImpl() override; bool PostProcessingImpl() override; std::vector Get(); + std::vector input_, output_; private: - std::vector input_, output_; int rc_size_{}; }; diff --git a/tasks-1/example/tbb/include/ops_tbb.hpp b/tasks-1/example/tbb/include/ops_tbb.hpp index 4df85defb..f89103655 100644 --- a/tasks-1/example/tbb/include/ops_tbb.hpp +++ b/tasks-1/example/tbb/include/ops_tbb.hpp @@ -15,9 +15,9 @@ class TestTaskTBB : public ppc::core::Task { bool RunImpl() override; bool PostProcessingImpl() override; std::vector Get(); + std::vector input_, output_; private: - std::vector input_, output_; int rc_size_{}; }; diff --git a/tasks-1/example/tests/perf_tests/main.cpp b/tasks-1/example/tests/perf_tests/main.cpp index 60e3dd336..da03fac0b 100644 --- a/tasks-1/example/tests/perf_tests/main.cpp +++ b/tasks-1/example/tests/perf_tests/main.cpp @@ -6,17 +6,25 @@ #include #include "example/all/include/ops_all.hpp" +#include "example/mpi/include/ops_mpi.hpp" +#include "example/omp/include/ops_omp.hpp" +#include "example/seq/include/ops_seq.hpp" +#include "example/stl/include/ops_stl.hpp" +#include "example/tbb/include/ops_tbb.hpp" + #include "core/perf/include/perf.hpp" #include "core/util/include/util.hpp" +using OutputType = std::vector; + using TestParam = std::tuple(std::vector)>, - std::function(std::shared_ptr)>>; + std::function, + std::function>; -class NesterovAllRunTest : public ::testing::TestWithParam { +class ExampleRunPerfTest : public ::testing::TestWithParam { protected: static constexpr int kCount = 400; - std::vector input_data; + OutputType input_data; void SetUp() override { input_data.assign(kCount * kCount, 0); @@ -26,8 +34,8 @@ class NesterovAllRunTest : public ::testing::TestWithParam { } void ExecuteTest(ppc::core::PerfResults::TypeOfRunning mode, - std::function(std::vector)> task_getter, - std::function(std::shared_ptr)> data_getter) { + std::function task_getter, + std::function data_getter) { auto task = task_getter(input_data); ppc::core::Perf perf(task); @@ -54,33 +62,49 @@ class NesterovAllRunTest : public ::testing::TestWithParam { } }; -TEST_P(NesterovAllRunTest, RunModes) { +TEST_P(ExampleRunPerfTest, RunModes) { ExecuteTest(std::get<0>(GetParam()), std::get<1>(GetParam()), std::get<2>(GetParam())); } INSTANTIATE_TEST_SUITE_P_NOLINT( RunModeTests, - NesterovAllRunTest, + ExampleRunPerfTest, ::testing::Values( - std::make_tuple( - ppc::core::PerfResults::TypeOfRunning::kPipeline, - [](std::vector in) -> std::shared_ptr { - return std::make_shared(in); - }, - [](std::shared_ptr current_task) -> std::vector { - auto inheritance_task = std::dynamic_pointer_cast(current_task); - return ppc::core::Task::Get(*inheritance_task, &nesterov_a_test_task_all::TestTaskALL::output_); - } - ), - std::make_tuple( - ppc::core::PerfResults::TypeOfRunning::kTaskRun, - [](std::vector in) -> std::shared_ptr { - return std::make_shared(in); - }, - [](std::shared_ptr current_task) -> std::vector { - auto inheritance_task = std::dynamic_pointer_cast(current_task); - return ppc::core::Task::Get(*inheritance_task, &nesterov_a_test_task_all::TestTaskALL::output_); - } - ) - ) + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, + ppc::core::task_getter, + ppc::core::data_getter), + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, + ppc::core::task_getter, + ppc::core::data_getter), + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, + ppc::core::task_getter, + ppc::core::data_getter), + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, + ppc::core::task_getter, + ppc::core::data_getter), + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, + ppc::core::task_getter, + ppc::core::data_getter), + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, + ppc::core::task_getter, + ppc::core::data_getter), + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, + ppc::core::task_getter, + ppc::core::data_getter), + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, + ppc::core::task_getter, + ppc::core::data_getter), + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, + ppc::core::task_getter, + ppc::core::data_getter), + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, + ppc::core::task_getter, + ppc::core::data_getter), + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, + ppc::core::task_getter, + ppc::core::data_getter), + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, + ppc::core::task_getter, + ppc::core::data_getter) + ) ); From 9570c5308d8ef56496157c96338f328bc04e6247 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Mon, 19 May 2025 15:14:21 +0200 Subject: [PATCH 007/141] 3rd part perf unifying tests --- tasks-1/example/tests/perf_tests/main.cpp | 123 +++++++++++----------- 1 file changed, 62 insertions(+), 61 deletions(-) diff --git a/tasks-1/example/tests/perf_tests/main.cpp b/tasks-1/example/tests/perf_tests/main.cpp index da03fac0b..2ca197bda 100644 --- a/tasks-1/example/tests/perf_tests/main.cpp +++ b/tasks-1/example/tests/perf_tests/main.cpp @@ -15,14 +15,57 @@ #include "core/perf/include/perf.hpp" #include "core/util/include/util.hpp" -using OutputType = std::vector; - +template using TestParam = std::tuple, - std::function>; + std::function, + std::function>; -class ExampleRunPerfTest : public ::testing::TestWithParam { +template +class BaseRunPerfTests : public ::testing::TestWithParam> { protected: + virtual void setPerfAttributes(ppc::core::PerfAttr& perf_attrs) = 0; + virtual bool checkData(std::function data_getter) = 0; + virtual OutputTypeParameter getInputData() = 0; + ppc::core::TaskPtr task; + + void ExecuteTest(ppc::core::PerfResults::TypeOfRunning mode, + std::function task_getter, + std::function data_getter) { + task = task_getter(getInputData()); + ppc::core::Perf perf(task); + ppc::core::PerfAttr perf_attr; + setPerfAttributes(perf_attr); + + if (mode == ppc::core::PerfResults::TypeOfRunning::kPipeline) { + perf.PipelineRun(perf_attr); + } else if (mode == ppc::core::PerfResults::TypeOfRunning::kTaskRun) { + perf.TaskRun(perf_attr); + } else { + throw std::runtime_error("Performance mode is wrong"); + } + + int rank = -1; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + if (rank == 0) { + perf.PrintPerfStatistic(); + } + + ASSERT_TRUE(checkData(data_getter)); + } +}; + +#define ADD_MODES(TaskType, OutputTypeParam) \ + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, \ + ppc::core::task_getter, \ + ppc::core::data_getter), \ + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, \ + ppc::core::task_getter, \ + ppc::core::data_getter) + + +using OutputType = std::vector; + +class ExampleRunPerfTest : public BaseRunPerfTests { static constexpr int kCount = 400; OutputType input_data; @@ -33,32 +76,21 @@ class ExampleRunPerfTest : public ::testing::TestWithParam { } } - void ExecuteTest(ppc::core::PerfResults::TypeOfRunning mode, - std::function task_getter, - std::function data_getter) { - auto task = task_getter(input_data); - ppc::core::Perf perf(task); - - ppc::core::PerfAttr perf_attr; + void setPerfAttributes(ppc::core::PerfAttr& perf_attrs) final { const auto t0 = std::chrono::high_resolution_clock::now(); - perf_attr.current_timer = [&] { + perf_attrs.current_timer = [&] { auto now = std::chrono::high_resolution_clock::now(); auto ns = std::chrono::duration_cast(now - t0).count(); return static_cast(ns) * 1e-9; }; + } - if (mode == ppc::core::PerfResults::TypeOfRunning::kPipeline) { - perf.PipelineRun(perf_attr); - } else { - perf.TaskRun(perf_attr); - } + bool checkData(std::function data_getter) final { + return input_data == data_getter(task); + } - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - if (rank == 0) { - perf.PrintPerfStatistic(); - } - ASSERT_EQ(input_data, data_getter(task)); + OutputType getInputData() final { + return input_data; } }; @@ -70,41 +102,10 @@ INSTANTIATE_TEST_SUITE_P_NOLINT( RunModeTests, ExampleRunPerfTest, ::testing::Values( - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, - ppc::core::task_getter, - ppc::core::data_getter), - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, - ppc::core::task_getter, - ppc::core::data_getter), - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, - ppc::core::task_getter, - ppc::core::data_getter), - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, - ppc::core::task_getter, - ppc::core::data_getter), - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, - ppc::core::task_getter, - ppc::core::data_getter), - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, - ppc::core::task_getter, - ppc::core::data_getter), - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, - ppc::core::task_getter, - ppc::core::data_getter), - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, - ppc::core::task_getter, - ppc::core::data_getter), - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, - ppc::core::task_getter, - ppc::core::data_getter), - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, - ppc::core::task_getter, - ppc::core::data_getter), - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, - ppc::core::task_getter, - ppc::core::data_getter), - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, - ppc::core::task_getter, - ppc::core::data_getter) - ) + ADD_MODES(nesterov_a_test_task_all::TestTaskALL, OutputType), + ADD_MODES(nesterov_a_test_task_mpi::TestTaskMPI, OutputType), + ADD_MODES(nesterov_a_test_task_omp::TestTaskOpenMP, OutputType), + ADD_MODES(nesterov_a_test_task_seq::TestTaskSequential, OutputType), + ADD_MODES(nesterov_a_test_task_stl::TestTaskSTL, OutputType), + ADD_MODES(nesterov_a_test_task_tbb::TestTaskTBB, OutputType)) ); From 594201a2f101052fe95cb00648665b7924585f40 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Mon, 19 May 2025 16:51:46 +0200 Subject: [PATCH 008/141] 4th part perf unifying tests --- modules/core/perf/include/perf.hpp | 2 +- modules/core/perf/src/perf.cpp | 19 ++++------------- modules/core/task/include/task.hpp | 4 ++-- modules/core/util/include/util.hpp | 26 +++++++++++++++++++++++ tasks-1/example/tests/perf_tests/main.cpp | 20 +++++++++++------ 5 files changed, 46 insertions(+), 25 deletions(-) diff --git a/modules/core/perf/include/perf.hpp b/modules/core/perf/include/perf.hpp index 61cc68559..0b37fe30d 100644 --- a/modules/core/perf/include/perf.hpp +++ b/modules/core/perf/include/perf.hpp @@ -31,7 +31,7 @@ class Perf { // Check performance of task's Run() function void TaskRun(const PerfAttr& perf_attr); // Pint results for automation checkers - void PrintPerfStatistic() const; + void PrintPerfStatistic(std::string test_id) const; // Get performance result structure of the current task PerfResults GetPerfResults(); diff --git a/modules/core/perf/src/perf.cpp b/modules/core/perf/src/perf.cpp index aac88841c..5f51b0069 100644 --- a/modules/core/perf/src/perf.cpp +++ b/modules/core/perf/src/perf.cpp @@ -55,14 +55,8 @@ void ppc::core::Perf::CommonRun(const PerfAttr& perf_attr, const std::functioncurrent_test_info()->file()); - std::string ppc_regex_template("parallel_programming_course"); - std::string perf_regex_template("perf_tests"); +void ppc::core::Perf::PrintPerfStatistic(std::string test_id) const { std::string type_test_name; - - auto time_secs = perf_results_.time_sec; - if (perf_results_.type_of_running == PerfResults::TypeOfRunning::kTaskRun) { type_test_name = "task_run"; } else if (perf_results_.type_of_running == PerfResults::TypeOfRunning::kPipeline) { @@ -73,23 +67,18 @@ void ppc::core::Perf::PrintPerfStatistic() const { throw std::runtime_error(err_msg.str().c_str()); } - auto first_found_position = relative_path.find(ppc_regex_template) + ppc_regex_template.length() + 1; - relative_path.erase(0, first_found_position); - - auto last_found_position = relative_path.find(perf_regex_template) - 1; - relative_path.erase(last_found_position, relative_path.length() - 1); - + auto time_secs = perf_results_.time_sec; std::stringstream perf_res_str; if (time_secs < PerfResults::kMaxTime) { perf_res_str << std::fixed << std::setprecision(10) << time_secs; - std::cout << relative_path << ":" << type_test_name << ":" << perf_res_str.str() << '\n'; + std::cout << test_id << ":" << type_test_name << ":" << perf_res_str.str() << '\n'; } else { std::stringstream err_msg; err_msg << '\n' << "Task execute time need to be: "; err_msg << "time < " << PerfResults::kMaxTime << " secs." << '\n'; err_msg << "Original time in secs: " << time_secs << '\n'; perf_res_str << std::fixed << std::setprecision(10) << -1.0; - std::cout << relative_path << ":" << type_test_name << ":" << perf_res_str.str() << '\n'; + std::cout << test_id << ":" << type_test_name << ":" << perf_res_str.str() << '\n'; throw std::runtime_error(err_msg.str().c_str()); } } diff --git a/modules/core/task/include/task.hpp b/modules/core/task/include/task.hpp index eee2ca410..76754018a 100644 --- a/modules/core/task/include/task.hpp +++ b/modules/core/task/include/task.hpp @@ -31,8 +31,8 @@ class Task { // get state of testing StateOfTesting &GetStateOfTesting() { return state_of_testing_; } - template - static T Get(const Class& obj, T Class::* member) { + template + static T Get(const Class &obj, T Class::*member) { return obj.*member; } diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index 80070d14a..39e103b3a 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -1,5 +1,6 @@ #pragma once #include +#include /* NOLINTBEGIN */ #define INSTANTIATE_TEST_SUITE_P_NOLINT(prefix, test_case_name, generator) \ @@ -15,4 +16,29 @@ namespace ppc::util { std::string GetAbsolutePath(const std::string &relative_path); int GetPPCNumThreads(); +template +consteval std::string_view get_namespace() { +#if defined(__clang__) || defined(__GNUC__) + constexpr std::string_view func = __PRETTY_FUNCTION__; + // example: "consteval std::string_view get_namespace() [with T = my_namespace::MyClass]" + constexpr std::string_view key = "T = "; +#elif defined(_MSC_VER) + constexpr std::string_view func = __FUNCSIG__; + // example: "class std::basic_string_view > __cdecl get_namespace(void)" + constexpr std::string_view key = "get_namespace<"; +#else + static_assert(false, "Unsupported compiler"); +#endif + + auto start = func.find(key); + if (start == std::string_view::npos) return {}; + start += key.size(); + + auto end = func.find("::", start); + if (end == std::string_view::npos) return {}; + + return func.substr(start, end - start); +} + } // namespace ppc::util diff --git a/tasks-1/example/tests/perf_tests/main.cpp b/tasks-1/example/tests/perf_tests/main.cpp index 2ca197bda..046749959 100644 --- a/tasks-1/example/tests/perf_tests/main.cpp +++ b/tasks-1/example/tests/perf_tests/main.cpp @@ -18,7 +18,8 @@ template using TestParam = std::tuple, - std::function>; + std::function, + std::string>; template class BaseRunPerfTests : public ::testing::TestWithParam> { @@ -30,7 +31,8 @@ class BaseRunPerfTests : public ::testing::TestWithParam task_getter, - std::function data_getter) { + std::function data_getter, + std::string test_name) { task = task_getter(getInputData()); ppc::core::Perf perf(task); ppc::core::PerfAttr perf_attr; @@ -41,13 +43,15 @@ class BaseRunPerfTests : public ::testing::TestWithParam, \ - ppc::core::data_getter), \ + ppc::core::data_getter,\ + ppc::util::get_namespace()), \ std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, \ ppc::core::task_getter, \ - ppc::core::data_getter) + ppc::core::data_getter,\ + ppc::util::get_namespace()) using OutputType = std::vector; @@ -95,7 +101,7 @@ class ExampleRunPerfTest : public BaseRunPerfTests { }; TEST_P(ExampleRunPerfTest, RunModes) { - ExecuteTest(std::get<0>(GetParam()), std::get<1>(GetParam()), std::get<2>(GetParam())); + ExecuteTest(std::get<0>(GetParam()), std::get<1>(GetParam()), std::get<2>(GetParam()), std::get<3>(GetParam())); } INSTANTIATE_TEST_SUITE_P_NOLINT( From 15e673fe70b91c9c187199dc1a406d7dcc272ee4 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Mon, 19 May 2025 19:16:48 +0200 Subject: [PATCH 009/141] Change API --- modules/core/CMakeLists.txt | 8 ++ modules/core/perf/include/perf.hpp | 74 +++++++++++-- modules/core/perf/src/perf.cpp | 86 --------------- modules/core/task/include/task.hpp | 127 ++++++++++++++++++---- modules/core/task/src/task.cpp | 101 ----------------- modules/core/util/include/test_util.hpp | 61 +++++++++++ modules/core/util/include/util.hpp | 2 +- tasks-1/example/all/include/ops_all.hpp | 8 +- tasks-1/example/all/src/ops_all.cpp | 22 ++-- tasks-1/example/mpi/include/ops_mpi.hpp | 10 +- tasks-1/example/mpi/src/ops_mpi.cpp | 62 ++++++----- tasks-1/example/omp/include/ops_omp.hpp | 9 +- tasks-1/example/omp/src/ops_omp.cpp | 18 +-- tasks-1/example/seq/include/ops_seq.hpp | 9 +- tasks-1/example/seq/src/ops_seq.cpp | 16 +-- tasks-1/example/stl/include/ops_stl.hpp | 9 +- tasks-1/example/stl/src/ops_stl.cpp | 16 +-- tasks-1/example/tbb/include/ops_tbb.hpp | 9 +- tasks-1/example/tbb/src/ops_tbb.cpp | 18 +-- tasks-1/example/tests/perf_tests/main.cpp | 84 +++----------- 20 files changed, 369 insertions(+), 380 deletions(-) delete mode 100644 modules/core/perf/src/perf.cpp delete mode 100644 modules/core/task/src/task.cpp create mode 100644 modules/core/util/include/test_util.hpp diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index 0237aab38..63659971e 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -27,6 +27,14 @@ add_executable(${exec_func_tests} ${FUNC_TESTS_SOURCE_FILES}) add_dependencies(${exec_func_tests} ppc_googletest) target_link_directories(${exec_func_tests} PUBLIC ${CMAKE_BINARY_DIR}/ppc_googletest/install/lib) target_link_libraries(${exec_func_tests} PUBLIC gtest gtest_main) +if( MPI_COMPILE_FLAGS ) + set_target_properties(${exec_func_tests} PROPERTIES COMPILE_FLAGS "${MPI_COMPILE_FLAGS}") +endif( MPI_COMPILE_FLAGS ) + +if( MPI_LINK_FLAGS ) + set_target_properties(${exec_func_tests} PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}") +endif( MPI_LINK_FLAGS ) +target_link_libraries(${exec_func_tests} PUBLIC ${MPI_LIBRARIES}) target_link_libraries(${exec_func_tests} PUBLIC ${exec_func_lib}) diff --git a/modules/core/perf/include/perf.hpp b/modules/core/perf/include/perf.hpp index 0b37fe30d..8e08d5d96 100644 --- a/modules/core/perf/include/perf.hpp +++ b/modules/core/perf/include/perf.hpp @@ -21,24 +21,84 @@ struct PerfResults { constexpr static double kMaxTime = 10.0; }; +template class Perf { public: // Init performance analysis with initialized task and initialized data - explicit Perf(const std::shared_ptr& task_ptr); + explicit Perf(const TaskPtr& task_ptr) : task_(task_ptr) { + task_ptr->GetStateOfTesting() = Task::StateOfTesting::kPerf; + } // Check performance of full task's pipeline: PreProcessing() -> // Validation() -> Run() -> PostProcessing() - void PipelineRun(const PerfAttr& perf_attr); + void PipelineRun(const PerfAttr& perf_attr) { + perf_results_.type_of_running = PerfResults::TypeOfRunning::kPipeline; + + CommonRun( + perf_attr, + [&]() { + task_->Validation(); + task_->PreProcessing(); + task_->Run(); + task_->PostProcessing(); + }, + perf_results_); + } // Check performance of task's Run() function - void TaskRun(const PerfAttr& perf_attr); + void TaskRun(const PerfAttr& perf_attr) { + perf_results_.type_of_running = PerfResults::TypeOfRunning::kTaskRun; + + task_->Validation(); + task_->PreProcessing(); + CommonRun(perf_attr, [&]() { task_->Run(); }, perf_results_); + task_->PostProcessing(); + + task_->Validation(); + task_->PreProcessing(); + task_->Run(); + task_->PostProcessing(); + } // Pint results for automation checkers - void PrintPerfStatistic(std::string test_id) const; + void PrintPerfStatistic(std::string test_id) const { + std::string type_test_name; + if (perf_results_.type_of_running == PerfResults::TypeOfRunning::kTaskRun) { + type_test_name = "task_run"; + } else if (perf_results_.type_of_running == PerfResults::TypeOfRunning::kPipeline) { + type_test_name = "pipeline"; + } else { + std::stringstream err_msg; + err_msg << '\n' << "The type of performance check for the task was not selected.\n"; + throw std::runtime_error(err_msg.str().c_str()); + } + + auto time_secs = perf_results_.time_sec; + std::stringstream perf_res_str; + if (time_secs < PerfResults::kMaxTime) { + perf_res_str << std::fixed << std::setprecision(10) << time_secs; + std::cout << test_id << ":" << type_test_name << ":" << perf_res_str.str() << '\n'; + } else { + std::stringstream err_msg; + err_msg << '\n' << "Task execute time need to be: "; + err_msg << "time < " << PerfResults::kMaxTime << " secs." << '\n'; + err_msg << "Original time in secs: " << time_secs << '\n'; + perf_res_str << std::fixed << std::setprecision(10) << -1.0; + std::cout << test_id << ":" << type_test_name << ":" << perf_res_str.str() << '\n'; + throw std::runtime_error(err_msg.str().c_str()); + } + } // Get performance result structure of the current task - PerfResults GetPerfResults(); + PerfResults GetPerfResults() { return perf_results_; } private: PerfResults perf_results_; - std::shared_ptr task_; - static void CommonRun(const PerfAttr& perf_attr, const std::function& pipeline, PerfResults& perf_results); + std::shared_ptr> task_; + static void CommonRun(const PerfAttr& perf_attr, const std::function& pipeline, PerfResults& perf_results) { + auto begin = perf_attr.current_timer(); + for (uint64_t i = 0; i < perf_attr.num_running; i++) { + pipeline(); + } + auto end = perf_attr.current_timer(); + perf_results.time_sec = end - begin; + } }; } // namespace ppc::core diff --git a/modules/core/perf/src/perf.cpp b/modules/core/perf/src/perf.cpp deleted file mode 100644 index 5f51b0069..000000000 --- a/modules/core/perf/src/perf.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "core/perf/include/perf.hpp" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "core/task/include/task.hpp" - -ppc::core::Perf::Perf(const std::shared_ptr& task_ptr) : task_(task_ptr) { - task_ptr->GetStateOfTesting() = Task::StateOfTesting::kPerf; -} - -void ppc::core::Perf::PipelineRun(const PerfAttr& perf_attr) { - perf_results_.type_of_running = PerfResults::TypeOfRunning::kPipeline; - - CommonRun( - perf_attr, - [&]() { - task_->Validation(); - task_->PreProcessing(); - task_->Run(); - task_->PostProcessing(); - }, - perf_results_); -} - -void ppc::core::Perf::TaskRun(const PerfAttr& perf_attr) { - perf_results_.type_of_running = PerfResults::TypeOfRunning::kTaskRun; - - task_->Validation(); - task_->PreProcessing(); - CommonRun(perf_attr, [&]() { task_->Run(); }, perf_results_); - task_->PostProcessing(); - - task_->Validation(); - task_->PreProcessing(); - task_->Run(); - task_->PostProcessing(); -} - -void ppc::core::Perf::CommonRun(const PerfAttr& perf_attr, const std::function& pipeline, - ppc::core::PerfResults& perf_results) { - auto begin = perf_attr.current_timer(); - for (uint64_t i = 0; i < perf_attr.num_running; i++) { - pipeline(); - } - auto end = perf_attr.current_timer(); - perf_results.time_sec = end - begin; -} - -void ppc::core::Perf::PrintPerfStatistic(std::string test_id) const { - std::string type_test_name; - if (perf_results_.type_of_running == PerfResults::TypeOfRunning::kTaskRun) { - type_test_name = "task_run"; - } else if (perf_results_.type_of_running == PerfResults::TypeOfRunning::kPipeline) { - type_test_name = "pipeline"; - } else { - std::stringstream err_msg; - err_msg << '\n' << "The type of performance check for the task was not selected.\n"; - throw std::runtime_error(err_msg.str().c_str()); - } - - auto time_secs = perf_results_.time_sec; - std::stringstream perf_res_str; - if (time_secs < PerfResults::kMaxTime) { - perf_res_str << std::fixed << std::setprecision(10) << time_secs; - std::cout << test_id << ":" << type_test_name << ":" << perf_res_str.str() << '\n'; - } else { - std::stringstream err_msg; - err_msg << '\n' << "Task execute time need to be: "; - err_msg << "time < " << PerfResults::kMaxTime << " secs." << '\n'; - err_msg << "Original time in secs: " << time_secs << '\n'; - perf_res_str << std::fixed << std::setprecision(10) << -1.0; - std::cout << test_id << ":" << type_test_name << ":" << perf_res_str.str() << '\n'; - throw std::runtime_error(err_msg.str().c_str()); - } -} - -ppc::core::PerfResults ppc::core::Perf::GetPerfResults() { return perf_results_; } diff --git a/modules/core/task/include/task.hpp b/modules/core/task/include/task.hpp index 76754018a..a13391e64 100644 --- a/modules/core/task/include/task.hpp +++ b/modules/core/task/include/task.hpp @@ -1,47 +1,120 @@ #pragma once +#include "core/task/include/task.hpp" + +#include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include +#include + +using namespace std::chrono; namespace ppc::core { // Memory of inputs and outputs need to be initialized before create object of // Task class +template class Task { public: enum StateOfTesting : uint8_t { kFunc, kPerf }; - explicit Task(StateOfTesting state_of_testing = StateOfTesting::kFunc); + explicit Task(StateOfTesting state_of_testing = StateOfTesting::kFunc) { + auto custom_terminate = []() { + std::cerr << "ORDER OF FUNCTIONS IS NOT RIGHT! \n" + "Expected - \"Validation\", \"PreProcessing\", \"Run\", \"PostProcessing\" \n"; + std::exit(404); + }; + std::set_terminate(custom_terminate); + functions_order_.clear(); + } // validation of data and validation of task attributes before running - virtual bool Validation() final; + virtual bool Validation() final { + InternalOrderTest(__builtin_FUNCTION()); + return ValidationImpl(); + } // pre-processing of input data - virtual bool PreProcessing() final; + virtual bool PreProcessing() final { + InternalOrderTest(__builtin_FUNCTION()); + if (state_of_testing_ == StateOfTesting::kFunc) { + InternalTimeTest(__builtin_FUNCTION()); + } + return PreProcessingImpl(); + } // realization of the current task - virtual bool Run() final; + virtual bool Run() final { + InternalOrderTest(__builtin_FUNCTION()); + return RunImpl(); + } // post-processing of output data - virtual bool PostProcessing() final; + virtual bool PostProcessing() final { + InternalOrderTest(__builtin_FUNCTION()); + if (state_of_testing_ == StateOfTesting::kFunc) { + InternalTimeTest(__builtin_FUNCTION()); + } + return PostProcessingImpl(); + } // get state of testing StateOfTesting &GetStateOfTesting() { return state_of_testing_; } - template - static T Get(const Class &obj, T Class::*member) { - return obj.*member; + InType& GetInput() { + return input_; + } + + OutType& GetOutput() { + return output_; } - virtual ~Task(); + virtual ~Task() { + if (!functions_order_.empty() || !was_worked_) { + std::terminate(); + } else { + functions_order_.clear(); + } + } protected: - virtual void InternalOrderTest(const std::string &str) final; + virtual void InternalOrderTest(const std::string &str) final { + functions_order_.push_back(str); + if (str == "PostProcessing" && IsFullPipelineStage()) { + functions_order_.clear(); + } else { + was_worked_ = true; + } + } - virtual void InternalTimeTest(const std::string &str) final; + virtual void InternalTimeTest(const std::string &str) final { + if (str == "PreProcessing") { + tmp_time_point_ = std::chrono::high_resolution_clock::now(); + } + + if (str == "PostProcessing") { + auto duration = duration_cast(high_resolution_clock::now() - tmp_time_point_).count(); + auto diff = static_cast(duration) * 1e-9; + + std::stringstream err_msg; + if (diff < kMaxTestTime) { + err_msg << "Test time:" << std::fixed << std::setprecision(10) << diff << '\n'; + } else { + err_msg << "\nTask execute time need to be: "; + err_msg << "time < " << kMaxTestTime << " secs.\n"; + err_msg << "Original time in secs: " << diff << '\n'; + throw std::runtime_error(err_msg.str().c_str()); + } + } + } // implementation of "Validation" function virtual bool ValidationImpl() = 0; @@ -56,6 +129,8 @@ class Task { virtual bool PostProcessingImpl() = 0; private: + InType input_; + OutType output_; StateOfTesting state_of_testing_; std::vector functions_order_; std::vector right_functions_order_ = {"Validation", "PreProcessing", "Run", "PostProcessing"}; @@ -63,20 +138,24 @@ class Task { std::chrono::high_resolution_clock::time_point tmp_time_point_; bool was_worked_ = false; - bool IsFullPipelineStage(); + bool IsFullPipelineStage() { + auto it = std::adjacent_find(functions_order_.begin() + 2, + functions_order_.begin() + static_cast(functions_order_.size() - 2), + std::not_equal_to<>()); + + return (functions_order_.size() >= 4 && functions_order_[0] == "Validation" && + functions_order_[1] == "PreProcessing" && functions_order_[2] == "Run" && + it == (functions_order_.begin() + static_cast(functions_order_.size() - 2)) && + functions_order_[functions_order_.size() - 1] == "PostProcessing"); + } }; -using TaskPtr = std::shared_ptr; +template +using TaskPtr = std::shared_ptr>; -template -std::shared_ptr task_getter(OutputType in) { +template +std::shared_ptr task_getter(InType in) { return std::make_shared(in); } -template -OutputType data_getter(TaskPtr current_task) { - auto inheritance_task = std::dynamic_pointer_cast(current_task); - return ppc::core::Task::Get(*inheritance_task, &TaskType::output_); -} - } // namespace ppc::core diff --git a/modules/core/task/src/task.cpp b/modules/core/task/src/task.cpp deleted file mode 100644 index 12c12929d..000000000 --- a/modules/core/task/src/task.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include "core/task/include/task.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std::chrono; - -ppc::core::Task::Task(StateOfTesting state_of_testing) : state_of_testing_(state_of_testing) { - auto custom_terminate = []() { - std::cerr << "ORDER OF FUNCTIONS IS NOT RIGHT! \n" - "Expected - \"Validation\", \"PreProcessing\", \"Run\", \"PostProcessing\" \n"; - std::exit(404); - }; - std::set_terminate(custom_terminate); - functions_order_.clear(); -} - -bool ppc::core::Task::Validation() { - InternalOrderTest(__builtin_FUNCTION()); - return ValidationImpl(); -} - -bool ppc::core::Task::PreProcessing() { - InternalOrderTest(__builtin_FUNCTION()); - if (state_of_testing_ == StateOfTesting::kFunc) { - InternalTimeTest(__builtin_FUNCTION()); - } - return PreProcessingImpl(); -} - -bool ppc::core::Task::Run() { - InternalOrderTest(__builtin_FUNCTION()); - return RunImpl(); -} - -bool ppc::core::Task::PostProcessing() { - InternalOrderTest(__builtin_FUNCTION()); - if (state_of_testing_ == StateOfTesting::kFunc) { - InternalTimeTest(__builtin_FUNCTION()); - } - return PostProcessingImpl(); -} - -void ppc::core::Task::InternalOrderTest(const std::string &str) { - functions_order_.push_back(str); - if (str == "PostProcessing" && IsFullPipelineStage()) { - functions_order_.clear(); - } else { - was_worked_ = true; - } -} - -void ppc::core::Task::InternalTimeTest(const std::string &str) { - if (str == "PreProcessing") { - tmp_time_point_ = std::chrono::high_resolution_clock::now(); - } - - if (str == "PostProcessing") { - auto duration = duration_cast(high_resolution_clock::now() - tmp_time_point_).count(); - auto diff = static_cast(duration) * 1e-9; - - std::stringstream err_msg; - if (diff < kMaxTestTime) { - err_msg << "Test time:" << std::fixed << std::setprecision(10) << diff << '\n'; - } else { - err_msg << "\nTask execute time need to be: "; - err_msg << "time < " << kMaxTestTime << " secs.\n"; - err_msg << "Original time in secs: " << diff << '\n'; - throw std::runtime_error(err_msg.str().c_str()); - } - } -} - -bool ppc::core::Task::IsFullPipelineStage() { - auto it = std::adjacent_find(functions_order_.begin() + 2, - functions_order_.begin() + static_cast(functions_order_.size() - 2), - std::not_equal_to<>()); - - return (functions_order_.size() >= 4 && functions_order_[0] == "Validation" && - functions_order_[1] == "PreProcessing" && functions_order_[2] == "Run" && - it == (functions_order_.begin() + static_cast(functions_order_.size() - 2)) && - functions_order_[functions_order_.size() - 1] == "PostProcessing"); -} - -ppc::core::Task::~Task() { - if (!functions_order_.empty() || !was_worked_) { - std::terminate(); - } else { - functions_order_.clear(); - } -} diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/test_util.hpp new file mode 100644 index 000000000..728ff0f40 --- /dev/null +++ b/modules/core/util/include/test_util.hpp @@ -0,0 +1,61 @@ +#pragma once + +#include "core/perf/include/perf.hpp" +#include +#include + +namespace ppc::util { + +template +using TestParam = std::tuple(InType)>, + std::string>; + +template +class BaseRunPerfTests : public ::testing::TestWithParam> { + protected: + virtual void SetPerfAttributes(ppc::core::PerfAttr& perf_attrs) = 0; + virtual bool CheckTestOutputData(OutType& output_data) = 0; + virtual InType GetTestInputData() = 0; + + void ExecuteTest(ppc::core::PerfResults::TypeOfRunning mode, + std::function(InType)> task_getter, + std::string test_name) { + task = task_getter(GetTestInputData()); + ppc::core::Perf perf(task); + ppc::core::PerfAttr perf_attr; + SetPerfAttributes(perf_attr); + + if (mode == ppc::core::PerfResults::TypeOfRunning::kPipeline) { + perf.PipelineRun(perf_attr); + } else if (mode == ppc::core::PerfResults::TypeOfRunning::kTaskRun) { + perf.TaskRun(perf_attr); + } else { + std::stringstream err_msg; + err_msg << '\n' << "The type of performance check for the task was not selected.\n"; + throw std::runtime_error(err_msg.str().c_str()); + } + + int rank = -1; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + if (rank == 0) { + perf.PrintPerfStatistic(test_name); + } + OutType output_data = task->GetOutput(); + ASSERT_TRUE(CheckTestOutputData(output_data)); + } + + private: + ppc::core::TaskPtr task; +}; + +#define ADD_MODES(TaskType, InputTypeParam) \ + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, \ + ppc::core::task_getter, \ + ppc::util::GetNamespace()), \ + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, \ + ppc::core::task_getter, \ + ppc::util::GetNamespace()) + + +} // namespace ppc::util diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index 39e103b3a..78af88acf 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -17,7 +17,7 @@ std::string GetAbsolutePath(const std::string &relative_path); int GetPPCNumThreads(); template -consteval std::string_view get_namespace() { +consteval std::string_view GetNamespace() { #if defined(__clang__) || defined(__GNUC__) constexpr std::string_view func = __PRETTY_FUNCTION__; // example: "consteval std::string_view get_namespace() [with T = my_namespace::MyClass]" diff --git a/tasks-1/example/all/include/ops_all.hpp b/tasks-1/example/all/include/ops_all.hpp index 9dd5f5b7b..e28911067 100644 --- a/tasks-1/example/all/include/ops_all.hpp +++ b/tasks-1/example/all/include/ops_all.hpp @@ -10,14 +10,16 @@ namespace nesterov_a_test_task_all { void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_vec); void MatMulTBB(const std::vector &in_vec, int rc_size, std::vector &out_vec); -class TestTaskALL : public ppc::core::Task { +using InType = std::vector; +using OutType = std::vector; + +class TestTaskALL : public ppc::core::Task { public: - explicit TestTaskALL(const std::vector &in) : input_(in) {} + explicit TestTaskALL(const InType &in); bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; bool PostProcessingImpl() override; - std::vector input_, output_; private: int rc_size_{}; }; diff --git a/tasks-1/example/all/src/ops_all.cpp b/tasks-1/example/all/src/ops_all.cpp index 6c95809a8..5947839d8 100644 --- a/tasks-1/example/all/src/ops_all.cpp +++ b/tasks-1/example/all/src/ops_all.cpp @@ -11,7 +11,7 @@ #include "core/util/include/util.hpp" #include "oneapi/tbb/parallel_for.h" -void nesterov_a_test_task_all::MatMul(const std::vector &in_vec, int rc_size, std::vector &out_vec) { +void nesterov_a_test_task_all::MatMul(const InType &in_vec, int rc_size, OutType &out_vec) { for (int i = 0; i < rc_size; ++i) { for (int j = 0; j < rc_size; ++j) { out_vec[(i * rc_size) + j] = 0; @@ -22,20 +22,24 @@ void nesterov_a_test_task_all::MatMul(const std::vector &in_vec, int rc_siz } } -void nesterov_a_test_task_all::MatMulTBB(const std::vector &in_vec, int rc_size, std::vector &out_vec) { +void nesterov_a_test_task_all::MatMulTBB(const InType &in_vec, int rc_size, OutType &out_vec) { tbb::parallel_for(0, ppc::util::GetPPCNumThreads(), [&](int i) { MatMul(in_vec, rc_size - i, out_vec); }); MatMul(in_vec, rc_size, out_vec); } +nesterov_a_test_task_all::TestTaskALL::TestTaskALL(const InType &in) { + GetInput() = in; +} + bool nesterov_a_test_task_all::TestTaskALL::ValidationImpl() { - auto sqrt_size = static_cast(std::sqrt(input_.size())); - return sqrt_size * sqrt_size == static_cast(input_.size()); + auto sqrt_size = static_cast(std::sqrt(GetInput().size())); + return sqrt_size * sqrt_size == static_cast(GetInput().size()); } bool nesterov_a_test_task_all::TestTaskALL::PreProcessingImpl() { // Init value for input and output - rc_size_ = static_cast(std::sqrt(input_.size())); - output_ = std::vector(input_.size(), 0); + rc_size_ = static_cast(std::sqrt(GetInput().size())); + GetOutput() = OutType(GetInput().size(), 0); return true; } @@ -46,16 +50,16 @@ bool nesterov_a_test_task_all::TestTaskALL::RunImpl() { #pragma omp parallel default(none) { #pragma omp critical - MatMul(input_, rc_size_, output_); + MatMul(GetInput(), rc_size_, GetOutput()); } } else { - MatMulTBB(input_, rc_size_, output_); + MatMulTBB(GetInput(), rc_size_, GetOutput()); } const int num_threads = ppc::util::GetPPCNumThreads(); std::vector threads(num_threads); for (int i = 0; i < num_threads; i++) { - threads[i] = std::thread(MatMul, std::cref(input_), rc_size_, std::ref(output_)); + threads[i] = std::thread(MatMul, std::cref(GetInput()), rc_size_, std::ref(GetOutput())); threads[i].join(); } diff --git a/tasks-1/example/mpi/include/ops_mpi.hpp b/tasks-1/example/mpi/include/ops_mpi.hpp index 1e158a5bd..f80e39548 100644 --- a/tasks-1/example/mpi/include/ops_mpi.hpp +++ b/tasks-1/example/mpi/include/ops_mpi.hpp @@ -10,16 +10,16 @@ namespace nesterov_a_test_task_mpi { void MultiplyRowMajor(const std::vector &in, std::vector &out, int rc_size); void MultiplyColumnMajor(const std::vector &in, std::vector &out, int rc_size); -class TestTaskMPI : public ppc::core::Task { +using InType = std::vector; +using OutType = std::vector; + +class TestTaskMPI : public ppc::core::Task { public: - explicit TestTaskMPI(const std::vector &in) : input_(in) {} + explicit TestTaskMPI(const InType &in); bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; bool PostProcessingImpl() override; - std::vector Get(); - - std::vector input_, output_; private: int rc_size_{}; diff --git a/tasks-1/example/mpi/src/ops_mpi.cpp b/tasks-1/example/mpi/src/ops_mpi.cpp index 01f7d39b2..b60b9287e 100644 --- a/tasks-1/example/mpi/src/ops_mpi.cpp +++ b/tasks-1/example/mpi/src/ops_mpi.cpp @@ -6,15 +6,39 @@ #include #include +void nesterov_a_test_task_mpi::MultiplyRowMajor(const InType &in, OutType &out, int rc_size) { + for (int i = 0; i < rc_size; ++i) { + for (int j = 0; j < rc_size; ++j) { + for (int k = 0; k < rc_size; ++k) { + out[(i * rc_size) + j] += in[(i * rc_size) + k] * in[(k * rc_size) + j]; + } + } + } +} + +void nesterov_a_test_task_mpi::MultiplyColumnMajor(const InType &in, OutType &out, int rc_size) { + for (int j = 0; j < rc_size; ++j) { + for (int k = 0; k < rc_size; ++k) { + for (int i = 0; i < rc_size; ++i) { + out[(i * rc_size) + j] += in[(i * rc_size) + k] * in[(k * rc_size) + j]; + } + } + } +} + +nesterov_a_test_task_mpi::TestTaskMPI::TestTaskMPI(const InType &in) { + GetInput() = in; +} + bool nesterov_a_test_task_mpi::TestTaskMPI::ValidationImpl() { - auto sqrt_size = static_cast(std::sqrt(input_.size())); - return sqrt_size * sqrt_size == static_cast(input_.size()); + auto sqrt_size = static_cast(std::sqrt(GetInput().size())); + return sqrt_size * sqrt_size == static_cast(GetInput().size()); } bool nesterov_a_test_task_mpi::TestTaskMPI::PreProcessingImpl() { // Init value for input and output - rc_size_ = static_cast(std::sqrt(input_.size())); - output_ = std::vector(input_.size(), 0); + rc_size_ = static_cast(std::sqrt(GetInput().size())); + GetOutput() = OutType(GetInput().size(), 0); return true; } @@ -23,38 +47,16 @@ bool nesterov_a_test_task_mpi::TestTaskMPI::RunImpl() { return true; } +bool nesterov_a_test_task_mpi::TestTaskMPI::PostProcessingImpl() { return true; } + void nesterov_a_test_task_mpi::TestTaskMPI::MultiplyMatrixBasedOnRank() { int rank = -1; MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { - MultiplyRowMajor(input_, output_, rc_size_); + MultiplyRowMajor(GetInput(), GetOutput(), rc_size_); } else { - MultiplyColumnMajor(input_, output_, rc_size_); + MultiplyColumnMajor(GetInput(), GetOutput(), rc_size_); } MPI_Barrier(MPI_COMM_WORLD); } - -void nesterov_a_test_task_mpi::MultiplyRowMajor(const std::vector &in, std::vector &out, int rc_size) { - for (int i = 0; i < rc_size; ++i) { - for (int j = 0; j < rc_size; ++j) { - for (int k = 0; k < rc_size; ++k) { - out[(i * rc_size) + j] += in[(i * rc_size) + k] * in[(k * rc_size) + j]; - } - } - } -} - -void nesterov_a_test_task_mpi::MultiplyColumnMajor(const std::vector &in, std::vector &out, int rc_size) { - for (int j = 0; j < rc_size; ++j) { - for (int k = 0; k < rc_size; ++k) { - for (int i = 0; i < rc_size; ++i) { - out[(i * rc_size) + j] += in[(i * rc_size) + k] * in[(k * rc_size) + j]; - } - } - } -} - -bool nesterov_a_test_task_mpi::TestTaskMPI::PostProcessingImpl() { return true; } - -std::vector nesterov_a_test_task_mpi::TestTaskMPI::Get() { return output_; } diff --git a/tasks-1/example/omp/include/ops_omp.hpp b/tasks-1/example/omp/include/ops_omp.hpp index ca8cfd90a..9b1a67c44 100644 --- a/tasks-1/example/omp/include/ops_omp.hpp +++ b/tasks-1/example/omp/include/ops_omp.hpp @@ -7,15 +7,16 @@ namespace nesterov_a_test_task_omp { -class TestTaskOpenMP : public ppc::core::Task { +using InType = std::vector; +using OutType = std::vector; + +class TestTaskOpenMP : public ppc::core::Task { public: - explicit TestTaskOpenMP(const std::vector& in) : input_(in) {} + explicit TestTaskOpenMP(const InType& in); bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; bool PostProcessingImpl() override; - std::vector Get(); - std::vector input_, output_; private: int rc_size_{}; diff --git a/tasks-1/example/omp/src/ops_omp.cpp b/tasks-1/example/omp/src/ops_omp.cpp index e7aa92fcb..54b8fd0f8 100644 --- a/tasks-1/example/omp/src/ops_omp.cpp +++ b/tasks-1/example/omp/src/ops_omp.cpp @@ -4,14 +4,18 @@ #include #include +nesterov_a_test_task_omp::TestTaskOpenMP::TestTaskOpenMP(const InType& in) { + GetInput() = in; +} + bool nesterov_a_test_task_omp::TestTaskOpenMP::ValidationImpl() { - auto sqrt_size = static_cast(std::sqrt(input_.size())); - return sqrt_size * sqrt_size == static_cast(input_.size()); + auto sqrt_size = static_cast(std::sqrt(GetInput().size())); + return sqrt_size * sqrt_size == static_cast(GetInput().size()); } bool nesterov_a_test_task_omp::TestTaskOpenMP::PreProcessingImpl() { - rc_size_ = static_cast(std::sqrt(input_.size())); - output_ = std::vector(input_.size(), 0); + rc_size_ = static_cast(std::sqrt(GetInput().size())); + GetOutput() = OutType(GetInput().size(), 0); return true; } @@ -23,9 +27,9 @@ bool nesterov_a_test_task_omp::TestTaskOpenMP::RunImpl() { // Multiply matrices for (int i = 0; i < rc_size_; ++i) { for (int j = 0; j < rc_size_; ++j) { - output_[(i * rc_size_) + j] = 0; + GetOutput()[(i * rc_size_) + j] = 0; for (int k = 0; k < rc_size_; ++k) { - output_[(i * rc_size_) + j] += input_[(i * rc_size_) + k] * input_[(k * rc_size_) + j]; + GetOutput()[(i * rc_size_) + j] += GetInput()[(i * rc_size_) + k] * GetInput()[(k * rc_size_) + j]; } } } @@ -35,5 +39,3 @@ bool nesterov_a_test_task_omp::TestTaskOpenMP::RunImpl() { } bool nesterov_a_test_task_omp::TestTaskOpenMP::PostProcessingImpl() { return true; } - -std::vector nesterov_a_test_task_omp::TestTaskOpenMP::Get() { return output_; } diff --git a/tasks-1/example/seq/include/ops_seq.hpp b/tasks-1/example/seq/include/ops_seq.hpp index aedc0350c..df2303de3 100644 --- a/tasks-1/example/seq/include/ops_seq.hpp +++ b/tasks-1/example/seq/include/ops_seq.hpp @@ -7,15 +7,16 @@ namespace nesterov_a_test_task_seq { -class TestTaskSequential : public ppc::core::Task { +using InType = std::vector; +using OutType = std::vector; + +class TestTaskSequential : public ppc::core::Task { public: - explicit TestTaskSequential(const std::vector& in) : input_(in) {} + explicit TestTaskSequential(const InType& in); bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; bool PostProcessingImpl() override; - std::vector Get(); - std::vector input_, output_; private: int rc_size_{}; diff --git a/tasks-1/example/seq/src/ops_seq.cpp b/tasks-1/example/seq/src/ops_seq.cpp index d172feb5c..da361f8c2 100644 --- a/tasks-1/example/seq/src/ops_seq.cpp +++ b/tasks-1/example/seq/src/ops_seq.cpp @@ -4,14 +4,18 @@ #include #include +nesterov_a_test_task_seq::TestTaskSequential::TestTaskSequential(const InType& in) { + GetInput() = in; +} + bool nesterov_a_test_task_seq::TestTaskSequential::ValidationImpl() { - auto sqrt_size = static_cast(std::sqrt(input_.size())); - return sqrt_size * sqrt_size == static_cast(input_.size()); + auto sqrt_size = static_cast(std::sqrt(GetInput().size())); + return sqrt_size * sqrt_size == static_cast(GetInput().size()); } bool nesterov_a_test_task_seq::TestTaskSequential::PreProcessingImpl() { - rc_size_ = static_cast(std::sqrt(input_.size())); - output_ = std::vector(input_.size(), 0); + rc_size_ = static_cast(std::sqrt(GetInput().size())); + GetOutput() = OutType(GetInput().size(), 0); return true; } @@ -20,7 +24,7 @@ bool nesterov_a_test_task_seq::TestTaskSequential::RunImpl() { for (int i = 0; i < rc_size_; ++i) { for (int j = 0; j < rc_size_; ++j) { for (int k = 0; k < rc_size_; ++k) { - output_[(i * rc_size_) + j] += input_[(i * rc_size_) + k] * input_[(k * rc_size_) + j]; + GetOutput()[(i * rc_size_) + j] += GetInput()[(i * rc_size_) + k] * GetInput()[(k * rc_size_) + j]; } } } @@ -28,5 +32,3 @@ bool nesterov_a_test_task_seq::TestTaskSequential::RunImpl() { } bool nesterov_a_test_task_seq::TestTaskSequential::PostProcessingImpl() { return true; } - -std::vector nesterov_a_test_task_seq::TestTaskSequential::Get() { return output_; } diff --git a/tasks-1/example/stl/include/ops_stl.hpp b/tasks-1/example/stl/include/ops_stl.hpp index 72aafed8c..8932b18f2 100644 --- a/tasks-1/example/stl/include/ops_stl.hpp +++ b/tasks-1/example/stl/include/ops_stl.hpp @@ -7,15 +7,16 @@ namespace nesterov_a_test_task_stl { -class TestTaskSTL : public ppc::core::Task { +using InType = std::vector; +using OutType = std::vector; + +class TestTaskSTL : public ppc::core::Task { public: - explicit TestTaskSTL(const std::vector& in) : input_(in) {} + explicit TestTaskSTL(const InType& in); bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; bool PostProcessingImpl() override; - std::vector Get(); - std::vector input_, output_; private: int rc_size_{}; diff --git a/tasks-1/example/stl/src/ops_stl.cpp b/tasks-1/example/stl/src/ops_stl.cpp index fb3c2b464..a335bd999 100644 --- a/tasks-1/example/stl/src/ops_stl.cpp +++ b/tasks-1/example/stl/src/ops_stl.cpp @@ -21,14 +21,18 @@ void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_v } } // namespace +nesterov_a_test_task_stl::TestTaskSTL::TestTaskSTL(const InType& in) { + GetInput() = in; +} + bool nesterov_a_test_task_stl::TestTaskSTL::ValidationImpl() { - auto sqrt_size = static_cast(std::sqrt(input_.size())); - return sqrt_size * sqrt_size == static_cast(input_.size()); + auto sqrt_size = static_cast(std::sqrt(GetInput().size())); + return sqrt_size * sqrt_size == static_cast(GetInput().size()); } bool nesterov_a_test_task_stl::TestTaskSTL::PreProcessingImpl() { - rc_size_ = static_cast(std::sqrt(input_.size())); - output_ = std::vector(input_.size(), 0); + rc_size_ = static_cast(std::sqrt(GetInput().size())); + GetOutput() = OutType(GetInput().size(), 0); return true; } @@ -36,12 +40,10 @@ bool nesterov_a_test_task_stl::TestTaskSTL::RunImpl() { const int num_threads = ppc::util::GetPPCNumThreads(); std::vector threads(num_threads); for (int i = 0; i < num_threads; i++) { - threads[i] = std::thread(MatMul, std::cref(input_), rc_size_, std::ref(output_)); + threads[i] = std::thread(MatMul, std::cref(GetInput()), rc_size_, std::ref(GetOutput())); threads[i].join(); } return true; } bool nesterov_a_test_task_stl::TestTaskSTL::PostProcessingImpl() { return true; } - -std::vector nesterov_a_test_task_stl::TestTaskSTL::Get() { return output_; } diff --git a/tasks-1/example/tbb/include/ops_tbb.hpp b/tasks-1/example/tbb/include/ops_tbb.hpp index f89103655..ce6449f96 100644 --- a/tasks-1/example/tbb/include/ops_tbb.hpp +++ b/tasks-1/example/tbb/include/ops_tbb.hpp @@ -7,15 +7,16 @@ namespace nesterov_a_test_task_tbb { -class TestTaskTBB : public ppc::core::Task { +using InType = std::vector; +using OutType = std::vector; + +class TestTaskTBB : public ppc::core::Task { public: - explicit TestTaskTBB(const std::vector& in) : input_(in) {} + explicit TestTaskTBB(const InType& in); bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; bool PostProcessingImpl() override; - std::vector Get(); - std::vector input_, output_; private: int rc_size_{}; diff --git a/tasks-1/example/tbb/src/ops_tbb.cpp b/tasks-1/example/tbb/src/ops_tbb.cpp index 2f0b12b9b..055ac8a21 100644 --- a/tasks-1/example/tbb/src/ops_tbb.cpp +++ b/tasks-1/example/tbb/src/ops_tbb.cpp @@ -22,23 +22,25 @@ void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_v } } // namespace +nesterov_a_test_task_tbb::TestTaskTBB::TestTaskTBB(const InType& in) { + GetInput() = in; +} + bool nesterov_a_test_task_tbb::TestTaskTBB::ValidationImpl() { - auto sqrt_size = static_cast(std::sqrt(input_.size())); - return sqrt_size * sqrt_size == static_cast(input_.size()); + auto sqrt_size = static_cast(std::sqrt(GetInput().size())); + return sqrt_size * sqrt_size == static_cast(GetInput().size()); } bool nesterov_a_test_task_tbb::TestTaskTBB::PreProcessingImpl() { - rc_size_ = static_cast(std::sqrt(input_.size())); - output_ = std::vector(input_.size(), 0); + rc_size_ = static_cast(std::sqrt(GetInput().size())); + GetOutput() = OutType(GetInput().size(), 0); return true; } bool nesterov_a_test_task_tbb::TestTaskTBB::RunImpl() { - tbb::parallel_for(0, ppc::util::GetPPCNumThreads(), [&](int i) { MatMul(input_, rc_size_ - i, output_); }); - MatMul(input_, rc_size_, output_); + tbb::parallel_for(0, ppc::util::GetPPCNumThreads(), [&](int i) { MatMul(GetInput(), rc_size_ - i, GetOutput()); }); + MatMul(GetInput(), rc_size_, GetOutput()); return true; } bool nesterov_a_test_task_tbb::TestTaskTBB::PostProcessingImpl() { return true; } - -std::vector nesterov_a_test_task_tbb::TestTaskTBB::Get() { return output_; } diff --git a/tasks-1/example/tests/perf_tests/main.cpp b/tasks-1/example/tests/perf_tests/main.cpp index 046749959..4e312bba3 100644 --- a/tasks-1/example/tests/perf_tests/main.cpp +++ b/tasks-1/example/tests/perf_tests/main.cpp @@ -14,66 +14,14 @@ #include "core/perf/include/perf.hpp" #include "core/util/include/util.hpp" +#include "core/util/include/test_util.hpp" -template -using TestParam = std::tuple, - std::function, - std::string>; +using InType = std::vector; +using OutType = std::vector; -template -class BaseRunPerfTests : public ::testing::TestWithParam> { - protected: - virtual void setPerfAttributes(ppc::core::PerfAttr& perf_attrs) = 0; - virtual bool checkData(std::function data_getter) = 0; - virtual OutputTypeParameter getInputData() = 0; - ppc::core::TaskPtr task; - - void ExecuteTest(ppc::core::PerfResults::TypeOfRunning mode, - std::function task_getter, - std::function data_getter, - std::string test_name) { - task = task_getter(getInputData()); - ppc::core::Perf perf(task); - ppc::core::PerfAttr perf_attr; - setPerfAttributes(perf_attr); - - if (mode == ppc::core::PerfResults::TypeOfRunning::kPipeline) { - perf.PipelineRun(perf_attr); - } else if (mode == ppc::core::PerfResults::TypeOfRunning::kTaskRun) { - perf.TaskRun(perf_attr); - } else { - std::stringstream err_msg; - err_msg << '\n' << "The type of performance check for the task was not selected.\n"; - throw std::runtime_error(err_msg.str().c_str()); - } - - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - if (rank == 0) { - perf.PrintPerfStatistic(test_name); - } - - ASSERT_TRUE(checkData(data_getter)); - } -}; - -#define ADD_MODES(TaskType, OutputTypeParam) \ - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, \ - ppc::core::task_getter, \ - ppc::core::data_getter,\ - ppc::util::get_namespace()), \ - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, \ - ppc::core::task_getter, \ - ppc::core::data_getter,\ - ppc::util::get_namespace()) - - -using OutputType = std::vector; - -class ExampleRunPerfTest : public BaseRunPerfTests { +class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { static constexpr int kCount = 400; - OutputType input_data; + InType input_data; void SetUp() override { input_data.assign(kCount * kCount, 0); @@ -82,7 +30,7 @@ class ExampleRunPerfTest : public BaseRunPerfTests { } } - void setPerfAttributes(ppc::core::PerfAttr& perf_attrs) final { + void SetPerfAttributes(ppc::core::PerfAttr& perf_attrs) final { const auto t0 = std::chrono::high_resolution_clock::now(); perf_attrs.current_timer = [&] { auto now = std::chrono::high_resolution_clock::now(); @@ -91,27 +39,27 @@ class ExampleRunPerfTest : public BaseRunPerfTests { }; } - bool checkData(std::function data_getter) final { - return input_data == data_getter(task); + bool CheckTestOutputData(OutType& output_data) final { + return input_data == output_data; } - OutputType getInputData() final { + InType GetTestInputData() final { return input_data; } }; TEST_P(ExampleRunPerfTest, RunModes) { - ExecuteTest(std::get<0>(GetParam()), std::get<1>(GetParam()), std::get<2>(GetParam()), std::get<3>(GetParam())); + ExecuteTest(std::get<0>(GetParam()), std::get<1>(GetParam()), std::get<2>(GetParam())); } INSTANTIATE_TEST_SUITE_P_NOLINT( RunModeTests, ExampleRunPerfTest, ::testing::Values( - ADD_MODES(nesterov_a_test_task_all::TestTaskALL, OutputType), - ADD_MODES(nesterov_a_test_task_mpi::TestTaskMPI, OutputType), - ADD_MODES(nesterov_a_test_task_omp::TestTaskOpenMP, OutputType), - ADD_MODES(nesterov_a_test_task_seq::TestTaskSequential, OutputType), - ADD_MODES(nesterov_a_test_task_stl::TestTaskSTL, OutputType), - ADD_MODES(nesterov_a_test_task_tbb::TestTaskTBB, OutputType)) + ADD_MODES(nesterov_a_test_task_all::TestTaskALL, InType), + ADD_MODES(nesterov_a_test_task_mpi::TestTaskMPI, InType), + ADD_MODES(nesterov_a_test_task_omp::TestTaskOpenMP, InType), + ADD_MODES(nesterov_a_test_task_seq::TestTaskSequential, InType), + ADD_MODES(nesterov_a_test_task_stl::TestTaskSTL, InType), + ADD_MODES(nesterov_a_test_task_tbb::TestTaskTBB, InType)) ); From ec82c6aee65299239811c593ca1ae56f6f18399d Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Mon, 19 May 2025 21:30:38 +0200 Subject: [PATCH 010/141] update func tests --- modules/core/perf/include/perf.hpp | 4 +- modules/core/task/include/task.hpp | 12 ++-- modules/core/util/include/test_util.hpp | 22 +++--- tasks-1/example/tests/func_tests/main.cpp | 87 +++++++++++------------ 4 files changed, 56 insertions(+), 69 deletions(-) diff --git a/modules/core/perf/include/perf.hpp b/modules/core/perf/include/perf.hpp index 8e08d5d96..6830ae4de 100644 --- a/modules/core/perf/include/perf.hpp +++ b/modules/core/perf/include/perf.hpp @@ -21,7 +21,7 @@ struct PerfResults { constexpr static double kMaxTime = 10.0; }; -template +template class Perf { public: // Init performance analysis with initialized task and initialized data @@ -86,7 +86,7 @@ class Perf { } } // Get performance result structure of the current task - PerfResults GetPerfResults() { return perf_results_; } + PerfResults GetPerfResults() { return perf_results_; } private: PerfResults perf_results_; diff --git a/modules/core/task/include/task.hpp b/modules/core/task/include/task.hpp index a13391e64..bd4efc6a0 100644 --- a/modules/core/task/include/task.hpp +++ b/modules/core/task/include/task.hpp @@ -1,7 +1,5 @@ #pragma once -#include "core/task/include/task.hpp" - #include #include #include @@ -15,6 +13,8 @@ #include #include +#include "core/task/include/task.hpp" + using namespace std::chrono; namespace ppc::core { @@ -69,13 +69,9 @@ class Task { // get state of testing StateOfTesting &GetStateOfTesting() { return state_of_testing_; } - InType& GetInput() { - return input_; - } + InType &GetInput() { return input_; } - OutType& GetOutput() { - return output_; - } + OutType &GetOutput() { return output_; } virtual ~Task() { if (!functions_order_.empty() || !was_worked_) { diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/test_util.hpp index 728ff0f40..60a39592b 100644 --- a/modules/core/util/include/test_util.hpp +++ b/modules/core/util/include/test_util.hpp @@ -1,15 +1,15 @@ #pragma once -#include "core/perf/include/perf.hpp" #include #include +#include "core/perf/include/perf.hpp" + namespace ppc::util { template using TestParam = std::tuple(InType)>, - std::string>; + std::function(InType)>, std::string>; template class BaseRunPerfTests : public ::testing::TestWithParam> { @@ -19,8 +19,7 @@ class BaseRunPerfTests : public ::testing::TestWithParam(InType)> task_getter, - std::string test_name) { + std::function(InType)> task_getter, std::string test_name) { task = task_getter(GetTestInputData()); ppc::core::Perf perf(task); ppc::core::PerfAttr perf_attr; @@ -49,13 +48,10 @@ class BaseRunPerfTests : public ::testing::TestWithParam task; }; -#define ADD_MODES(TaskType, InputTypeParam) \ - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, \ - ppc::core::task_getter, \ - ppc::util::GetNamespace()), \ - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, \ - ppc::core::task_getter, \ - ppc::util::GetNamespace()) - +#define ADD_MODES(TaskType, InputTypeParam) \ + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, ppc::core::task_getter, \ + ppc::util::GetNamespace()), \ + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, \ + ppc::core::task_getter, ppc::util::GetNamespace()) } // namespace ppc::util diff --git a/tasks-1/example/tests/func_tests/main.cpp b/tasks-1/example/tests/func_tests/main.cpp index 5f7aee917..933855f8d 100644 --- a/tasks-1/example/tests/func_tests/main.cpp +++ b/tasks-1/example/tests/func_tests/main.cpp @@ -6,69 +6,64 @@ #include #include "example/all/include/ops_all.hpp" +#include "example/mpi/include/ops_mpi.hpp" +#include "example/omp/include/ops_omp.hpp" +#include "example/seq/include/ops_seq.hpp" +#include "example/stl/include/ops_stl.hpp" +#include "example/tbb/include/ops_tbb.hpp" + #include "core/util/include/util.hpp" -class NesterovATestTaskAll : public ::testing::TestWithParam { +using InType = std::vector; +using OutType = std::vector; + +using TestParam = std::tuple(InType)>>; + +class NesterovARunFuncTests: public ::testing::TestWithParam { protected: void SetUp() override { - width = height = channels = -1; + // Read image std::string abs_path = ppc::util::GetAbsolutePath("all/example/data/pic_all.jpg"); data = stbi_load(abs_path.c_str(), &width, &height, &channels, 0); ASSERT_TRUE(data != nullptr) << "Failed to load image: " << stbi_failure_reason(); img = std::vector(data, data + (width * height * channels)); stbi_image_free(data); - ASSERT_EQ(width, height); + + const int k_count = (width + height) / std::get<0>(GetParam()); + std::vector in(k_count * k_count, 0); + for (int i = 0; i < k_count; i++) { + in[(i * k_count) + i] = 1; + } + task = std::get<1>(GetParam())(in); } + void ExecuteTest() { + ASSERT_TRUE(task->Validation()); + task->PreProcessing(); + task->Run(); + task->PostProcessing(); + EXPECT_EQ(task->GetInput(), task->GetOutput()); + } + + ppc::core::TaskPtr task; int width = -1, height = -1, channels = -1; unsigned char* data = nullptr; std::vector img; }; -TEST_P(NesterovATestTaskAll, MatmulFromPic) { - int divider = GetParam(); - const int k_count = (width + height) / divider; - - std::vector in(k_count * k_count, 0); - for (int i = 0; i < k_count; i++) { - in[(i * k_count) + i] = 1; - } - - nesterov_a_test_task_all::TestTaskALL test_task_all(in); - ASSERT_TRUE(test_task_all.Validation()); - test_task_all.PreProcessing(); - test_task_all.Run(); - test_task_all.PostProcessing(); - EXPECT_EQ(in, test_task_all.Get()); +TEST_P(NesterovARunFuncTests, MatmulFromPic) { + ExecuteTest(); } -TEST_P(NesterovATestTaskAll, MatMulUtilFromPic) { - int divider = GetParam(); - const int k_count = (width + height) / divider; - - std::vector in(k_count * k_count, 0); - for (int i = 0; i < k_count; i++) { - in[(i * k_count) + i] = 1; - } - std::vector out(k_count * k_count, 0); - nesterov_a_test_task_all::MatMul(in, static_cast(k_count), out); - - EXPECT_EQ(in, out); -} - -TEST_P(NesterovATestTaskAll, MatMulTBBUtilFromPic) { - int divider = GetParam(); - const int k_count = (width + height) / divider; - - std::vector in(k_count * k_count, 0); - for (int i = 0; i < k_count; i++) { - in[(i * k_count) + i] = 1; - } - std::vector out(k_count * k_count, 0); - nesterov_a_test_task_all::MatMulTBB(in, static_cast(k_count), out); - - EXPECT_EQ(in, out); -} +#define ADD_TASK(TASK) \ + std::make_tuple(5, ppc::core::task_getter), \ + std::make_tuple(10, ppc::core::task_getter) -INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovATestTaskAll, ::testing::Values(5, 10)); +INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTests, + ::testing::Values(ADD_TASK(nesterov_a_test_task_all::TestTaskALL), + ADD_TASK(nesterov_a_test_task_mpi::TestTaskMPI), + ADD_TASK(nesterov_a_test_task_omp::TestTaskOpenMP), + ADD_TASK(nesterov_a_test_task_seq::TestTaskSequential), + ADD_TASK(nesterov_a_test_task_stl::TestTaskSTL), + ADD_TASK(nesterov_a_test_task_tbb::TestTaskTBB))); From b6c406f1c34ce2ac7aa921297bdaec9acab7d9a9 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Mon, 19 May 2025 22:03:53 +0200 Subject: [PATCH 011/141] update omp task --- tasks-1/example/omp/include/ops_omp.hpp | 4 ++-- tasks-1/example/omp/src/ops_omp.cpp | 10 +++++----- tasks-1/example/tests/func_tests/main.cpp | 2 +- tasks-1/example/tests/perf_tests/main.cpp | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tasks-1/example/omp/include/ops_omp.hpp b/tasks-1/example/omp/include/ops_omp.hpp index 9b1a67c44..e043e39c0 100644 --- a/tasks-1/example/omp/include/ops_omp.hpp +++ b/tasks-1/example/omp/include/ops_omp.hpp @@ -10,9 +10,9 @@ namespace nesterov_a_test_task_omp { using InType = std::vector; using OutType = std::vector; -class TestTaskOpenMP : public ppc::core::Task { +class TestTaskOMP : public ppc::core::Task { public: - explicit TestTaskOpenMP(const InType& in); + explicit TestTaskOMP(const InType& in); bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; diff --git a/tasks-1/example/omp/src/ops_omp.cpp b/tasks-1/example/omp/src/ops_omp.cpp index 54b8fd0f8..ce7059549 100644 --- a/tasks-1/example/omp/src/ops_omp.cpp +++ b/tasks-1/example/omp/src/ops_omp.cpp @@ -4,22 +4,22 @@ #include #include -nesterov_a_test_task_omp::TestTaskOpenMP::TestTaskOpenMP(const InType& in) { +nesterov_a_test_task_omp::TestTaskOMP::TestTaskOMP(const InType& in) { GetInput() = in; } -bool nesterov_a_test_task_omp::TestTaskOpenMP::ValidationImpl() { +bool nesterov_a_test_task_omp::TestTaskOMP::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task_omp::TestTaskOpenMP::PreProcessingImpl() { +bool nesterov_a_test_task_omp::TestTaskOMP::PreProcessingImpl() { rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task_omp::TestTaskOpenMP::RunImpl() { +bool nesterov_a_test_task_omp::TestTaskOMP::RunImpl() { #pragma omp parallel default(none) { #pragma omp critical @@ -38,4 +38,4 @@ bool nesterov_a_test_task_omp::TestTaskOpenMP::RunImpl() { return true; } -bool nesterov_a_test_task_omp::TestTaskOpenMP::PostProcessingImpl() { return true; } +bool nesterov_a_test_task_omp::TestTaskOMP::PostProcessingImpl() { return true; } diff --git a/tasks-1/example/tests/func_tests/main.cpp b/tasks-1/example/tests/func_tests/main.cpp index 933855f8d..731cd6091 100644 --- a/tasks-1/example/tests/func_tests/main.cpp +++ b/tasks-1/example/tests/func_tests/main.cpp @@ -63,7 +63,7 @@ TEST_P(NesterovARunFuncTests, MatmulFromPic) { INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTests, ::testing::Values(ADD_TASK(nesterov_a_test_task_all::TestTaskALL), ADD_TASK(nesterov_a_test_task_mpi::TestTaskMPI), - ADD_TASK(nesterov_a_test_task_omp::TestTaskOpenMP), + ADD_TASK(nesterov_a_test_task_omp::TestTaskOMP), ADD_TASK(nesterov_a_test_task_seq::TestTaskSequential), ADD_TASK(nesterov_a_test_task_stl::TestTaskSTL), ADD_TASK(nesterov_a_test_task_tbb::TestTaskTBB))); diff --git a/tasks-1/example/tests/perf_tests/main.cpp b/tasks-1/example/tests/perf_tests/main.cpp index 4e312bba3..98aa114f1 100644 --- a/tasks-1/example/tests/perf_tests/main.cpp +++ b/tasks-1/example/tests/perf_tests/main.cpp @@ -58,7 +58,7 @@ INSTANTIATE_TEST_SUITE_P_NOLINT( ::testing::Values( ADD_MODES(nesterov_a_test_task_all::TestTaskALL, InType), ADD_MODES(nesterov_a_test_task_mpi::TestTaskMPI, InType), - ADD_MODES(nesterov_a_test_task_omp::TestTaskOpenMP, InType), + ADD_MODES(nesterov_a_test_task_omp::TestTaskOMP, InType), ADD_MODES(nesterov_a_test_task_seq::TestTaskSequential, InType), ADD_MODES(nesterov_a_test_task_stl::TestTaskSTL, InType), ADD_MODES(nesterov_a_test_task_tbb::TestTaskTBB, InType)) From 33ae009c1027ca9638195ad7ad64263b92b73afd Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 21 May 2025 11:21:36 +0200 Subject: [PATCH 012/141] update seq task --- tasks-1/example/seq/include/ops_seq.hpp | 4 ++-- tasks-1/example/seq/src/ops_seq.cpp | 10 +++++----- tasks-1/example/tests/func_tests/main.cpp | 2 +- tasks-1/example/tests/perf_tests/main.cpp | 12 ++++++------ 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tasks-1/example/seq/include/ops_seq.hpp b/tasks-1/example/seq/include/ops_seq.hpp index df2303de3..ac5f3cb1e 100644 --- a/tasks-1/example/seq/include/ops_seq.hpp +++ b/tasks-1/example/seq/include/ops_seq.hpp @@ -10,9 +10,9 @@ namespace nesterov_a_test_task_seq { using InType = std::vector; using OutType = std::vector; -class TestTaskSequential : public ppc::core::Task { +class TestTaskSEQ : public ppc::core::Task { public: - explicit TestTaskSequential(const InType& in); + explicit TestTaskSEQ(const InType& in); bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; diff --git a/tasks-1/example/seq/src/ops_seq.cpp b/tasks-1/example/seq/src/ops_seq.cpp index da361f8c2..ec604f977 100644 --- a/tasks-1/example/seq/src/ops_seq.cpp +++ b/tasks-1/example/seq/src/ops_seq.cpp @@ -4,22 +4,22 @@ #include #include -nesterov_a_test_task_seq::TestTaskSequential::TestTaskSequential(const InType& in) { +nesterov_a_test_task_seq::TestTaskSEQ::TestTaskSEQ(const InType& in) { GetInput() = in; } -bool nesterov_a_test_task_seq::TestTaskSequential::ValidationImpl() { +bool nesterov_a_test_task_seq::TestTaskSEQ::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task_seq::TestTaskSequential::PreProcessingImpl() { +bool nesterov_a_test_task_seq::TestTaskSEQ::PreProcessingImpl() { rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task_seq::TestTaskSequential::RunImpl() { +bool nesterov_a_test_task_seq::TestTaskSEQ::RunImpl() { // Multiply matrices for (int i = 0; i < rc_size_; ++i) { for (int j = 0; j < rc_size_; ++j) { @@ -31,4 +31,4 @@ bool nesterov_a_test_task_seq::TestTaskSequential::RunImpl() { return true; } -bool nesterov_a_test_task_seq::TestTaskSequential::PostProcessingImpl() { return true; } +bool nesterov_a_test_task_seq::TestTaskSEQ::PostProcessingImpl() { return true; } diff --git a/tasks-1/example/tests/func_tests/main.cpp b/tasks-1/example/tests/func_tests/main.cpp index 731cd6091..d003f3373 100644 --- a/tasks-1/example/tests/func_tests/main.cpp +++ b/tasks-1/example/tests/func_tests/main.cpp @@ -64,6 +64,6 @@ INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTests, ::testing::Values(ADD_TASK(nesterov_a_test_task_all::TestTaskALL), ADD_TASK(nesterov_a_test_task_mpi::TestTaskMPI), ADD_TASK(nesterov_a_test_task_omp::TestTaskOMP), - ADD_TASK(nesterov_a_test_task_seq::TestTaskSequential), + ADD_TASK(nesterov_a_test_task_seq::TestTaskSEQ), ADD_TASK(nesterov_a_test_task_stl::TestTaskSTL), ADD_TASK(nesterov_a_test_task_tbb::TestTaskTBB))); diff --git a/tasks-1/example/tests/perf_tests/main.cpp b/tasks-1/example/tests/perf_tests/main.cpp index 98aa114f1..4dc3fcf7f 100644 --- a/tasks-1/example/tests/perf_tests/main.cpp +++ b/tasks-1/example/tests/perf_tests/main.cpp @@ -56,10 +56,10 @@ INSTANTIATE_TEST_SUITE_P_NOLINT( RunModeTests, ExampleRunPerfTest, ::testing::Values( - ADD_MODES(nesterov_a_test_task_all::TestTaskALL, InType), - ADD_MODES(nesterov_a_test_task_mpi::TestTaskMPI, InType), - ADD_MODES(nesterov_a_test_task_omp::TestTaskOMP, InType), - ADD_MODES(nesterov_a_test_task_seq::TestTaskSequential, InType), - ADD_MODES(nesterov_a_test_task_stl::TestTaskSTL, InType), - ADD_MODES(nesterov_a_test_task_tbb::TestTaskTBB, InType)) + ADD_MODES(nesterov_a_test_task_all::TestTaskALL, InType), + ADD_MODES(nesterov_a_test_task_mpi::TestTaskMPI, InType), + ADD_MODES(nesterov_a_test_task_omp::TestTaskOMP, InType), + ADD_MODES(nesterov_a_test_task_seq::TestTaskSEQ, InType), + ADD_MODES(nesterov_a_test_task_stl::TestTaskSTL, InType), + ADD_MODES(nesterov_a_test_task_tbb::TestTaskTBB, InType)) ); From 984570ee5c4ad227f4ca0b6a8bbc91c96a688175 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Fri, 23 May 2025 12:47:24 +0200 Subject: [PATCH 013/141] fix core tests --- modules/core/perf/func_tests/perf_tests.cpp | 36 ++++++++++----------- modules/core/perf/func_tests/test_task.hpp | 28 +++++++--------- modules/core/task/func_tests/task_tests.cpp | 28 ++++++++-------- modules/core/task/func_tests/test_task.hpp | 28 +++++++--------- modules/core/task/include/task.hpp | 6 ++-- modules/core/util/include/test_util.hpp | 10 +++--- tasks-1/example/tests/func_tests/main.cpp | 4 +-- 7 files changed, 64 insertions(+), 76 deletions(-) diff --git a/modules/core/perf/func_tests/perf_tests.cpp b/modules/core/perf/func_tests/perf_tests.cpp index 7704073c3..407eed9b3 100644 --- a/modules/core/perf/func_tests/perf_tests.cpp +++ b/modules/core/perf/func_tests/perf_tests.cpp @@ -14,19 +14,19 @@ TEST(perf_tests, check_perf_pipeline) { std::vector in(2000, 1); // Create Task - auto test_task = std::make_shared>(in); + auto test_task = std::make_shared, uint32_t>>(in); // Create Perf analyzer - ppc::core::Perf perf_analyzer(test_task); + ppc::core::Perf, uint32_t> perf_analyzer(test_task); // Create Perf attributes ppc::core::PerfAttr perf_attr; perf_analyzer.PipelineRun(perf_attr); // Get perf statistic - perf_analyzer.PrintPerfStatistic(); + perf_analyzer.PrintPerfStatistic("check_perf_pipeline"); ASSERT_LE(perf_analyzer.GetPerfResults().time_sec, ppc::core::PerfResults::kMaxTime); - EXPECT_EQ(test_task->Get(), in.size()); + EXPECT_EQ(test_task->GetOutput(), in.size()); } TEST(perf_tests, check_perf_pipeline_float) { @@ -34,19 +34,19 @@ TEST(perf_tests, check_perf_pipeline_float) { std::vector in(2000, 1); // Create Task - auto test_task = std::make_shared>(in); + auto test_task = std::make_shared, float>>(in); // Create Perf analyzer - ppc::core::Perf perf_analyzer(test_task); + ppc::core::Perf, float> perf_analyzer(test_task); // Create Perf attributes ppc::core::PerfAttr perf_attr; perf_analyzer.PipelineRun(perf_attr); // Get perf statistic - perf_analyzer.PrintPerfStatistic(); + perf_analyzer.PrintPerfStatistic("check_perf_pipeline_float"); ASSERT_LE(perf_analyzer.GetPerfResults().time_sec, ppc::core::PerfResults::kMaxTime); - EXPECT_EQ(test_task->Get(), in.size()); + EXPECT_EQ(test_task->GetOutput(), in.size()); } TEST(perf_tests, check_perf_pipeline_uint8_t_slow_test) { @@ -54,10 +54,10 @@ TEST(perf_tests, check_perf_pipeline_uint8_t_slow_test) { std::vector in(128, 1); // Create Task - auto test_task = std::make_shared>(in); + auto test_task = std::make_shared, uint8_t>>(in); // Create Perf analyzer - ppc::core::Perf perf_analyzer(test_task); + ppc::core::Perf, uint8_t> perf_analyzer(test_task); // Create Perf attributes ppc::core::PerfAttr perf_attr; @@ -72,7 +72,7 @@ TEST(perf_tests, check_perf_pipeline_uint8_t_slow_test) { perf_analyzer.PipelineRun(perf_attr); // Get perf statistic - ASSERT_ANY_THROW(perf_analyzer.PrintPerfStatistic()); + ASSERT_ANY_THROW(perf_analyzer.PrintPerfStatistic("check_perf_pipeline_uint8_t_slow_test")); } TEST(perf_tests, check_perf_task_exception) { @@ -80,13 +80,13 @@ TEST(perf_tests, check_perf_task_exception) { std::vector in(2000, 1); // Create Task - auto test_task = std::make_shared>(in); + auto test_task = std::make_shared, uint32_t>>(in); // Create Perf analyzer - ppc::core::Perf perf_analyzer(test_task); + ppc::core::Perf, uint32_t> perf_analyzer(test_task); // Get perf statistic - ASSERT_ANY_THROW(perf_analyzer.PrintPerfStatistic()); + ASSERT_ANY_THROW(perf_analyzer.PrintPerfStatistic("check_perf_task_exception")); // Create Perf attributes ppc::core::PerfAttr perf_attr; @@ -98,17 +98,17 @@ TEST(perf_tests, check_perf_task_float) { std::vector in(2000, 1); // Create Task - auto test_task = std::make_shared>(in); + auto test_task = std::make_shared, float>>(in); // Create Perf analyzer - ppc::core::Perf perf_analyzer(test_task); + ppc::core::Perf, float> perf_analyzer(test_task); // Create Perf attributes ppc::core::PerfAttr perf_attr; perf_analyzer.TaskRun(perf_attr); // Get perf statistic - perf_analyzer.PrintPerfStatistic(); + perf_analyzer.PrintPerfStatistic("check_perf_task_float"); ASSERT_LE(perf_analyzer.GetPerfResults().time_sec, ppc::core::PerfResults::kMaxTime); - EXPECT_EQ(test_task->Get(), in.size()); + EXPECT_EQ(test_task->GetOutput(), in.size()); } diff --git a/modules/core/perf/func_tests/test_task.hpp b/modules/core/perf/func_tests/test_task.hpp index 3a9982765..653436e52 100644 --- a/modules/core/perf/func_tests/test_task.hpp +++ b/modules/core/perf/func_tests/test_task.hpp @@ -9,42 +9,36 @@ namespace ppc::test::perf { -template -class TestTask : public ppc::core::Task { +template +class TestTask : public ppc::core::Task { public: - explicit TestTask(const std::vector& in) : input_(in) {} + explicit TestTask(const InType& in) { this->GetInput() = in; } - bool ValidationImpl() override { return !input_.empty(); } + bool ValidationImpl() override { return !this->GetInput().empty(); } bool PreProcessingImpl() override { - output_ = 0; + this->GetOutput() = 0; return true; } bool RunImpl() override { - for (unsigned i = 0; i < input_.size(); i++) { - output_ += input_[i]; + for (unsigned i = 0; i < this->GetInput().size(); i++) { + this->GetOutput() += this->GetInput()[i]; } return true; } bool PostProcessingImpl() override { return true; } - - T Get() { return output_; } - - private: - std::vector input_{}; - T output_; }; -template -class FakePerfTask : public TestTask { +template +class FakePerfTask : public TestTask { public: - explicit FakePerfTask(const std::vector& in) : TestTask(in) {} + explicit FakePerfTask(const InType& in) : TestTask(in) {} bool RunImpl() override { std::this_thread::sleep_for(std::chrono::seconds(11)); - return TestTask::RunImpl(); + return TestTask::RunImpl(); } }; diff --git a/modules/core/task/func_tests/task_tests.cpp b/modules/core/task/func_tests/task_tests.cpp index 36aae351c..da420c85b 100644 --- a/modules/core/task/func_tests/task_tests.cpp +++ b/modules/core/task/func_tests/task_tests.cpp @@ -13,7 +13,7 @@ TEST(task_tests, check_int32_t) { std::vector in(20, 1); // Create and check Task - ppc::test::task::TestTask test_task(in); + ppc::test::task::TestTask, int32_t> test_task(in); bool is_valid = test_task.Validation(); ASSERT_EQ(is_valid, true); @@ -23,7 +23,7 @@ TEST(task_tests, check_int32_t) { test_task.PostProcessing(); // Check Result - ASSERT_EQ(static_cast(test_task.Get()), in.size()); + ASSERT_EQ(static_cast(test_task.GetOutput()), in.size()); } TEST(task_tests, check_int32_t_slow) { @@ -31,7 +31,7 @@ TEST(task_tests, check_int32_t_slow) { std::vector in(20, 1); // Create and check Task - ppc::test::task::FakeSlowTask test_task(in); + ppc::test::task::FakeSlowTask, int32_t> test_task(in); bool is_valid = test_task.Validation(); ASSERT_EQ(is_valid, true); @@ -46,7 +46,7 @@ TEST(task_tests, check_validate_func) { std::vector in; // Create and check Task - ppc::test::task::TestTask test_task(in); + ppc::test::task::TestTask, int32_t> test_task(in); bool is_valid = test_task.Validation(); // Check Result @@ -62,7 +62,7 @@ TEST(task_tests, check_double) { std::vector in(20, 1); // Create and check Task - ppc::test::task::TestTask test_task(in); + ppc::test::task::TestTask, double> test_task(in); bool is_valid = test_task.Validation(); ASSERT_EQ(is_valid, true); @@ -72,7 +72,7 @@ TEST(task_tests, check_double) { test_task.PostProcessing(); // Check Result - EXPECT_NEAR(test_task.Get(), static_cast(in.size()), 1e-6); + EXPECT_NEAR(test_task.GetOutput(), static_cast(in.size()), 1e-6); } TEST(task_tests, check_uint8_t) { @@ -80,7 +80,7 @@ TEST(task_tests, check_uint8_t) { std::vector in(20, 1); // Create Task - ppc::test::task::TestTask test_task(in); + ppc::test::task::TestTask, uint8_t> test_task(in); bool is_valid = test_task.Validation(); ASSERT_EQ(is_valid, true); @@ -90,7 +90,7 @@ TEST(task_tests, check_uint8_t) { test_task.PostProcessing(); // Check Result - ASSERT_EQ(static_cast(test_task.Get()), in.size()); + ASSERT_EQ(static_cast(test_task.GetOutput()), in.size()); } TEST(task_tests, check_int64_t) { @@ -98,7 +98,7 @@ TEST(task_tests, check_int64_t) { std::vector in(20, 1); // Create Task - ppc::test::task::TestTask test_task(in); + ppc::test::task::TestTask, int64_t> test_task(in); bool is_valid = test_task.Validation(); ASSERT_EQ(is_valid, true); @@ -108,7 +108,7 @@ TEST(task_tests, check_int64_t) { test_task.PostProcessing(); // Check Result - ASSERT_EQ(static_cast(test_task.Get()), in.size()); + ASSERT_EQ(static_cast(test_task.GetOutput()), in.size()); } TEST(task_tests, check_float) { @@ -116,7 +116,7 @@ TEST(task_tests, check_float) { std::vector in(20, 1); // Create Task - ppc::test::task::TestTask test_task(in); + ppc::test::task::TestTask, float> test_task(in); bool is_valid = test_task.Validation(); ASSERT_EQ(is_valid, true); @@ -126,7 +126,7 @@ TEST(task_tests, check_float) { test_task.PostProcessing(); // Check Result - EXPECT_NEAR(test_task.Get(), in.size(), 1e-3); + EXPECT_NEAR(test_task.GetOutput(), in.size(), 1e-3); } DEATH_TEST(task_tests, check_wrong_order) { @@ -135,7 +135,7 @@ DEATH_TEST(task_tests, check_wrong_order) { std::vector in(20, 1); // Create Task - ppc::test::task::TestTask test_task(in); + ppc::test::task::TestTask, float> test_task(in); bool is_valid = test_task.Validation(); ASSERT_EQ(is_valid, true); test_task.PreProcessing(); @@ -150,7 +150,7 @@ DEATH_TEST(task_tests, check_empty_order) { std::vector in(20, 1); // Create Task - ppc::test::task::TestTask test_task(in); + ppc::test::task::TestTask, float> test_task(in); }; EXPECT_DEATH_IF_SUPPORTED(destroy_function(), ".*ORDER OF FUNCTIONS IS NOT RIGHT.*"); } diff --git a/modules/core/task/func_tests/test_task.hpp b/modules/core/task/func_tests/test_task.hpp index ec79cefbf..e3d872e2f 100644 --- a/modules/core/task/func_tests/test_task.hpp +++ b/modules/core/task/func_tests/test_task.hpp @@ -8,42 +8,36 @@ namespace ppc::test::task { -template -class TestTask : public ppc::core::Task { +template +class TestTask : public ppc::core::Task { public: - explicit TestTask(const std::vector& in) : input_(in) {} + explicit TestTask(const InType& in) { this->GetInput() = in; } - bool ValidationImpl() override { return !input_.empty(); } + bool ValidationImpl() override { return !this->GetInput().empty(); } bool PreProcessingImpl() override { - output_ = 0; + this->GetOutput() = 0; return true; } bool RunImpl() override { - for (unsigned i = 0; i < input_.size(); i++) { - output_ += input_[i]; + for (unsigned i = 0; i < this->GetInput().size(); i++) { + this->GetOutput() += this->GetInput()[i]; } return true; } bool PostProcessingImpl() override { return true; } - - T Get() { return output_; } - - private: - std::vector input_{}; - T output_; }; -template -class FakeSlowTask : public TestTask { +template +class FakeSlowTask : public TestTask { public: - explicit FakeSlowTask(const std::vector& in) : TestTask(in) {} + explicit FakeSlowTask(const InType& in) : TestTask(in) {} bool RunImpl() override { std::this_thread::sleep_for(std::chrono::seconds(2)); - return TestTask::RunImpl(); + return TestTask::RunImpl(); } }; diff --git a/modules/core/task/include/task.hpp b/modules/core/task/include/task.hpp index bd4efc6a0..6a6cf20e0 100644 --- a/modules/core/task/include/task.hpp +++ b/modules/core/task/include/task.hpp @@ -26,7 +26,7 @@ class Task { public: enum StateOfTesting : uint8_t { kFunc, kPerf }; - explicit Task(StateOfTesting state_of_testing = StateOfTesting::kFunc) { + explicit Task(StateOfTesting /*state_of_testing*/ = StateOfTesting::kFunc) { auto custom_terminate = []() { std::cerr << "ORDER OF FUNCTIONS IS NOT RIGHT! \n" "Expected - \"Validation\", \"PreProcessing\", \"Run\", \"PostProcessing\" \n"; @@ -127,7 +127,7 @@ class Task { private: InType input_; OutType output_; - StateOfTesting state_of_testing_; + StateOfTesting state_of_testing_ = kFunc; std::vector functions_order_; std::vector right_functions_order_ = {"Validation", "PreProcessing", "Run", "PostProcessing"}; static constexpr double kMaxTestTime = 1.0; @@ -150,7 +150,7 @@ template using TaskPtr = std::shared_ptr>; template -std::shared_ptr task_getter(InType in) { +std::shared_ptr TaskGetter(InType in) { return std::make_shared(in); } diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/test_util.hpp index 60a39592b..9f8fa8e28 100644 --- a/modules/core/util/include/test_util.hpp +++ b/modules/core/util/include/test_util.hpp @@ -48,10 +48,10 @@ class BaseRunPerfTests : public ::testing::TestWithParam task; }; -#define ADD_MODES(TaskType, InputTypeParam) \ - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, ppc::core::task_getter, \ - ppc::util::GetNamespace()), \ - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, \ - ppc::core::task_getter, ppc::util::GetNamespace()) +#define ADD_MODES(TaskType, InputTypeParam) \ + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, ppc::core::TaskGetter, \ + ppc::util::GetNamespace()), \ + std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, \ + ppc::core::TaskGetter, ppc::util::GetNamespace()) } // namespace ppc::util diff --git a/tasks-1/example/tests/func_tests/main.cpp b/tasks-1/example/tests/func_tests/main.cpp index d003f3373..a8318d188 100644 --- a/tasks-1/example/tests/func_tests/main.cpp +++ b/tasks-1/example/tests/func_tests/main.cpp @@ -57,8 +57,8 @@ TEST_P(NesterovARunFuncTests, MatmulFromPic) { } #define ADD_TASK(TASK) \ - std::make_tuple(5, ppc::core::task_getter), \ - std::make_tuple(10, ppc::core::task_getter) + std::make_tuple(5, ppc::core::TaskGetter), \ + std::make_tuple(10, ppc::core::TaskGetter) INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTests, ::testing::Values(ADD_TASK(nesterov_a_test_task_all::TestTaskALL), From a0a5ef084311a6caeccadca0835517b59ad27614 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Fri, 23 May 2025 12:49:29 +0200 Subject: [PATCH 014/141] fix clang format --- tasks-1/example/all/include/ops_all.hpp | 1 + tasks-1/example/all/src/ops_all.cpp | 4 +-- tasks-1/example/mpi/include/ops_mpi.hpp | 1 + tasks-1/example/mpi/src/ops_mpi.cpp | 4 +-- tasks-1/example/omp/src/ops_omp.cpp | 4 +-- tasks-1/example/seq/src/ops_seq.cpp | 4 +-- tasks-1/example/stl/src/ops_stl.cpp | 4 +-- tasks-1/example/tbb/src/ops_tbb.cpp | 4 +-- tasks-1/example/tests/func_tests/main.cpp | 12 +++------ tasks-1/example/tests/perf_tests/main.cpp | 33 +++++++++-------------- 10 files changed, 24 insertions(+), 47 deletions(-) diff --git a/tasks-1/example/all/include/ops_all.hpp b/tasks-1/example/all/include/ops_all.hpp index e28911067..5d5163012 100644 --- a/tasks-1/example/all/include/ops_all.hpp +++ b/tasks-1/example/all/include/ops_all.hpp @@ -20,6 +20,7 @@ class TestTaskALL : public ppc::core::Task { bool PreProcessingImpl() override; bool RunImpl() override; bool PostProcessingImpl() override; + private: int rc_size_{}; }; diff --git a/tasks-1/example/all/src/ops_all.cpp b/tasks-1/example/all/src/ops_all.cpp index 5947839d8..8ef7285ef 100644 --- a/tasks-1/example/all/src/ops_all.cpp +++ b/tasks-1/example/all/src/ops_all.cpp @@ -27,9 +27,7 @@ void nesterov_a_test_task_all::MatMulTBB(const InType &in_vec, int rc_size, OutT MatMul(in_vec, rc_size, out_vec); } -nesterov_a_test_task_all::TestTaskALL::TestTaskALL(const InType &in) { - GetInput() = in; -} +nesterov_a_test_task_all::TestTaskALL::TestTaskALL(const InType &in) { GetInput() = in; } bool nesterov_a_test_task_all::TestTaskALL::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); diff --git a/tasks-1/example/mpi/include/ops_mpi.hpp b/tasks-1/example/mpi/include/ops_mpi.hpp index f80e39548..e0e3d5863 100644 --- a/tasks-1/example/mpi/include/ops_mpi.hpp +++ b/tasks-1/example/mpi/include/ops_mpi.hpp @@ -20,6 +20,7 @@ class TestTaskMPI : public ppc::core::Task { bool PreProcessingImpl() override; bool RunImpl() override; bool PostProcessingImpl() override; + private: int rc_size_{}; diff --git a/tasks-1/example/mpi/src/ops_mpi.cpp b/tasks-1/example/mpi/src/ops_mpi.cpp index b60b9287e..1be470a83 100644 --- a/tasks-1/example/mpi/src/ops_mpi.cpp +++ b/tasks-1/example/mpi/src/ops_mpi.cpp @@ -26,9 +26,7 @@ void nesterov_a_test_task_mpi::MultiplyColumnMajor(const InType &in, OutType &ou } } -nesterov_a_test_task_mpi::TestTaskMPI::TestTaskMPI(const InType &in) { - GetInput() = in; -} +nesterov_a_test_task_mpi::TestTaskMPI::TestTaskMPI(const InType &in) { GetInput() = in; } bool nesterov_a_test_task_mpi::TestTaskMPI::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); diff --git a/tasks-1/example/omp/src/ops_omp.cpp b/tasks-1/example/omp/src/ops_omp.cpp index ce7059549..87cf9cee1 100644 --- a/tasks-1/example/omp/src/ops_omp.cpp +++ b/tasks-1/example/omp/src/ops_omp.cpp @@ -4,9 +4,7 @@ #include #include -nesterov_a_test_task_omp::TestTaskOMP::TestTaskOMP(const InType& in) { - GetInput() = in; -} +nesterov_a_test_task_omp::TestTaskOMP::TestTaskOMP(const InType& in) { GetInput() = in; } bool nesterov_a_test_task_omp::TestTaskOMP::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); diff --git a/tasks-1/example/seq/src/ops_seq.cpp b/tasks-1/example/seq/src/ops_seq.cpp index ec604f977..dfe608328 100644 --- a/tasks-1/example/seq/src/ops_seq.cpp +++ b/tasks-1/example/seq/src/ops_seq.cpp @@ -4,9 +4,7 @@ #include #include -nesterov_a_test_task_seq::TestTaskSEQ::TestTaskSEQ(const InType& in) { - GetInput() = in; -} +nesterov_a_test_task_seq::TestTaskSEQ::TestTaskSEQ(const InType& in) { GetInput() = in; } bool nesterov_a_test_task_seq::TestTaskSEQ::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); diff --git a/tasks-1/example/stl/src/ops_stl.cpp b/tasks-1/example/stl/src/ops_stl.cpp index a335bd999..83fa2e0cf 100644 --- a/tasks-1/example/stl/src/ops_stl.cpp +++ b/tasks-1/example/stl/src/ops_stl.cpp @@ -21,9 +21,7 @@ void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_v } } // namespace -nesterov_a_test_task_stl::TestTaskSTL::TestTaskSTL(const InType& in) { - GetInput() = in; -} +nesterov_a_test_task_stl::TestTaskSTL::TestTaskSTL(const InType &in) { GetInput() = in; } bool nesterov_a_test_task_stl::TestTaskSTL::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); diff --git a/tasks-1/example/tbb/src/ops_tbb.cpp b/tasks-1/example/tbb/src/ops_tbb.cpp index 055ac8a21..51d6bd079 100644 --- a/tasks-1/example/tbb/src/ops_tbb.cpp +++ b/tasks-1/example/tbb/src/ops_tbb.cpp @@ -22,9 +22,7 @@ void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_v } } // namespace -nesterov_a_test_task_tbb::TestTaskTBB::TestTaskTBB(const InType& in) { - GetInput() = in; -} +nesterov_a_test_task_tbb::TestTaskTBB::TestTaskTBB(const InType &in) { GetInput() = in; } bool nesterov_a_test_task_tbb::TestTaskTBB::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); diff --git a/tasks-1/example/tests/func_tests/main.cpp b/tasks-1/example/tests/func_tests/main.cpp index a8318d188..dd15ca1fd 100644 --- a/tasks-1/example/tests/func_tests/main.cpp +++ b/tasks-1/example/tests/func_tests/main.cpp @@ -5,6 +5,7 @@ #include #include +#include "core/util/include/util.hpp" #include "example/all/include/ops_all.hpp" #include "example/mpi/include/ops_mpi.hpp" #include "example/omp/include/ops_omp.hpp" @@ -12,14 +13,12 @@ #include "example/stl/include/ops_stl.hpp" #include "example/tbb/include/ops_tbb.hpp" -#include "core/util/include/util.hpp" - using InType = std::vector; using OutType = std::vector; using TestParam = std::tuple(InType)>>; -class NesterovARunFuncTests: public ::testing::TestWithParam { +class NesterovARunFuncTests : public ::testing::TestWithParam { protected: void SetUp() override { // Read image @@ -52,13 +51,10 @@ class NesterovARunFuncTests: public ::testing::TestWithParam { std::vector img; }; -TEST_P(NesterovARunFuncTests, MatmulFromPic) { - ExecuteTest(); -} +TEST_P(NesterovARunFuncTests, MatmulFromPic) { ExecuteTest(); } #define ADD_TASK(TASK) \ - std::make_tuple(5, ppc::core::TaskGetter), \ - std::make_tuple(10, ppc::core::TaskGetter) + std::make_tuple(5, ppc::core::TaskGetter), std::make_tuple(10, ppc::core::TaskGetter) INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTests, ::testing::Values(ADD_TASK(nesterov_a_test_task_all::TestTaskALL), diff --git a/tasks-1/example/tests/perf_tests/main.cpp b/tasks-1/example/tests/perf_tests/main.cpp index 4dc3fcf7f..2200e2ebb 100644 --- a/tasks-1/example/tests/perf_tests/main.cpp +++ b/tasks-1/example/tests/perf_tests/main.cpp @@ -5,6 +5,9 @@ #include #include +#include "core/perf/include/perf.hpp" +#include "core/util/include/test_util.hpp" +#include "core/util/include/util.hpp" #include "example/all/include/ops_all.hpp" #include "example/mpi/include/ops_mpi.hpp" #include "example/omp/include/ops_omp.hpp" @@ -12,10 +15,6 @@ #include "example/stl/include/ops_stl.hpp" #include "example/tbb/include/ops_tbb.hpp" -#include "core/perf/include/perf.hpp" -#include "core/util/include/util.hpp" -#include "core/util/include/test_util.hpp" - using InType = std::vector; using OutType = std::vector; @@ -39,27 +38,19 @@ class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { }; } - bool CheckTestOutputData(OutType& output_data) final { - return input_data == output_data; - } + bool CheckTestOutputData(OutType& output_data) final { return input_data == output_data; } - InType GetTestInputData() final { - return input_data; - } + InType GetTestInputData() final { return input_data; } }; TEST_P(ExampleRunPerfTest, RunModes) { ExecuteTest(std::get<0>(GetParam()), std::get<1>(GetParam()), std::get<2>(GetParam())); } -INSTANTIATE_TEST_SUITE_P_NOLINT( - RunModeTests, - ExampleRunPerfTest, - ::testing::Values( - ADD_MODES(nesterov_a_test_task_all::TestTaskALL, InType), - ADD_MODES(nesterov_a_test_task_mpi::TestTaskMPI, InType), - ADD_MODES(nesterov_a_test_task_omp::TestTaskOMP, InType), - ADD_MODES(nesterov_a_test_task_seq::TestTaskSEQ, InType), - ADD_MODES(nesterov_a_test_task_stl::TestTaskSTL, InType), - ADD_MODES(nesterov_a_test_task_tbb::TestTaskTBB, InType)) -); +INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, ExampleRunPerfTest, + ::testing::Values(ADD_MODES(nesterov_a_test_task_all::TestTaskALL, InType), + ADD_MODES(nesterov_a_test_task_mpi::TestTaskMPI, InType), + ADD_MODES(nesterov_a_test_task_omp::TestTaskOMP, InType), + ADD_MODES(nesterov_a_test_task_seq::TestTaskSEQ, InType), + ADD_MODES(nesterov_a_test_task_stl::TestTaskSTL, InType), + ADD_MODES(nesterov_a_test_task_tbb::TestTaskTBB, InType))); From 7d671e0f60aaed9ae261980b95b44fe46a853d65 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Fri, 23 May 2025 12:54:33 +0200 Subject: [PATCH 015/141] update dir --- CMakeLists.txt | 6 +- tasks-1/CMakeLists.txt | 26 ---- tasks/CMakeLists.txt | 125 +++--------------- tasks/all/example/data/pic_all.jpg | Bin 15356 -> 0 bytes tasks/all/example/func_tests/main.cpp | 75 ----------- tasks/all/example/include/ops_all.hpp | 27 ---- tasks/all/example/perf_tests/main.cpp | 57 -------- tasks/all/example/src/ops_all.cpp | 68 ---------- tasks/all/runner.cpp | 93 ------------- {tasks-1 => tasks}/example/CMakeLists.txt | 0 .../example/all/include/ops_all.hpp | 0 .../example/all/src/ops_all.cpp | 0 .../example/mpi/include/ops_mpi.hpp | 0 .../example/mpi/src/ops_mpi.cpp | 0 .../example/omp/include/ops_omp.hpp | 0 .../example/omp/src/ops_omp.cpp | 0 .../example/seq/include/ops_seq.hpp | 0 .../example/seq/src/ops_seq.cpp | 0 .../example/stl/include/ops_stl.hpp | 0 .../example/stl/src/ops_stl.cpp | 0 .../example/tbb/include/ops_tbb.hpp | 0 .../example/tbb/src/ops_tbb.cpp | 0 .../example/tests/data/pic_all.jpg | Bin .../example/tests/func_tests/main.cpp | 0 .../example/tests/perf_tests/main.cpp | 0 {tasks-1 => tasks}/example/tests/runner.cpp | 0 tasks/mpi/example/data/test.txt | 1 - tasks/mpi/example/func_tests/main.cpp | 74 ----------- tasks/mpi/example/include/ops_mpi.hpp | 29 ---- tasks/mpi/example/perf_tests/main.cpp | 60 --------- tasks/mpi/example/src/ops_mpi.cpp | 60 --------- tasks/mpi/runner.cpp | 87 ------------ tasks/omp/example/data/test.txt | 1 - tasks/omp/example/func_tests/main.cpp | 47 ------- tasks/omp/example/include/ops_omp.hpp | 24 ---- tasks/omp/example/perf_tests/main.cpp | 55 -------- tasks/omp/example/src/ops_omp.cpp | 39 ------ tasks/omp/runner.cpp | 6 - tasks/seq/example/data/test.txt | 1 - tasks/seq/example/func_tests/main.cpp | 46 ------- tasks/seq/example/include/ops_seq.hpp | 24 ---- tasks/seq/example/perf_tests/main.cpp | 55 -------- tasks/seq/example/src/ops_seq.cpp | 32 ----- tasks/seq/runner.cpp | 6 - tasks/stl/example/data/test.txt | 1 - tasks/stl/example/func_tests/main.cpp | 47 ------- tasks/stl/example/include/ops_stl.hpp | 24 ---- tasks/stl/example/perf_tests/main.cpp | 55 -------- tasks/stl/example/src/ops_stl.cpp | 47 ------- tasks/stl/runner.cpp | 6 - tasks/tbb/example/data/test.txt | 1 - tasks/tbb/example/func_tests/main.cpp | 47 ------- tasks/tbb/example/include/ops_tbb.hpp | 24 ---- tasks/tbb/example/perf_tests/main.cpp | 55 -------- tasks/tbb/example/src/ops_tbb.cpp | 44 ------ tasks/tbb/runner.cpp | 13 -- 56 files changed, 21 insertions(+), 1467 deletions(-) delete mode 100644 tasks-1/CMakeLists.txt delete mode 100644 tasks/all/example/data/pic_all.jpg delete mode 100644 tasks/all/example/func_tests/main.cpp delete mode 100644 tasks/all/example/include/ops_all.hpp delete mode 100644 tasks/all/example/perf_tests/main.cpp delete mode 100644 tasks/all/example/src/ops_all.cpp delete mode 100644 tasks/all/runner.cpp rename {tasks-1 => tasks}/example/CMakeLists.txt (100%) rename {tasks-1 => tasks}/example/all/include/ops_all.hpp (100%) rename {tasks-1 => tasks}/example/all/src/ops_all.cpp (100%) rename {tasks-1 => tasks}/example/mpi/include/ops_mpi.hpp (100%) rename {tasks-1 => tasks}/example/mpi/src/ops_mpi.cpp (100%) rename {tasks-1 => tasks}/example/omp/include/ops_omp.hpp (100%) rename {tasks-1 => tasks}/example/omp/src/ops_omp.cpp (100%) rename {tasks-1 => tasks}/example/seq/include/ops_seq.hpp (100%) rename {tasks-1 => tasks}/example/seq/src/ops_seq.cpp (100%) rename {tasks-1 => tasks}/example/stl/include/ops_stl.hpp (100%) rename {tasks-1 => tasks}/example/stl/src/ops_stl.cpp (100%) rename {tasks-1 => tasks}/example/tbb/include/ops_tbb.hpp (100%) rename {tasks-1 => tasks}/example/tbb/src/ops_tbb.cpp (100%) rename {tasks-1 => tasks}/example/tests/data/pic_all.jpg (100%) rename {tasks-1 => tasks}/example/tests/func_tests/main.cpp (100%) rename {tasks-1 => tasks}/example/tests/perf_tests/main.cpp (100%) rename {tasks-1 => tasks}/example/tests/runner.cpp (100%) delete mode 100644 tasks/mpi/example/data/test.txt delete mode 100644 tasks/mpi/example/func_tests/main.cpp delete mode 100644 tasks/mpi/example/include/ops_mpi.hpp delete mode 100644 tasks/mpi/example/perf_tests/main.cpp delete mode 100644 tasks/mpi/example/src/ops_mpi.cpp delete mode 100644 tasks/mpi/runner.cpp delete mode 100644 tasks/omp/example/data/test.txt delete mode 100644 tasks/omp/example/func_tests/main.cpp delete mode 100644 tasks/omp/example/include/ops_omp.hpp delete mode 100644 tasks/omp/example/perf_tests/main.cpp delete mode 100644 tasks/omp/example/src/ops_omp.cpp delete mode 100644 tasks/omp/runner.cpp delete mode 100644 tasks/seq/example/data/test.txt delete mode 100644 tasks/seq/example/func_tests/main.cpp delete mode 100644 tasks/seq/example/include/ops_seq.hpp delete mode 100644 tasks/seq/example/perf_tests/main.cpp delete mode 100644 tasks/seq/example/src/ops_seq.cpp delete mode 100644 tasks/seq/runner.cpp delete mode 100644 tasks/stl/example/data/test.txt delete mode 100644 tasks/stl/example/func_tests/main.cpp delete mode 100644 tasks/stl/example/include/ops_stl.hpp delete mode 100644 tasks/stl/example/perf_tests/main.cpp delete mode 100644 tasks/stl/example/src/ops_stl.cpp delete mode 100644 tasks/stl/runner.cpp delete mode 100644 tasks/tbb/example/data/test.txt delete mode 100644 tasks/tbb/example/func_tests/main.cpp delete mode 100644 tasks/tbb/example/include/ops_tbb.hpp delete mode 100644 tasks/tbb/example/perf_tests/main.cpp delete mode 100644 tasks/tbb/example/src/ops_tbb.cpp delete mode 100644 tasks/tbb/runner.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b1042cbb5..4bf136dfb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,12 +43,10 @@ include(cmake/gtest.cmake) message( STATUS "PPC step: Setup headers" ) include_directories(3rdparty) include_directories(modules) -#include_directories(tasks) -include_directories(tasks-1) +include_directories(tasks) ############################## Modules ############################## message( STATUS "PPC step: Setup modules" ) add_subdirectory(modules) -#add_subdirectory(tasks) -add_subdirectory(tasks-1) +add_subdirectory(tasks) diff --git a/tasks-1/CMakeLists.txt b/tasks-1/CMakeLists.txt deleted file mode 100644 index 9467d6cfa..000000000 --- a/tasks-1/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -message(STATUS "Student's tasks") - -set(list_of_reverts "") - -SUBDIRLIST(subdirs ${CMAKE_CURRENT_LIST_DIR}) -foreach(subd ${subdirs}) - add_subdirectory(${subd}) - foreach (dir_type "all" "mpi" "omp" "seq" "stl" "tbb") - set(base_dir "${CMAKE_CURRENT_SOURCE_DIR}/${subd}/${dir_type}_disabled") - if (NOT EXISTS "${base_dir}") - continue() - else () - list(APPEND list_of_reverts "${subd}_${dir_type}") - endif () - endforeach () -endforeach() - -set(output_file "${CMAKE_BINARY_DIR}/revert-list.txt") -file(WRITE ${output_file} "${CONTENT}") -message(STATUS "Revert list") -foreach (dir_name ${list_of_reverts}) - message(STATUS "-- ${dir_name}") - file(APPEND ${output_file} "${dir_name}\n") -endforeach() - -add_compile_definitions(PATH_TO_PPC_PROJECT="${CMAKE_SOURCE_DIR}") diff --git a/tasks/CMakeLists.txt b/tasks/CMakeLists.txt index 4ae9df094..9467d6cfa 100644 --- a/tasks/CMakeLists.txt +++ b/tasks/CMakeLists.txt @@ -1,113 +1,26 @@ message(STATUS "Student's tasks") -list(APPEND LIST_OF_TASKS "mpi") -list(APPEND LIST_OF_TASKS "omp") -list(APPEND LIST_OF_TASKS "seq") -list(APPEND LIST_OF_TASKS "stl") -list(APPEND LIST_OF_TASKS "tbb") -list(APPEND LIST_OF_TASKS "all") - -add_compile_definitions(PATH_TO_PPC_PROJECT="${CMAKE_SOURCE_DIR}") - -add_library(stb_image INTERFACE) - -foreach(TASK_TYPE ${LIST_OF_TASKS}) - set(PATH_TO_TASK "${CMAKE_CURRENT_SOURCE_DIR}/${TASK_TYPE}") - get_filename_component(MODULE_NAME ${PATH_TO_TASK} NAME) - message(STATUS "${MODULE_NAME} tasks") - set(exec_func_tests "${MODULE_NAME}_func_tests") - set(exec_perf_tests "${MODULE_NAME}_perf_tests") - set(exec_func_lib "${MODULE_NAME}_module_lib") - set(project_suffix "_${MODULE_NAME}") - - SUBDIRLIST(subdirs ${PATH_TO_TASK}) - foreach(subd ${subdirs}) - if ("${subd}" MATCHES "_disabled$") - get_filename_component(DIR_NAME ${PATH_TO_TASK} NAME) - list(APPEND LIST_OF_REVERTS "${DIR_NAME}_${subd}") - continue() - endif() - get_filename_component(PROJECT_ID ${subd} NAME) - set(PATH_PREFIX "${PATH_TO_TASK}/${subd}") - message(STATUS "-- ${PROJECT_ID}${project_suffix}") - - file(GLOB_RECURSE TMP_LIB_SOURCE_FILES "${PATH_PREFIX}/include/*" "${PATH_PREFIX}/src/*") - list(APPEND LIB_SOURCE_FILES ${TMP_LIB_SOURCE_FILES}) - - file(GLOB SRC_RES "${PATH_PREFIX}/src/*") - list(APPEND SRC_RES ${TMP_SRC_RES}) - - file(GLOB_RECURSE TMP_FUNC_TESTS_SOURCE_FILES "${PATH_PREFIX}/func_tests/*") - list(APPEND FUNC_TESTS_SOURCE_FILES ${TMP_FUNC_TESTS_SOURCE_FILES}) - - file(GLOB_RECURSE TMP_PERF_TESTS_SOURCE_FILES "${PATH_PREFIX}/perf_tests/*") - list(APPEND PERF_TESTS_SOURCE_FILES ${TMP_PERF_TESTS_SOURCE_FILES}) - endforeach() - - project(${exec_func_lib}) - list(LENGTH SRC_RES RES_LEN) - if(RES_LEN EQUAL 0) - add_library(${exec_func_lib} INTERFACE ${LIB_SOURCE_FILES}) - else() - add_library(${exec_func_lib} STATIC ${LIB_SOURCE_FILES}) - endif() - set_target_properties(${exec_func_lib} PROPERTIES LINKER_LANGUAGE CXX) - - if (USE_FUNC_TESTS) - add_executable(${exec_func_tests} ${FUNC_TESTS_SOURCE_FILES} "${PATH_TO_TASK}/runner.cpp") - list(APPEND LIST_OF_EXEC_TESTS ${exec_func_tests}) - endif (USE_FUNC_TESTS) - if (USE_PERF_TESTS) - add_executable(${exec_perf_tests} ${PERF_TESTS_SOURCE_FILES} "${PATH_TO_TASK}/runner.cpp") - list(APPEND LIST_OF_EXEC_TESTS ${exec_perf_tests}) - endif (USE_PERF_TESTS) - - foreach (EXEC_FUNC ${LIST_OF_EXEC_TESTS}) - target_link_libraries(${EXEC_FUNC} PUBLIC ${exec_func_lib} core_module_lib) - target_link_libraries(${EXEC_FUNC} PUBLIC Threads::Threads) - target_link_libraries(${EXEC_FUNC} PUBLIC ${OpenMP_libomp_LIBRARY}) - if( MPI_COMPILE_FLAGS ) - set_target_properties(${EXEC_FUNC} PROPERTIES COMPILE_FLAGS "${MPI_COMPILE_FLAGS}") - endif( MPI_COMPILE_FLAGS ) - - if( MPI_LINK_FLAGS ) - set_target_properties(${EXEC_FUNC} PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}") - endif( MPI_LINK_FLAGS ) - target_link_libraries(${EXEC_FUNC} PUBLIC ${MPI_LIBRARIES}) - - add_dependencies(${EXEC_FUNC} ppc_onetbb) - target_link_directories(${EXEC_FUNC} PUBLIC ${CMAKE_BINARY_DIR}/ppc_onetbb/install/lib) - if(NOT MSVC) - target_link_libraries(${EXEC_FUNC} PUBLIC tbb) - endif() - - target_link_directories(stb_image INTERFACE ${CMAKE_SOURCE_DIR}/3rdparty/stb) - target_link_libraries(${EXEC_FUNC} PUBLIC stb_image) - - add_dependencies(${EXEC_FUNC} ppc_googletest) - target_link_directories(${EXEC_FUNC} PUBLIC "${CMAKE_BINARY_DIR}/ppc_googletest/install/lib") - target_link_libraries(${EXEC_FUNC} PUBLIC gtest gtest_main) - enable_testing() - add_test(NAME ${EXEC_FUNC} COMMAND ${EXEC_FUNC}) - - # Install the executable - install(TARGETS ${EXEC_FUNC} RUNTIME DESTINATION bin) +set(list_of_reverts "") + +SUBDIRLIST(subdirs ${CMAKE_CURRENT_LIST_DIR}) +foreach(subd ${subdirs}) + add_subdirectory(${subd}) + foreach (dir_type "all" "mpi" "omp" "seq" "stl" "tbb") + set(base_dir "${CMAKE_CURRENT_SOURCE_DIR}/${subd}/${dir_type}_disabled") + if (NOT EXISTS "${base_dir}") + continue() + else () + list(APPEND list_of_reverts "${subd}_${dir_type}") + endif () endforeach () - - # Install the library - install(TARGETS ${exec_func_lib} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) - - set(LIST_OF_EXEC_TESTS "") - set(LIB_SOURCE_FILES "") - set(SRC_RES "") - set(FUNC_TESTS_SOURCE_FILES "") - set(PERF_TESTS_SOURCE_FILES "") endforeach() -set(OUTPUT_FILE "${CMAKE_BINARY_DIR}/revert-list.txt") -file(WRITE ${OUTPUT_FILE} "${CONTENT}") -message(STATUS "revert list") -foreach (dir_name ${LIST_OF_REVERTS}) +set(output_file "${CMAKE_BINARY_DIR}/revert-list.txt") +file(WRITE ${output_file} "${CONTENT}") +message(STATUS "Revert list") +foreach (dir_name ${list_of_reverts}) message(STATUS "-- ${dir_name}") - file(APPEND ${OUTPUT_FILE} "${dir_name}\n") + file(APPEND ${output_file} "${dir_name}\n") endforeach() + +add_compile_definitions(PATH_TO_PPC_PROJECT="${CMAKE_SOURCE_DIR}") diff --git a/tasks/all/example/data/pic_all.jpg b/tasks/all/example/data/pic_all.jpg deleted file mode 100644 index 34458023494a39d66880a98aa5dcad18eb14b249..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15356 zcmb7r1ymeM+h(J|Lh#^jgS!(nxH}|3!r<;sAOsKYPH>0dE6e&6od zf6v*P!%WfLQ`J@7_0Ic9Kg~R?0BAB2(h>j^6aYX$Ucl2D)Qq&4n7)#VqJ*^E>wk89 z2OtHO1put99qm;lMM<@^bx5DB{PT@p``&{cY=3?J4+YZh<mpyF;3wpd(jL+|a@S=2LIFre$`zZZ5<)UDE+G2tEq@V>V}Xyt;v7Y z4gRYRwzdCtd?@4?0V_+VUw!>5zs?xN$XZ<$@`(WXBLo}(6+jXY{WX5b|Bzyn1pqu3 z000yDpKS(708r--0JwAi*+%&V0ABb3K<&tXw*6;LY~S0z|J@uc}B7ywT50pPhd z0AT(A0Him+_d(wNhjSx^>>`Ammks1)0$2h@04X31SOZ{y2~uMNSO8Xl>uDYk17M(k zm0#~LkOB)2`>PgAVo71sMPU1NFQ79WC$- z0Uiz!76ux!R|O4nIS^rBkx>xfV4>h3hd=?)FmUkC&@nJ!u~@NjUXmf;vT=)OeDcew z8Y8Em`noY_Uo!DAF1^Q*^SP5kQd-wxrQ0dNSA z4iO=HHP8Vl7-(2nXlTUe$S5$7gP@>c(BUuuSa`B$n5-h?%2?P4IBZ-h_Kp=*FL5b2 zMBm$e^!*e)Hcrhc_F7dfDyFidlaiL5TODi^o0UDfMrE*``7{UoY6==11|1Lr5SWE7 z$Aqi}Jt})ogXX0k>MxE4Ncus+5yA){#z7(OyeXs56>}TSH!UPkRd@`O)C&{{JxaZU z3dWq3W;mr(;ooeu)rI48wv;6---WI|e`ktH3MX~p!O-Jqs1~P7Du-|)?vnnfWirkq zuT!)eXP&2P%7V6bNT>UAR7v9-9GfNUT6naiu^sHoj5{-uI^vdD@Xc!%{{T>6;JR;T z^j;`v*-$g){&*Ef-QYewdTJ(m*~XkMUlwtsK|2hxS~#IuPyl4LqqfP=%$ygw_UiQc zKS7h}-j(sJdB&`MoTB8y`*}^$BTQvCa9?wAF>@$7VkekE2za z;EYQl*-~;cz?RzQ6w3M%sJ9|g1_RQ#y@IW5*{M#5NQqP_2EFW|$h;O7+Eh;8tls6j zRBK4ZOON4)9&M8K;zV<`(fUFFBp@5_T8aBalZI^xpNIM)8q9LZlNaXHYB3PXAF0^`<4(kgxJ*8aN~9k5zUxXXSPA zY6b(w)}kNKg3=#Y+ZT$F~iWgw2P|?BJ(Xx*NT=ZdxE^l>#b&d5egtiwlOi- zS2CLJ(zcNVsL1cTd}KaGItNjkFbi`r9%BriEl<%f3-wppmBvUFITgvmeKeAWrXLJY zmT;snllkZR1Q-1u*GI~<6kBQ932wY_KvW|ZJG$}WuJOm8g4^Xqu;9Grc|e^SxM6}A?Yk` zIX0_Gh(E*u%jttk$rNHyV|hw5qKyx`DzhZ^d7b)fg)-!;TC&EY9$9=pHqw4F*omK99fTb zK0=SyYR6mM7XsEy=hZ}&#;il1dD^SuC8SHW7I3DJ5kY`|4p+-E-|^yDn}xUsUh3q%LRVW;`k6fxz@O2+FXIuJ#m@ zT9}$EYR*MrpT$0K{N>#PbJJL~^b^238v0m*Sad94t9ja@yiqic+_3&qTychxy~ab~ zc4D4BlGK!1VDATVmTf3nx&SrWXNC!)0`8Qd+H%L}T&zd{*4h~W;J5Lqvz5nqi71lC z=R7$2;`PMj$u{b17`w_aqTJ(iLFRrr(v&{WL_*%?%4aVS|i6|A1IPccJ`s zbPYl!Y`-umdXJ_4D`)ojT5qnSx+1UJ8-dCkj)%dIxC1Dz(#HA*X$qD4C6PtgIOdnt zXR4CCc|)Kq+kGBk7$t-?9jm`r7i6fqv%5hhEq)BAAL7D3kDwEi+!-_+Qhd;qOiS4G zW6%eRuI|7TG0O9}8GVlBdVci2>}vUX^Rub5(&lD&rd8quec#e)>W|nT-1s7d0^R9z zwGZ{5kNHW4sP0q-m=kj^3X{xAxH;p(Wp?NiqooHq&OEYV<#8dmPJydzK5rEG)refOr( zW6+CaofzxqxT5cRhu=_lSC|lN*-!Pc$r9YoEh`+GWJO_}QgV_lj)}>0keUUeR-g!M zv<;8maPp&#qCh9TqPP0!@_C>nX&(Ph?gV$Dnmfms{jjJgZ>ffD#iGEX5kLh!kT@tNi4N}25OvU3x(lq^q&@q87} zle8LkPsu5Pa@~zH)YG!M`@}q^&n=y1N!3n?VNI*4`_8nxAU_SR*}Is^FdO(jr^0bL zcfmz47>~jS{6gEj_VW|K;nnvjVw$?X?t)snK!?k9lHF%9sk?S%*pRQNkmVRGcQlG? z_X!gNmoFSw0;U8OF?qO+TWd;>-K(%g*RXVjD~2kW?P$~wOuM>8@BeCyU>hV%Gc0a1 z{vl=6afmuIX*k(|fl<*{l7Z^AeNw#++*l$Txj5c#@I&Uz_Ln%p%)RaKx8Lnu;T4-S zN^D8*Wby})s;nj0I@JttTPpN=?>g^Z%f2d>c^P|?zxP!pV^C} zF`0M5ov1_xxWb(6NZSA2NOaSM=W`tmdr)@O{v@3QxW}J#tjnfSc}>R>RZcTak__gg zC?hdlX3^B)zt5XJYhKT+nVx^)@&q^*Jk!}MV<4{_NUiF7)7a3#D(AW?R8sFZ41Pmx zr8YEkfO8Q?xl^QIgcT?XLPeW`4|+!`iZvHen#Q2M0QZ$rj;5RRd6zSdSx@j(BhSyv z^pK1f_Mau}ES?v9VLa;xsl+nqvp~5kuT`VHlfytoUpsg^a*%PcwQ5^@ZKS;&^DzD% zQP4F3FMMV^(>VP5>De@cp?f-9jP-?iHt&l$^;cTzDfW=eMS^tFG$WsdT&MbVxyr&8cMO8(9`#HyS)ZX^63;m!7Gx z09!P3V$(2Ra(wMsk-Xr+uRVoQuH_q7zfX4bZWAp6TD~1ti`T9#&<5+Or&xAr#IbEg zgzUWI$hCVE^AdryO>2*t>Iu*g(!{rzvw?pCVh12`vG{Uk7Hjz0rRUArhfF+G*d3R2 zn&KP1>eFPQ!_9lKvwX~1qGL_wQ$H_)`ZJDN1rJXnNuE87mpMkMt{-Shc$um@_=>!; zuDUb_?cyA1T8m8j@ovRenbfou{9i}reSRc4^==7#0xC_e%g>&Gl~tyn_qJO0y2}3i z2O+24Y4_yK2=s4TGtS+EN6u)Ra3lN$x2td7L09#>c(XIH%Pd+;VAN{D<~@pqR~0Wf znZ`8dp13^ppG=O9!8a~UXy2rBVc?y(_!Z5d+nViqD2eK=YV3&Uw%)4!kx>*#)PUFg znw@<)Zw7hfAvWcXV`1Rj6md@>&~44VEpA^CBsoD`>sd8W3p+SsD-f7YgMKY^A(YFl zdcNdz1b?_WixF33l34x;o#^&3f?d{dyRJvgAv}}JT|&DzaLv6ldS8y-Jb#Ya^R;I$ z@&n>=QPOF^hbSJ|ND+ygx~x$zJMZv$aP{EGGO^ZNs{ESG#P+CnpWFT2|2{@~3LRnm4_iGoa88nO5jpz;Ki$f0yIkAXVL zJT0SGe}b#8A_NTaxf(AdDm6;aJ#u?fHGxkq#(Zfm zBF!aE*o#NzUZggr_)2UtfEjeVzxPqyI)CRrh2Z(T*BO#do|R%pQ23%tcdUp+?hbr+ z%bIq&$8FaJ?;-QU6YwB(_kR3h@CoR60*;@6>ovn!?2RXY|5`kmS)BN4RiLetl7Dq+ z6Eci*qvNjisAZmXn!fE-aSJt(4# z@{^4wGfmA9b#P*7bETD}Kq^vjbg*c`q{Fz40^kSqF^tR45+Y31EeBV!4}M+VtO{A( zE8H&8?!Dba`EBW}HEdxe^-12@g@eoFG>JdC^aXi~iT8#MPci37*bQenLh_<#-+g5$ zBz>(QMw`utE@2v8!6Au`v9|mC>v@~x>sdx(Q;{ctSOHOY*}=DTP8|1@Y0bscX1@B;}ivRTs=vn1FQS%pgad& zV{8>s7;DPSZvs=Jmr8FLXR?sg>6-n~Ns}<=AR#x(d`#9TfOz?DuAwUi&m1YQbEw$3&zG^Gwn|js+AUNu=3E0+V2yk#m@p z8E$GvKQA9KW*qHA0T5#+z9Z^tz#}=Ke)}hw!4rQ!c5m>GrPx{QY+0|S_eWLeVtDM8N z_m(1u>JV$-U);mkLehWi^#p_~SfSmCjS9KBYZNwQniQ#;yeTEa9HX%lTpu`Dj|tG3 z^V`n#QX)BzupHLmD{|t>D(1 zwnz+Z+qE7}1n!VtjAcYx^-AH@nbq^Z%<$ltk(c0)L|B27Hw~O44!-MmnYI6JoM-Mu z;ohR(2DyiR+;`#*JppiiQhgda!(?ui#jt~Al41mJJ$ev$f(u>El*YAFYcs?sIEoo) z2jVBIg6RC?V~EiT7o?(=Sn6y;EB$Lc=%|hIzAj_e4oo^?D@qE)8|J4h;*vt(pFCvs zX~0j`VRq@e&A&2x%~aDkTI^h6RjH@kH`$Eef**&L9^nG|;djz*8(32C{O>GD%nagg z?YJ$Rxa8&^#z4jEGR)*Yk4rMP;^wppcSoS)q>M?o+jf!kNoD0(57hdZ&>_p!eYTY% zX<>3^ec_b9TplgY#;&;VoyG4*uTN|PchT$>vbKwc6z0+Q`ID&ah#zT^@;~rp=~53( zs1mGdXh}&VWtzn?V99ETgZaCxrt=5}0{m@Tv*SwRcH|XXk}a!5e^2ALx1h=53v(mU zr6IlV={iB%JhQnxsLzdq5G(*fS+=8eCU2t`nMW^?^j(Vu&K^~NWg79{>(9)FjH+nH z5VwMs49{V0XsTVlF{L|y(#awnjrWO zv0wQ7RtSY<Tgaz$cC_g*vDyqCtjhFYR%<+_Y2giI<3R!w6DHOU>(kLB7w7GML~lOPnslo8oj#s(#AFrn#z6fD5%c5p zfn<-erIC!EdHOa8SF{#wG>Zf`$1fwW{O|N056LdQXuj6qX7_<6&c3 zLh&mGP*gjgcHk$Knq!s9m8$il>C@XeM;254_)_ZY`$Z4jEl8RE1k5umuniU6_77Ik z%dYj$3c_MxP^62Y3LNd63IF(*m&(`clZY>1DTqFX?i^w=Q`c6-KH@Er+5*rin%$5D zwC$1<2Y62t6?vy@J^>;lb8C*Ew4cYJbz2XjY@SqSG#r@D{nA|rb=LBd??z`eB0mUhjVh7%KWCL=Kk)&5zNbAo~L2rf5nKgLUZWaa_ z{HYl>yL9~SDcA)Y!DB}J^DdAzgWZ_W`Cu(TcKi)zQ}s z&~Z!Azi36@89Q;GNWf$rIHN&+0t{VROWOKI&%;+Bw7!bX!MFqS=odP$lvN-kzA^PN&&3nP zTWL<^CFQ9v<7o8J=a)qhp5mGXTu~Fk`#tCQF+m6?Sa0|N`U&{*p_XQ9y~sP&=n0S? znKe*hj7eX{Qy%8?^PlrPaDW6e&t*+r8_kf#8%Quy(4Fl>kmGUtJ~LBRQL3-X`>rmt z=p*B)12rZXnf(3pcceT%*!6ClA?~p~)49Tm>jYg_9lQM&&Ad}673yRrbo=!BOj4v; z+W{-VT!~AtS7ARN=@_b#|IK#QZ$E@T&?F6$E}~=3dA6T@3&iD#kXd_{>0VKX-nXSY zh=}RUL_S%(l9YHjjp*`6I$&5e{kv=$nO4(P%PYe*DyB0fGCX-^jnny~5LRF@F69Rw zv=^Ghp*31txF{iTg~9CBI=g?D5h}W5TP2rkNuQYvz;=zEgN0V%D^OTByT|R0R0tzx zeGJ+~^bj{ai8z;(lAWVxHoG|vh}ab>_9-vpm-Xfz{P4-UrYAJ|_(d;VAk`$U>Z>`) z!`^adtw&`pT<2WRxymW(q`W$P9F6|C@iA7yQ%asrj~L)N0=`*h0T0rZmRD9p_$#CL z>IZgLlZiKck5MH&i@(<+HHa+s5NTEH4dpzoW_-Q}$8K&Yw=heWZ0xDte1{UN?5{|d zX(1w!ESm+Bn*<67&kjW+5+(a+r(`i}jB7!jQ?wiWk(dhiSn&Rbx(XJ!V2S%rdy-a&lS`FrD2^xW ztt)*yd{pLjpagnCWqdG!#C_lfET>EDW(VO=oobd^5bqXFd%)rg?^t>VwIzZpOz`+y zZ5gcV3U{tz1BV!>7w}p9zD1)+(1)>RjnP2!NuBmIJscGuT53zy?36 zcrDzV*m@-MS5y}FCZ)_ts*g7Pwd*Kw#ncRt1^;HV@-HXNL{HPAH$w~}`ss7SmJW@5 zG7A-cgpobWNy{PNzV9p%Lx8V`lI7P}u0!|Q2H)h`$eU1hzUIYXOj}uOMm_bAcA?`END>8x?kVwHKD zM&_F$teS)1t-R>dAV{hzPb5hQjo&T?UFz;HF_5<%jUmt<`^xFvR7&>;Dh*u*)r>a- z&@xJ$7Nk;`h^C3ru;PJJ;r+o2Wj<7jKPM0$Oly4u(QdhDXBe%g`5b0(6#BUd>KqY^RLg~CgMavK zt)n>E#!y}8C^hFBHW(ykpN8y$U7EDN(3-1OQ%HF`N2@}^mFNDLXJCp;ai`(I~HYG_7_XH9d~+ z?H&FAR`LIkmte`Tz$`vdrcup3lx|7pfpfqm$!~F!DAeU!;Io}MuJYa1d9|6kgn=yq zo&CX9GSj9klM<^jm(i_&4_=m#fm|)_OhzkQH73sVNUh+;2S*yRt6ZIj?OiBdv&k|n zCxY?XRvHG+MDvZXE`PyNr@C1a2rTU#VD0z?OQ}QUc_6SfK1|_9;q+vsd}Rxwxl2`8 zylJN+6d`ObJF~(T*{Ng>I^BtD8AbPMT7))wU1ZnPMVcX-TagOJc42g}jzHAFMkY8? zY)U3t_;qpfa$T@$8}=@@4(EFut6EtIrjGcenXQrqMnBr*LrdpDMZ1W70_w7FbdTFk z`noGwAyPy`p1)E-m1a$T<8Lj3u@JGdWEG+iQUr@P{s}Ec&X*313F_rMu^HsTH$Ths zc8eyBvL5)U_rJp1riFIK?tH8nZb`)x)p;C67AK_5;dio zZ?U-`D%xv9Gs85z??Xq*sdk;15geSr`W9Viyewsp6we9_2NWrWXc_G6N_q>a#GR!H zimq}ICq(C`2gRzSX7c2X)#O$eM)ya5Or&8!dr$rrS<6-%>4bW*iC@?2>y`JF6k~d# z?g(xp`G;?CefvbOH`?}k_f|gr@60Zma-k}!hewlXv5Yr@c zZ*zTzuB4NK4xS~Q_Pkts)p+|w{Y~Mm5Oq(d^Rj10d|`^}&n${M-JjSj+jR{PTDFDE zGKkc?=gUPERJ!h0V`C5W4S|y)SG#XdK;eUWe@5O}xn-RV)Au+sRe^3#+@RxWOStU6 z$=GNkNq57Gptlf~xT|_$;35dQF);su3}yQ!s=3P(+ik@4w7ndg=i6TBkeIYP_SmdV z(qP1SDGZnWNJCrhe6KP;rxY_?5H%_rJk#`_%!QF4^Zrfbwg0vouk$|$3Vy5bL%x^O z=ObVF3gVq!Z9%5fCDvS8o&CKinE~77(VLgG0XNgjgnofE3Fg#~YLe`oj(tH~7JqVg zjJLiBDivxMRjd1qAJN$tGRU?e3_B_Z^TcE9Ci@ugbp6}L0df_;uD9i%*adH`LKu8c z3w*8D&#H)n1dlu1yaS|MI$QdeQ!aM;P5#XV{Xi;NJ!a|_4_$OK`|k+kuEHzomOGyS z@e}SOQE=en=gaOvhw`geku}IS&Ne3O3rkGlg=rNz*s&tEcaBeh9b^eT*3;e2wykAc z3O!WR&eg8DLUcltAyC{&HL{Dw$il%nf0oSL~cz zrApa+`uVSFHN>&WWJJhCf~DapVTdSSFuc3ut?G9b;p%Eb^Ng49Owo>N8$z^m!+t9GFa;_>@5uGp8(rS$oCc2L^`<(u z9y?^ZWSmhZn?L@NdUbI8*Ecr>GgYGsG-F!zsQvPxW@OMiht<^a^CU?J8n`A6I^+NZ zU-6)iFeR(S*^b0TlQjbI*~2Ujct(xBHT7#)YJLnTyF>HtIK3xQsdG`_U_!8#v`Wp&KTfyocy{gJUeYLAkE>jBf!ngphgH`*>(_ zACWTD7IjH*xH<35G+)}FG1%S1m->Ne*0xf=LT0mZX&X-a4(gifs{-$Uk|V(V9MO(|ogKK$Ymvt*a%TBSP9 zsWYxiqncaDdl5~5OUVO4 z$51{{p0{L|fmt6;+1pqi3pe&JdXKRS6@@$(`W?vxSP2nSQWP#^b8nm8afu`PyXK&O zO>aNO_1@PtaP?Pw%^uiLQ_kZbh=r!{Z4p3R-FHySwkAf&0eKLXFWz74*=VZ>9Nio(<(NoLT+uto&GVjhRzt(#5 z^yXu}y909&eO-}B&fyf-5o;3xVbNqt#r)xcuG+4-!UyG=l;0Cg1+)Y4Zz%9K`GbcJ zv9(T#-?l8@txhFRn2z7sL4;E220!CzTv&dthqyV;nj8ZMWZI1#R|U0fl`qip-I$q( zt3j(I%AQZa-Pk2Rds~5Cx%VTRtn>Y7hA;l0y_A9l=?_m`klgUuSN;**s~+2lktWf} zq>HgwEymWLB9^gOpC=OKD@^M;p<%7Yk)|zA->Bc2m#HyMs~-gKtNk|MWc|t{zL1pw zb~I5R7@Rv($4w8y;G=9bb<(yer8&M2vpca!%U$R%^JFq#4wM67NYXF?Umce~{qo~c=y5seijy3sz&Q-nP zzhdm!Si|5jm?x)sEtZiVL(%bOy*MJ-{IkTkrI12jb^pLFoRk#;rTro+20776;mmztLJZ?4rR`zofEK&D+$G* z_cv9N+dzBtkl$oKE@s(_MGW_oXn#Sm8SogtuI??ZqLXcyWF%kbh@ESsM+GvLvZE*p zwd9KE3<3WIl4%5Hgo+Sbqvg%(?HjmBx$Fw*wrJ@_YH;-p)ON^or!Mz$G(i%`Z&$ed zG?!x5X%f^8yE zQBTXAQ<~d^2LrLc=lyoXaQ?fB?m)FP6!QMGt>V&I_awLSR*elBn|kV=N&?}a(FQ46 z22zT!k4%Jk@WQdsC#-L#=l>-HAda6q(=80!k=P2J350#hU&Tv097m_`o7uY2JS^(AE&vzLVvgp;&}z#kt4ZMVh0FZLzE+mXPNnlT z!>O0bh6mYpO|B|flc4F0gAqQo)P?uqWf)%&s8vz&nZ~pg#eJTwp@+(A6!L2q2q}94 zb@90ch&~!w*%;En{L<9?srJe7xuV^)R`Trf)(yp$_L_=P=MYUUk6H%qH-*%AhF4^0ys1Mwzd)Ph%LkKq4T_KbryH5(pF048|Dyq3JRx^*2`;B8=#7p zf~AExV8h#QRx>)REEIpl<(qS2F-ob*2qPd;%ls&BR1p_dbW5B^IsI4irzGq&7_CVH z^Wbn7mo7!PNf=hCrP!KEutB73^Wu1}ZuJVH*7oFRN9D*H;T>_xqP&p^)R*@faqaaAW8mt;5QKcu(ZA|F2vd%k z0K#ECdly{Q*4X5Q+&PfcWaBhOe(Y%b$vAbHd|7=_L>W1590%G8$QFhK26)&x7nIX9uUPw<@D?PFyVafn zj+2ETNq|hltgJ1K7c0s!ioZ9&r26u-b1%Qt?7WmMP3;s%i`L57CuMakGA+c{P>-gY z=w15#w%fXITijj*jR;6zJqfwSSvGz$gq?;dZrY|f>jf5FQ&&|e! zq{p`V#26T(Pk;^c8c7<@kN+rM-2zu_h?|diWXpdH$joWeE!2mbMgo_5n}lf+hbsk2 zAb>r9-9?oRaU-<$vU1#6Gv~2%Q z9BD=uhTZ#4cZ-^IZ1U7^P&S-NqSA?Q7Ea{vFfm+wV? zc*r>aU2)xyW`Ty3+ACdhrfX{VcbIZdK*|%qJaPV%Ho?qbmgDmqd|9{_BXwx4-{uc!NPzr7D2yB;+jt>e zlxM`uh5$usLu`0SGeSV)H%FJ5Nn18vL@yejul7|*O&p6%$T2o4HhmPmm9|p0`H%A) z|Br)RHl#vp9;db|9wHY1@}FduAbQW7dN%>S~*=S3TDWpANFMQBo0^n^k6A z0()Kd!q=>JtGDQFH8FATlz{Rlk~CQ|{YXoojOvKBtFe6yr3rdx{v%MK=@E~gEk7q2 z^VY;^`!8WC^eCYveb@VI{#DNYdF*1zyk!H#5=sK!q>(R=73g4;(3gX=!9^Vd90 z4a1PDU0XyzFE=<_9x`uujyY`3yCJZSdZdWPLu!`~|8)iQmm^y9kY8CoP4d2}`7lrT z5@+pH@6GMFM(O+!TL-rH0tqi?^*^aC8;R1f+w2PWo{RU|2<5m}>TjA=R-?=^siw4o z$hW<+D2>68Ekq0qpc5IG!UI%xG5v<@-(~jfc9HgwN;S0<{m==-t=jaibz0>$SZf(pJ&DPOQ1gZ3SrUa3atBJ1YbQH;GR#EYN)UKKN_qxJb{OOm0+b7o;^ z>JXj!gUkQT8`|m;a^hSA@vLQ@MeyuBtZj=P(`-s}Og<!foQEPYD(A_GcokyEFn zT0h@#(GB>fLZH*mf+8b=35&ZA>$bKu`l4D8^D5S)^0{K9-syv?Yq{wDGG#owwla~Q z1n$kiC`QEcyq^bS@vL6;-~h-|W1guRbGhXEcJyFSXH(4B-wf8la2HSDlm9{^X%vz4 z{7KB_=N8E>dD&w7!afZLfu6B1Um2`kks`n=`K5>O%h`vO3n3mI;v@M zZcr4A)#j%i{U?nY5t>bRB;&2`BzjBLNVSyvaPD&IUCCPMN_C7$akHG~0HtiihmE7z z$b9YH_jrk|*O#%@Hu3~~3VztNR31}xuCl7SqA|jM^*nlCHP5fhqp_!lO%muKuGHo{ z2$=N9ALAWKy%73j-?W%}-$#?&R)q1hR~>(%txm3+xm0dIZgOEtgO~nG{hW$4Z$P?@ zqX8?2fmu&@<|-xe_a1+RhboWP8iNgy$1abTPRU{B9FGeq$sEzvU__@5GK_;WHy14x zcDwh%F)#&T8!n+HR*b17<9kEKj@QaV)cerrgBrU^YNWZUt8{6hh=Tbf?4|DbGS-u! z3Sxb;5_Nt{7Lb!ZPYHe=Y8XHk>h)UqkL^m`A@p`}ve`+@bxE5|Cs@<9Wo{2YJxv@D z9dCggGXgg~vVFp|gOx~_Ty1Jj5)-0RzImmr#x9y|jOhSEB7QF;#P+qj&`v*C%|s0Q z$?%luf|Mi-j(@=IKm857&fyXodmv&qtfCK#3O5t3lq+~s%fV<$ zRS-cl7ak85UYRl{gPI`aNl4*v$9b<&iIKg5qc~XNq*fo*t-~&I8?tBw+pco@U6>j% zSXEdK8e9Ui84jcO-8grAmtb-)|EFQRwl_-;yZ1NLKTpl*^Gls4O2#=4#vLj5jW2m( zv*A0D(ahmmg2`qipL@cc|7D4hjoF3__X~`o5Rt{7kGxUzd{v0u{FuF}VUVwCf0d9h z^tM38c*$I%5Awj}a|lVgz=uHUYqE|E?$0`hF<3fb7!iChutxv|hkyF*I5JB8%LF4( zwMZ_bT_4`}^-PSm?OBb)Y&`+hmqf5=B5bT7C)lxV7$ zSdd3Re)}sR94(?v$*U#FE)u?q8o}^a7Y-z}`lB@vE*61Wf>rOOqQ}p4{nh9VUqsbH zZ!eRW - -#include -#include -#include -#include -#include - -#include "all/example/include/ops_all.hpp" -#include "core/util/include/util.hpp" - -class NesterovATestTaskAll : public ::testing::TestWithParam { - protected: - void SetUp() override { - width = height = channels = -1; - std::string abs_path = ppc::util::GetAbsolutePath("all/example/data/pic_all.jpg"); - data = stbi_load(abs_path.c_str(), &width, &height, &channels, 0); - ASSERT_TRUE(data != nullptr) << "Failed to load image: " << stbi_failure_reason(); - img = std::vector(data, data + (static_cast(width) * height * channels)); - stbi_image_free(data); - - ASSERT_EQ(width, height); - } - - int width = -1, height = -1, channels = -1; - unsigned char* data = nullptr; - std::vector img; -}; - -TEST_P(NesterovATestTaskAll, MatmulFromPic) { - int divider = GetParam(); - const size_t k_count = (width + height) / divider; - - std::vector in(k_count * k_count, 0); - for (size_t i = 0; i < k_count; i++) { - in[(i * k_count) + i] = 1; - } - - nesterov_a_test_task_all::TestTaskALL test_task_all(in); - ASSERT_TRUE(test_task_all.Validation()); - test_task_all.PreProcessing(); - test_task_all.Run(); - test_task_all.PostProcessing(); - EXPECT_EQ(in, test_task_all.Get()); -} - -TEST_P(NesterovATestTaskAll, MatMulUtilFromPic) { - int divider = GetParam(); - const size_t k_count = (width + height) / divider; - - std::vector in(k_count * k_count, 0); - for (size_t i = 0; i < k_count; i++) { - in[(i * k_count) + i] = 1; - } - std::vector out(k_count * k_count, 0); - nesterov_a_test_task_all::MatMul(in, static_cast(k_count), out); - - EXPECT_EQ(in, out); -} - -TEST_P(NesterovATestTaskAll, MatMulTBBUtilFromPic) { - int divider = GetParam(); - const size_t k_count = (width + height) / divider; - - std::vector in(k_count * k_count, 0); - for (size_t i = 0; i < k_count; i++) { - in[(i * k_count) + i] = 1; - } - std::vector out(k_count * k_count, 0); - nesterov_a_test_task_all::MatMulTBB(in, static_cast(k_count), out); - - EXPECT_EQ(in, out); -} - -INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovATestTaskAll, ::testing::Values(5, 10)); diff --git a/tasks/all/example/include/ops_all.hpp b/tasks/all/example/include/ops_all.hpp deleted file mode 100644 index fab463ee8..000000000 --- a/tasks/all/example/include/ops_all.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include -#include - -#include "core/task/include/task.hpp" - -namespace nesterov_a_test_task_all { - -void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_vec); -void MatMulTBB(const std::vector &in_vec, int rc_size, std::vector &out_vec); - -class TestTaskALL : public ppc::core::Task { - public: - explicit TestTaskALL(const std::vector &in) : input_(in) {} - bool ValidationImpl() override; - bool PreProcessingImpl() override; - bool RunImpl() override; - bool PostProcessingImpl() override; - std::vector Get(); - - private: - std::vector input_, output_; - int rc_size_{}; -}; - -} // namespace nesterov_a_test_task_all diff --git a/tasks/all/example/perf_tests/main.cpp b/tasks/all/example/perf_tests/main.cpp deleted file mode 100644 index 226b57fb8..000000000 --- a/tasks/all/example/perf_tests/main.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include - -#include -#include -#include -#include - -#include "all/example/include/ops_all.hpp" -#include "core/perf/include/perf.hpp" -#include "core/util/include/util.hpp" - -class NesterovAllRunTest : public ::testing::TestWithParam { - protected: - static constexpr size_t kCount = 400; - std::vector input_data; - - void SetUp() override { - input_data.assign(kCount * kCount, 0); - for (size_t i = 0; i < kCount; ++i) { - input_data[(i * kCount) + i] = 1; - } - } - - void ExecuteTest(ppc::core::PerfResults::TypeOfRunning mode) { - auto task = std::make_shared(input_data); - ppc::core::Perf perf(task); - - ppc::core::PerfAttr perf_attr; - const auto t0 = std::chrono::high_resolution_clock::now(); - perf_attr.current_timer = [&] { - auto now = std::chrono::high_resolution_clock::now(); - auto ns = std::chrono::duration_cast(now - t0).count(); - return static_cast(ns) * 1e-9; - }; - - if (mode == ppc::core::PerfResults::TypeOfRunning::kPipeline) { - perf.PipelineRun(perf_attr); - } else { - perf.TaskRun(perf_attr); - } - - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - if (rank == 0) { - perf.PrintPerfStatistic(); - } - - ASSERT_EQ(input_data, task->Get()); - } -}; - -TEST_P(NesterovAllRunTest, RunModes) { ExecuteTest(GetParam()); } - -INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, NesterovAllRunTest, - ::testing::Values(ppc::core::PerfResults::TypeOfRunning::kPipeline, - ppc::core::PerfResults::TypeOfRunning::kTaskRun)); diff --git a/tasks/all/example/src/ops_all.cpp b/tasks/all/example/src/ops_all.cpp deleted file mode 100644 index eecb816e2..000000000 --- a/tasks/all/example/src/ops_all.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "all/example/include/ops_all.hpp" - -#include - -#include -#include -#include -#include -#include - -#include "core/util/include/util.hpp" -#include "oneapi/tbb/parallel_for.h" - -void nesterov_a_test_task_all::MatMul(const std::vector &in_vec, int rc_size, std::vector &out_vec) { - for (int i = 0; i < rc_size; ++i) { - for (int j = 0; j < rc_size; ++j) { - out_vec[(i * rc_size) + j] = 0; - for (int k = 0; k < rc_size; ++k) { - out_vec[(i * rc_size) + j] += in_vec[(i * rc_size) + k] * in_vec[(k * rc_size) + j]; - } - } - } -} - -void nesterov_a_test_task_all::MatMulTBB(const std::vector &in_vec, int rc_size, std::vector &out_vec) { - tbb::parallel_for(0, ppc::util::GetPPCNumThreads(), [&](int i) { MatMul(in_vec, rc_size - i, out_vec); }); - MatMul(in_vec, rc_size, out_vec); -} - -bool nesterov_a_test_task_all::TestTaskALL::ValidationImpl() { - auto sqrt_size = static_cast(std::sqrt(input_.size())); - return sqrt_size * sqrt_size == static_cast(input_.size()); -} - -bool nesterov_a_test_task_all::TestTaskALL::PreProcessingImpl() { - // Init value for input and output - rc_size_ = static_cast(std::sqrt(input_.size())); - output_ = std::vector(input_.size(), 0); - return true; -} - -bool nesterov_a_test_task_all::TestTaskALL::RunImpl() { - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - if (rank == 0) { -#pragma omp parallel default(none) - { -#pragma omp critical - MatMul(input_, rc_size_, output_); - } - } else { - MatMulTBB(input_, rc_size_, output_); - } - - const int num_threads = ppc::util::GetPPCNumThreads(); - std::vector threads(num_threads); - for (int i = 0; i < num_threads; i++) { - threads[i] = std::thread(MatMul, std::cref(input_), rc_size_, std::ref(output_)); - threads[i].join(); - } - - MPI_Barrier(MPI_COMM_WORLD); - return true; -} - -bool nesterov_a_test_task_all::TestTaskALL::PostProcessingImpl() { return true; } - -std::vector nesterov_a_test_task_all::TestTaskALL::Get() { return output_; } diff --git a/tasks/all/runner.cpp b/tasks/all/runner.cpp deleted file mode 100644 index 378c34a4c..000000000 --- a/tasks/all/runner.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include - -#include "core/util/include/util.hpp" -#include "oneapi/tbb/global_control.h" - -class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { - public: - UnreadMessagesDetector() = default; - - void OnTestEnd(const ::testing::TestInfo& /*test_info*/) override { - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - - MPI_Barrier(MPI_COMM_WORLD); - - int flag = -1; - MPI_Status status; - - MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status); - - if (flag != 0) { - fprintf( - stderr, - "[ PROCESS %d ] [ FAILED ] %s.%s: MPI message queue has an unread message from process %d with tag %d\n", - rank, "test_suite_name", "test_name", status.MPI_SOURCE, status.MPI_TAG); - MPI_Finalize(); - std::abort(); - } - - MPI_Barrier(MPI_COMM_WORLD); - } - - private: -}; - -class WorkerTestFailurePrinter : public ::testing::EmptyTestEventListener { - public: - explicit WorkerTestFailurePrinter(std::shared_ptr<::testing::TestEventListener> base) : base_(std::move(base)) {} - - void OnTestEnd(const ::testing::TestInfo& test_info) override { - if (test_info.result()->Passed()) { - return; - } - PrintProcessRank(); - base_->OnTestEnd(test_info); - } - - void OnTestPartResult(const ::testing::TestPartResult& test_part_result) override { - if (test_part_result.passed() || test_part_result.skipped()) { - return; - } - PrintProcessRank(); - base_->OnTestPartResult(test_part_result); - } - - private: - static void PrintProcessRank() { - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - printf(" [ PROCESS %d ] ", rank); - } - - std::shared_ptr<::testing::TestEventListener> base_; -}; - -int main(int argc, char** argv) { - MPI_Init(&argc, &argv); - - // Limit the number of threads in TBB - tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetPPCNumThreads()); - - ::testing::InitGoogleTest(&argc, argv); - - auto& listeners = ::testing::UnitTest::GetInstance()->listeners(); - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - if (rank != 0 && (argc < 2 || argv[1] != std::string("--print-workers"))) { - auto* listener = listeners.Release(listeners.default_result_printer()); - listeners.Append(new WorkerTestFailurePrinter(std::shared_ptr<::testing::TestEventListener>(listener))); - } - listeners.Append(new UnreadMessagesDetector()); - auto status = RUN_ALL_TESTS(); - - MPI_Finalize(); - return status; -} diff --git a/tasks-1/example/CMakeLists.txt b/tasks/example/CMakeLists.txt similarity index 100% rename from tasks-1/example/CMakeLists.txt rename to tasks/example/CMakeLists.txt diff --git a/tasks-1/example/all/include/ops_all.hpp b/tasks/example/all/include/ops_all.hpp similarity index 100% rename from tasks-1/example/all/include/ops_all.hpp rename to tasks/example/all/include/ops_all.hpp diff --git a/tasks-1/example/all/src/ops_all.cpp b/tasks/example/all/src/ops_all.cpp similarity index 100% rename from tasks-1/example/all/src/ops_all.cpp rename to tasks/example/all/src/ops_all.cpp diff --git a/tasks-1/example/mpi/include/ops_mpi.hpp b/tasks/example/mpi/include/ops_mpi.hpp similarity index 100% rename from tasks-1/example/mpi/include/ops_mpi.hpp rename to tasks/example/mpi/include/ops_mpi.hpp diff --git a/tasks-1/example/mpi/src/ops_mpi.cpp b/tasks/example/mpi/src/ops_mpi.cpp similarity index 100% rename from tasks-1/example/mpi/src/ops_mpi.cpp rename to tasks/example/mpi/src/ops_mpi.cpp diff --git a/tasks-1/example/omp/include/ops_omp.hpp b/tasks/example/omp/include/ops_omp.hpp similarity index 100% rename from tasks-1/example/omp/include/ops_omp.hpp rename to tasks/example/omp/include/ops_omp.hpp diff --git a/tasks-1/example/omp/src/ops_omp.cpp b/tasks/example/omp/src/ops_omp.cpp similarity index 100% rename from tasks-1/example/omp/src/ops_omp.cpp rename to tasks/example/omp/src/ops_omp.cpp diff --git a/tasks-1/example/seq/include/ops_seq.hpp b/tasks/example/seq/include/ops_seq.hpp similarity index 100% rename from tasks-1/example/seq/include/ops_seq.hpp rename to tasks/example/seq/include/ops_seq.hpp diff --git a/tasks-1/example/seq/src/ops_seq.cpp b/tasks/example/seq/src/ops_seq.cpp similarity index 100% rename from tasks-1/example/seq/src/ops_seq.cpp rename to tasks/example/seq/src/ops_seq.cpp diff --git a/tasks-1/example/stl/include/ops_stl.hpp b/tasks/example/stl/include/ops_stl.hpp similarity index 100% rename from tasks-1/example/stl/include/ops_stl.hpp rename to tasks/example/stl/include/ops_stl.hpp diff --git a/tasks-1/example/stl/src/ops_stl.cpp b/tasks/example/stl/src/ops_stl.cpp similarity index 100% rename from tasks-1/example/stl/src/ops_stl.cpp rename to tasks/example/stl/src/ops_stl.cpp diff --git a/tasks-1/example/tbb/include/ops_tbb.hpp b/tasks/example/tbb/include/ops_tbb.hpp similarity index 100% rename from tasks-1/example/tbb/include/ops_tbb.hpp rename to tasks/example/tbb/include/ops_tbb.hpp diff --git a/tasks-1/example/tbb/src/ops_tbb.cpp b/tasks/example/tbb/src/ops_tbb.cpp similarity index 100% rename from tasks-1/example/tbb/src/ops_tbb.cpp rename to tasks/example/tbb/src/ops_tbb.cpp diff --git a/tasks-1/example/tests/data/pic_all.jpg b/tasks/example/tests/data/pic_all.jpg similarity index 100% rename from tasks-1/example/tests/data/pic_all.jpg rename to tasks/example/tests/data/pic_all.jpg diff --git a/tasks-1/example/tests/func_tests/main.cpp b/tasks/example/tests/func_tests/main.cpp similarity index 100% rename from tasks-1/example/tests/func_tests/main.cpp rename to tasks/example/tests/func_tests/main.cpp diff --git a/tasks-1/example/tests/perf_tests/main.cpp b/tasks/example/tests/perf_tests/main.cpp similarity index 100% rename from tasks-1/example/tests/perf_tests/main.cpp rename to tasks/example/tests/perf_tests/main.cpp diff --git a/tasks-1/example/tests/runner.cpp b/tasks/example/tests/runner.cpp similarity index 100% rename from tasks-1/example/tests/runner.cpp rename to tasks/example/tests/runner.cpp diff --git a/tasks/mpi/example/data/test.txt b/tasks/mpi/example/data/test.txt deleted file mode 100644 index 105d7d9ad..000000000 --- a/tasks/mpi/example/data/test.txt +++ /dev/null @@ -1 +0,0 @@ -100 \ No newline at end of file diff --git a/tasks/mpi/example/func_tests/main.cpp b/tasks/mpi/example/func_tests/main.cpp deleted file mode 100644 index 493083f03..000000000 --- a/tasks/mpi/example/func_tests/main.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include - -#include "core/util/include/util.hpp" -#include "mpi/example/include/ops_mpi.hpp" - -class NesterovATestTaskMPI : public ::testing::TestWithParam { - protected: - void SetUp() override { - std::ifstream test_file(ppc::util::GetAbsolutePath("mpi/example/data/test.txt")); - ASSERT_TRUE(test_file.is_open()) << "Failed to open input file"; - std::string line; - std::getline(test_file, line); - test_file.close(); - base_count = std::stoi(line); - } - - [[nodiscard]] size_t GetCount() const { return static_cast(base_count * GetParam()); } - - int base_count = 0; -}; - -TEST_P(NesterovATestTaskMPI, MatmulFromFile) { - const size_t count = GetCount(); - - std::vector in(count * count, 0); - for (size_t i = 0; i < count; ++i) { - in[(i * count) + i] = 1; - } - - nesterov_a_test_task_mpi::TestTaskMPI test_task_mpi(in); - ASSERT_TRUE(test_task_mpi.Validation()); - test_task_mpi.PreProcessing(); - test_task_mpi.Run(); - test_task_mpi.PostProcessing(); - - EXPECT_EQ(in, test_task_mpi.Get()); -} - -TEST_P(NesterovATestTaskMPI, MultiplyRowMajorUtilTestFromFile) { - const size_t count = GetCount(); - - std::vector in(count * count, 0); - for (size_t i = 0; i < count; ++i) { - in[(i * count) + i] = 1; - } - - std::vector out(count * count, 0); - nesterov_a_test_task_mpi::MultiplyRowMajor(in, out, static_cast(count)); - - EXPECT_EQ(in, out); -} - -TEST_P(NesterovATestTaskMPI, MultiplyColumnMajorUtilTestFromFile) { - const size_t count = GetCount(); - - std::vector in(count * count, 0); - for (size_t i = 0; i < count; ++i) { - in[(i * count) + i] = 1; - } - - std::vector out(count * count, 0); - nesterov_a_test_task_mpi::MultiplyColumnMajor(in, out, static_cast(count)); - - EXPECT_EQ(in, out); -} - -INSTANTIATE_TEST_SUITE_P_NOLINT(FileMatrixTestsMPI, NesterovATestTaskMPI, ::testing::Values(0.5, 1.0)); diff --git a/tasks/mpi/example/include/ops_mpi.hpp b/tasks/mpi/example/include/ops_mpi.hpp deleted file mode 100644 index 31b1f0424..000000000 --- a/tasks/mpi/example/include/ops_mpi.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include -#include - -#include "core/task/include/task.hpp" - -namespace nesterov_a_test_task_mpi { - -void MultiplyRowMajor(const std::vector &in, std::vector &out, int rc_size); -void MultiplyColumnMajor(const std::vector &in, std::vector &out, int rc_size); - -class TestTaskMPI : public ppc::core::Task { - public: - explicit TestTaskMPI(const std::vector &in) : input_(in) {} - bool ValidationImpl() override; - bool PreProcessingImpl() override; - bool RunImpl() override; - bool PostProcessingImpl() override; - std::vector Get(); - - private: - std::vector input_, output_; - int rc_size_{}; - - void MultiplyMatrixBasedOnRank(); -}; - -} // namespace nesterov_a_test_task_mpi diff --git a/tasks/mpi/example/perf_tests/main.cpp b/tasks/mpi/example/perf_tests/main.cpp deleted file mode 100644 index ec70c79df..000000000 --- a/tasks/mpi/example/perf_tests/main.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include - -#include "core/perf/include/perf.hpp" -#include "core/util/include/util.hpp" -#include "mpi/example/include/ops_mpi.hpp" - -class NesterovATaskMPITest : public ::testing::TestWithParam { - protected: - static void RunTest(ppc::core::PerfResults::TypeOfRunning mode) { - constexpr size_t kCount = 500; - - // Create data - std::vector in(kCount * kCount, 0); - for (size_t i = 0; i < kCount; i++) { - in[(i * kCount) + i] = 1; - } - - // Create Task - auto test_task_mpi = std::make_shared(in); - - // Create Perf analyzer - ppc::core::Perf perf_analyzer(test_task_mpi); - - // Create Perf attributes - ppc::core::PerfAttr perf_attr; - const auto t0 = std::chrono::high_resolution_clock::now(); - perf_attr.current_timer = [&] { - auto current_time_point = std::chrono::high_resolution_clock::now(); - auto duration = std::chrono::duration_cast(current_time_point - t0).count(); - return static_cast(duration) * 1e-9; - }; - - if (mode == ppc::core::PerfResults::TypeOfRunning::kPipeline) { - perf_analyzer.PipelineRun(perf_attr); - } else { - perf_analyzer.TaskRun(perf_attr); - } - - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - if (rank == 0) { - perf_analyzer.PrintPerfStatistic(); - } - - ASSERT_EQ(in, test_task_mpi->Get()); - } -}; - -TEST_P(NesterovATaskMPITest, RunModes) { RunTest(GetParam()); } - -INSTANTIATE_TEST_SUITE_P_NOLINT(NesterovATests, NesterovATaskMPITest, - ::testing::Values(ppc::core::PerfResults::TypeOfRunning::kPipeline, - ppc::core::PerfResults::TypeOfRunning::kTaskRun)); diff --git a/tasks/mpi/example/src/ops_mpi.cpp b/tasks/mpi/example/src/ops_mpi.cpp deleted file mode 100644 index 43821a5d5..000000000 --- a/tasks/mpi/example/src/ops_mpi.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "mpi/example/include/ops_mpi.hpp" - -#include - -#include -#include -#include - -bool nesterov_a_test_task_mpi::TestTaskMPI::ValidationImpl() { - auto sqrt_size = static_cast(std::sqrt(input_.size())); - return sqrt_size * sqrt_size == static_cast(input_.size()); -} - -bool nesterov_a_test_task_mpi::TestTaskMPI::PreProcessingImpl() { - // Init value for input and output - rc_size_ = static_cast(std::sqrt(input_.size())); - output_ = std::vector(input_.size(), 0); - return true; -} - -bool nesterov_a_test_task_mpi::TestTaskMPI::RunImpl() { - MultiplyMatrixBasedOnRank(); - return true; -} - -void nesterov_a_test_task_mpi::TestTaskMPI::MultiplyMatrixBasedOnRank() { - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - - if (rank == 0) { - MultiplyRowMajor(input_, output_, rc_size_); - } else { - MultiplyColumnMajor(input_, output_, rc_size_); - } - MPI_Barrier(MPI_COMM_WORLD); -} - -void nesterov_a_test_task_mpi::MultiplyRowMajor(const std::vector &in, std::vector &out, int rc_size) { - for (int i = 0; i < rc_size; ++i) { - for (int j = 0; j < rc_size; ++j) { - for (int k = 0; k < rc_size; ++k) { - out[(i * rc_size) + j] += in[(i * rc_size) + k] * in[(k * rc_size) + j]; - } - } - } -} - -void nesterov_a_test_task_mpi::MultiplyColumnMajor(const std::vector &in, std::vector &out, int rc_size) { - for (int j = 0; j < rc_size; ++j) { - for (int k = 0; k < rc_size; ++k) { - for (int i = 0; i < rc_size; ++i) { - out[(i * rc_size) + j] += in[(i * rc_size) + k] * in[(k * rc_size) + j]; - } - } - } -} - -bool nesterov_a_test_task_mpi::TestTaskMPI::PostProcessingImpl() { return true; } - -std::vector nesterov_a_test_task_mpi::TestTaskMPI::Get() { return output_; } diff --git a/tasks/mpi/runner.cpp b/tasks/mpi/runner.cpp deleted file mode 100644 index 04bd520af..000000000 --- a/tasks/mpi/runner.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include - -class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { - public: - UnreadMessagesDetector() = default; - - void OnTestEnd(const ::testing::TestInfo& /*test_info*/) override { - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - - MPI_Barrier(MPI_COMM_WORLD); - - int flag = -1; - MPI_Status status; - - MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status); - - if (flag != 0) { - fprintf( - stderr, - "[ PROCESS %d ] [ FAILED ] %s.%s: MPI message queue has an unread message from process %d with tag %d\n", - rank, "test_suite_name", "test_name", status.MPI_SOURCE, status.MPI_TAG); - MPI_Finalize(); - std::abort(); - } - - MPI_Barrier(MPI_COMM_WORLD); - } - - private: -}; - -class WorkerTestFailurePrinter : public ::testing::EmptyTestEventListener { - public: - explicit WorkerTestFailurePrinter(std::shared_ptr<::testing::TestEventListener> base) : base_(std::move(base)) {} - - void OnTestEnd(const ::testing::TestInfo& test_info) override { - if (test_info.result()->Passed()) { - return; - } - PrintProcessRank(); - base_->OnTestEnd(test_info); - } - - void OnTestPartResult(const ::testing::TestPartResult& test_part_result) override { - if (test_part_result.passed() || test_part_result.skipped()) { - return; - } - PrintProcessRank(); - base_->OnTestPartResult(test_part_result); - } - - private: - static void PrintProcessRank() { - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - printf(" [ PROCESS %d ] ", rank); - } - - std::shared_ptr<::testing::TestEventListener> base_; -}; - -int main(int argc, char** argv) { - MPI_Init(&argc, &argv); - - ::testing::InitGoogleTest(&argc, argv); - - auto& listeners = ::testing::UnitTest::GetInstance()->listeners(); - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - if (rank != 0 && (argc < 2 || argv[1] != std::string("--print-workers"))) { - auto* listener = listeners.Release(listeners.default_result_printer()); - listeners.Append(new WorkerTestFailurePrinter(std::shared_ptr<::testing::TestEventListener>(listener))); - } - listeners.Append(new UnreadMessagesDetector()); - auto status = RUN_ALL_TESTS(); - - MPI_Finalize(); - return status; -} diff --git a/tasks/omp/example/data/test.txt b/tasks/omp/example/data/test.txt deleted file mode 100644 index 105d7d9ad..000000000 --- a/tasks/omp/example/data/test.txt +++ /dev/null @@ -1 +0,0 @@ -100 \ No newline at end of file diff --git a/tasks/omp/example/func_tests/main.cpp b/tasks/omp/example/func_tests/main.cpp deleted file mode 100644 index 278b5d479..000000000 --- a/tasks/omp/example/func_tests/main.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include - -#include "core/task/include/task.hpp" -#include "core/util/include/util.hpp" -#include "omp/example/include/ops_omp.hpp" - -class NesterovATestTaskOMP : public ::testing::TestWithParam { - protected: - void SetUp() override { - std::ifstream test_file(ppc::util::GetAbsolutePath("omp/example/data/test.txt")); - ASSERT_TRUE(test_file.is_open()) << "Failed to open input file"; - std::string line; - std::getline(test_file, line); - test_file.close(); - base_count = std::stoi(line); - } - - [[nodiscard]] size_t GetCount() const { return static_cast(base_count * GetParam()); } - - int base_count = 0; -}; - -TEST_P(NesterovATestTaskOMP, MatmulFromFile) { - const size_t count = GetCount(); - - std::vector in(count * count, 0); - for (size_t i = 0; i < count; ++i) { - in[(i * count) + i] = 1; - } - - nesterov_a_test_task_omp::TestTaskOpenMP test_task_omp(in); - ASSERT_TRUE(test_task_omp.Validation()); - test_task_omp.PreProcessing(); - test_task_omp.Run(); - test_task_omp.PostProcessing(); - - EXPECT_EQ(in, test_task_omp.Get()); -} - -INSTANTIATE_TEST_SUITE_P_NOLINT(FileMatrixTestsOMP, NesterovATestTaskOMP, ::testing::Values(0.5, 1.0)); diff --git a/tasks/omp/example/include/ops_omp.hpp b/tasks/omp/example/include/ops_omp.hpp deleted file mode 100644 index 87209c39e..000000000 --- a/tasks/omp/example/include/ops_omp.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include - -#include "core/task/include/task.hpp" - -namespace nesterov_a_test_task_omp { - -class TestTaskOpenMP : public ppc::core::Task { - public: - explicit TestTaskOpenMP(const std::vector& in) : input_(in) {} - bool ValidationImpl() override; - bool PreProcessingImpl() override; - bool RunImpl() override; - bool PostProcessingImpl() override; - std::vector Get(); - - private: - std::vector input_, output_; - int rc_size_{}; -}; - -} // namespace nesterov_a_test_task_omp \ No newline at end of file diff --git a/tasks/omp/example/perf_tests/main.cpp b/tasks/omp/example/perf_tests/main.cpp deleted file mode 100644 index 7b2db214e..000000000 --- a/tasks/omp/example/perf_tests/main.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include - -#include -#include -#include -#include -#include - -#include "core/perf/include/perf.hpp" -#include "core/util/include/util.hpp" -#include "omp/example/include/ops_omp.hpp" - -class NesterovTaskOMPTest : public ::testing::TestWithParam { - protected: - static void RunTest(ppc::core::PerfResults::TypeOfRunning mode) { - constexpr size_t kCount = 300; - - // Create data - std::vector in(kCount * kCount, 0); - for (size_t i = 0; i < kCount; i++) { - in[(i * kCount) + i] = 1; - } - - // Create Task - auto test_task_omp = std::make_shared(in); - - // Create Perf analyzer - ppc::core::Perf perf_analyzer(test_task_omp); - - // Create Perf attributes - ppc::core::PerfAttr perf_attr; - const auto t0 = std::chrono::high_resolution_clock::now(); - perf_attr.current_timer = [&] { - auto current_time_point = std::chrono::high_resolution_clock::now(); - auto duration = std::chrono::duration_cast(current_time_point - t0).count(); - return static_cast(duration) * 1e-9; - }; - - if (mode == ppc::core::PerfResults::TypeOfRunning::kPipeline) { - perf_analyzer.PipelineRun(perf_attr); - } else { - perf_analyzer.TaskRun(perf_attr); - } - - perf_analyzer.PrintPerfStatistic(); - - ASSERT_EQ(in, test_task_omp->Get()); - } -}; - -TEST_P(NesterovTaskOMPTest, RunModes) { RunTest(GetParam()); } - -INSTANTIATE_TEST_SUITE_P_NOLINT(NesterovOMPTests, NesterovTaskOMPTest, - ::testing::Values(ppc::core::PerfResults::TypeOfRunning::kPipeline, - ppc::core::PerfResults::TypeOfRunning::kTaskRun)); diff --git a/tasks/omp/example/src/ops_omp.cpp b/tasks/omp/example/src/ops_omp.cpp deleted file mode 100644 index 380be6aa8..000000000 --- a/tasks/omp/example/src/ops_omp.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "omp/example/include/ops_omp.hpp" - -#include -#include -#include - -bool nesterov_a_test_task_omp::TestTaskOpenMP::ValidationImpl() { - auto sqrt_size = static_cast(std::sqrt(input_.size())); - return sqrt_size * sqrt_size == static_cast(input_.size()); -} - -bool nesterov_a_test_task_omp::TestTaskOpenMP::PreProcessingImpl() { - rc_size_ = static_cast(std::sqrt(input_.size())); - output_ = std::vector(input_.size(), 0); - return true; -} - -bool nesterov_a_test_task_omp::TestTaskOpenMP::RunImpl() { -#pragma omp parallel default(none) - { -#pragma omp critical - { - // Multiply matrices - for (int i = 0; i < rc_size_; ++i) { - for (int j = 0; j < rc_size_; ++j) { - output_[(i * rc_size_) + j] = 0; - for (int k = 0; k < rc_size_; ++k) { - output_[(i * rc_size_) + j] += input_[(i * rc_size_) + k] * input_[(k * rc_size_) + j]; - } - } - } - } - } - return true; -} - -bool nesterov_a_test_task_omp::TestTaskOpenMP::PostProcessingImpl() { return true; } - -std::vector nesterov_a_test_task_omp::TestTaskOpenMP::Get() { return output_; } diff --git a/tasks/omp/runner.cpp b/tasks/omp/runner.cpp deleted file mode 100644 index 4d820af77..000000000 --- a/tasks/omp/runner.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/tasks/seq/example/data/test.txt b/tasks/seq/example/data/test.txt deleted file mode 100644 index 105d7d9ad..000000000 --- a/tasks/seq/example/data/test.txt +++ /dev/null @@ -1 +0,0 @@ -100 \ No newline at end of file diff --git a/tasks/seq/example/func_tests/main.cpp b/tasks/seq/example/func_tests/main.cpp deleted file mode 100644 index cf196f774..000000000 --- a/tasks/seq/example/func_tests/main.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include - -#include "core/task/include/task.hpp" -#include "core/util/include/util.hpp" -#include "seq/example/include/ops_seq.hpp" - -class NesterovATestTaskSeq : public ::testing::TestWithParam { - protected: - void SetUp() override { - std::ifstream test_file(ppc::util::GetAbsolutePath("seq/example/data/test.txt")); - ASSERT_TRUE(test_file.is_open()) << "Failed to open input file"; - std::string line; - std::getline(test_file, line); - test_file.close(); - base_count = std::stoi(line); - } - - [[nodiscard]] size_t GetCount() const { return static_cast(base_count * GetParam()); } - - int base_count = 0; -}; - -TEST_P(NesterovATestTaskSeq, MatmulFromFile) { - const size_t count = GetCount(); - - std::vector in(count * count, 0); - for (size_t i = 0; i < count; i++) { - in[(i * count) + i] = 1; - } - - nesterov_a_test_task_seq::TestTaskSequential test_task_sequential(in); - ASSERT_TRUE(test_task_sequential.Validation()); - test_task_sequential.PreProcessing(); - test_task_sequential.Run(); - test_task_sequential.PostProcessing(); - EXPECT_EQ(in, test_task_sequential.Get()); -} - -INSTANTIATE_TEST_SUITE_P_NOLINT(FileMatrixTests, NesterovATestTaskSeq, ::testing::Values(0.5, 1.0)); diff --git a/tasks/seq/example/include/ops_seq.hpp b/tasks/seq/example/include/ops_seq.hpp deleted file mode 100644 index f03fc7fb8..000000000 --- a/tasks/seq/example/include/ops_seq.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include - -#include "core/task/include/task.hpp" - -namespace nesterov_a_test_task_seq { - -class TestTaskSequential : public ppc::core::Task { - public: - explicit TestTaskSequential(const std::vector& in) : input_(in) {} - bool ValidationImpl() override; - bool PreProcessingImpl() override; - bool RunImpl() override; - bool PostProcessingImpl() override; - std::vector Get(); - - private: - std::vector input_, output_; - int rc_size_{}; -}; - -} // namespace nesterov_a_test_task_seq \ No newline at end of file diff --git a/tasks/seq/example/perf_tests/main.cpp b/tasks/seq/example/perf_tests/main.cpp deleted file mode 100644 index cfc12fc06..000000000 --- a/tasks/seq/example/perf_tests/main.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include - -#include -#include -#include -#include -#include - -#include "core/perf/include/perf.hpp" -#include "core/util/include/util.hpp" -#include "seq/example/include/ops_seq.hpp" - -class NesterovTaskSeqTest : public ::testing::TestWithParam { - protected: - static void RunTest(ppc::core::PerfResults::TypeOfRunning mode) { - constexpr size_t kCount = 500; - - // Create data - std::vector in(kCount * kCount, 0); - for (size_t i = 0; i < kCount; i++) { - in[(i * kCount) + i] = 1; - } - - // Create Task - auto test_task_sequential = std::make_shared(in); - - // Create Perf analyzer - ppc::core::Perf perf_analyzer(test_task_sequential); - - // Create Perf attributes - ppc::core::PerfAttr perf_attr; - const auto t0 = std::chrono::high_resolution_clock::now(); - perf_attr.current_timer = [&] { - auto current_time_point = std::chrono::high_resolution_clock::now(); - auto duration = std::chrono::duration_cast(current_time_point - t0).count(); - return static_cast(duration) * 1e-9; - }; - - if (mode == ppc::core::PerfResults::TypeOfRunning::kPipeline) { - perf_analyzer.PipelineRun(perf_attr); - } else { - perf_analyzer.TaskRun(perf_attr); - } - - perf_analyzer.PrintPerfStatistic(); - - ASSERT_EQ(in, test_task_sequential->Get()); - } -}; - -TEST_P(NesterovTaskSeqTest, RunModes) { RunTest(GetParam()); } - -INSTANTIATE_TEST_SUITE_P_NOLINT(NesterovSeqTests, NesterovTaskSeqTest, - ::testing::Values(ppc::core::PerfResults::TypeOfRunning::kPipeline, - ppc::core::PerfResults::TypeOfRunning::kTaskRun)); diff --git a/tasks/seq/example/src/ops_seq.cpp b/tasks/seq/example/src/ops_seq.cpp deleted file mode 100644 index 40df2e006..000000000 --- a/tasks/seq/example/src/ops_seq.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "seq/example/include/ops_seq.hpp" - -#include -#include -#include - -bool nesterov_a_test_task_seq::TestTaskSequential::ValidationImpl() { - auto sqrt_size = static_cast(std::sqrt(input_.size())); - return sqrt_size * sqrt_size == static_cast(input_.size()); -} - -bool nesterov_a_test_task_seq::TestTaskSequential::PreProcessingImpl() { - rc_size_ = static_cast(std::sqrt(input_.size())); - output_ = std::vector(input_.size(), 0); - return true; -} - -bool nesterov_a_test_task_seq::TestTaskSequential::RunImpl() { - // Multiply matrices - for (int i = 0; i < rc_size_; ++i) { - for (int j = 0; j < rc_size_; ++j) { - for (int k = 0; k < rc_size_; ++k) { - output_[(i * rc_size_) + j] += input_[(i * rc_size_) + k] * input_[(k * rc_size_) + j]; - } - } - } - return true; -} - -bool nesterov_a_test_task_seq::TestTaskSequential::PostProcessingImpl() { return true; } - -std::vector nesterov_a_test_task_seq::TestTaskSequential::Get() { return output_; } diff --git a/tasks/seq/runner.cpp b/tasks/seq/runner.cpp deleted file mode 100644 index 4d820af77..000000000 --- a/tasks/seq/runner.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/tasks/stl/example/data/test.txt b/tasks/stl/example/data/test.txt deleted file mode 100644 index 105d7d9ad..000000000 --- a/tasks/stl/example/data/test.txt +++ /dev/null @@ -1 +0,0 @@ -100 \ No newline at end of file diff --git a/tasks/stl/example/func_tests/main.cpp b/tasks/stl/example/func_tests/main.cpp deleted file mode 100644 index 0460c3a2c..000000000 --- a/tasks/stl/example/func_tests/main.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include - -#include "core/task/include/task.hpp" -#include "core/util/include/util.hpp" -#include "stl/example/include/ops_stl.hpp" - -class NesterovATestTaskSTL : public ::testing::TestWithParam { - protected: - void SetUp() override { - std::ifstream test_file(ppc::util::GetAbsolutePath("stl/example/data/test.txt")); - ASSERT_TRUE(test_file.is_open()) << "Failed to open input file"; - std::string line; - std::getline(test_file, line); - test_file.close(); - base_count = std::stoi(line); - } - - [[nodiscard]] size_t GetCount() const { return static_cast(base_count * GetParam()); } - - int base_count = 0; -}; - -TEST_P(NesterovATestTaskSTL, MatmulFromFile) { - const size_t count = GetCount(); - - std::vector in(count * count, 0); - for (size_t i = 0; i < count; ++i) { - in[(i * count) + i] = 1; - } - - nesterov_a_test_task_stl::TestTaskSTL test_task_stl(in); - ASSERT_TRUE(test_task_stl.Validation()); - test_task_stl.PreProcessing(); - test_task_stl.Run(); - test_task_stl.PostProcessing(); - - EXPECT_EQ(in, test_task_stl.Get()); -} - -INSTANTIATE_TEST_SUITE_P_NOLINT(FileMatrixTestsSTL, NesterovATestTaskSTL, ::testing::Values(0.5, 1.0)); diff --git a/tasks/stl/example/include/ops_stl.hpp b/tasks/stl/example/include/ops_stl.hpp deleted file mode 100644 index 1461d8ca2..000000000 --- a/tasks/stl/example/include/ops_stl.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include - -#include "core/task/include/task.hpp" - -namespace nesterov_a_test_task_stl { - -class TestTaskSTL : public ppc::core::Task { - public: - explicit TestTaskSTL(const std::vector& in) : input_(in) {} - bool ValidationImpl() override; - bool PreProcessingImpl() override; - bool RunImpl() override; - bool PostProcessingImpl() override; - std::vector Get(); - - private: - std::vector input_, output_; - int rc_size_{}; -}; - -} // namespace nesterov_a_test_task_stl diff --git a/tasks/stl/example/perf_tests/main.cpp b/tasks/stl/example/perf_tests/main.cpp deleted file mode 100644 index 176aa8fcf..000000000 --- a/tasks/stl/example/perf_tests/main.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include - -#include -#include -#include -#include -#include - -#include "core/perf/include/perf.hpp" -#include "core/util/include/util.hpp" -#include "stl/example/include/ops_stl.hpp" - -class NesterovTaskSTLTest : public ::testing::TestWithParam { - protected: - static void RunTest(ppc::core::PerfResults::TypeOfRunning mode) { - constexpr size_t kCount = 450; - - // Create data - std::vector in(kCount * kCount, 0); - for (size_t i = 0; i < kCount; i++) { - in[(i * kCount) + i] = 1; - } - - // Create Task - auto test_task_stl = std::make_shared(in); - - // Create Perf analyzer - ppc::core::Perf perf_analyzer(test_task_stl); - - // Create Perf attributes - ppc::core::PerfAttr perf_attr; - const auto t0 = std::chrono::high_resolution_clock::now(); - perf_attr.current_timer = [&] { - auto current_time_point = std::chrono::high_resolution_clock::now(); - auto duration = std::chrono::duration_cast(current_time_point - t0).count(); - return static_cast(duration) * 1e-9; - }; - - if (mode == ppc::core::PerfResults::TypeOfRunning::kPipeline) { - perf_analyzer.PipelineRun(perf_attr); - } else { - perf_analyzer.TaskRun(perf_attr); - } - - perf_analyzer.PrintPerfStatistic(); - - ASSERT_EQ(in, test_task_stl->Get()); - } -}; - -TEST_P(NesterovTaskSTLTest, RunModes) { RunTest(GetParam()); } - -INSTANTIATE_TEST_SUITE_P_NOLINT(NesterovSTLTests, NesterovTaskSTLTest, - ::testing::Values(ppc::core::PerfResults::TypeOfRunning::kPipeline, - ppc::core::PerfResults::TypeOfRunning::kTaskRun)); diff --git a/tasks/stl/example/src/ops_stl.cpp b/tasks/stl/example/src/ops_stl.cpp deleted file mode 100644 index 608360d54..000000000 --- a/tasks/stl/example/src/ops_stl.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "stl/example/include/ops_stl.hpp" - -#include -#include -#include -#include -#include - -#include "core/util/include/util.hpp" - -namespace { -void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_vec) { - for (int i = 0; i < rc_size; ++i) { - for (int j = 0; j < rc_size; ++j) { - out_vec[(i * rc_size) + j] = 0; - for (int k = 0; k < rc_size; ++k) { - out_vec[(i * rc_size) + j] += in_vec[(i * rc_size) + k] * in_vec[(k * rc_size) + j]; - } - } - } -} -} // namespace - -bool nesterov_a_test_task_stl::TestTaskSTL::ValidationImpl() { - auto sqrt_size = static_cast(std::sqrt(input_.size())); - return sqrt_size * sqrt_size == static_cast(input_.size()); -} - -bool nesterov_a_test_task_stl::TestTaskSTL::PreProcessingImpl() { - rc_size_ = static_cast(std::sqrt(input_.size())); - output_ = std::vector(input_.size(), 0); - return true; -} - -bool nesterov_a_test_task_stl::TestTaskSTL::RunImpl() { - const int num_threads = ppc::util::GetPPCNumThreads(); - std::vector threads(num_threads); - for (int i = 0; i < num_threads; i++) { - threads[i] = std::thread(MatMul, std::cref(input_), rc_size_, std::ref(output_)); - threads[i].join(); - } - return true; -} - -bool nesterov_a_test_task_stl::TestTaskSTL::PostProcessingImpl() { return true; } - -std::vector nesterov_a_test_task_stl::TestTaskSTL::Get() { return output_; } diff --git a/tasks/stl/runner.cpp b/tasks/stl/runner.cpp deleted file mode 100644 index 4d820af77..000000000 --- a/tasks/stl/runner.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/tasks/tbb/example/data/test.txt b/tasks/tbb/example/data/test.txt deleted file mode 100644 index 105d7d9ad..000000000 --- a/tasks/tbb/example/data/test.txt +++ /dev/null @@ -1 +0,0 @@ -100 \ No newline at end of file diff --git a/tasks/tbb/example/func_tests/main.cpp b/tasks/tbb/example/func_tests/main.cpp deleted file mode 100644 index c4236089b..000000000 --- a/tasks/tbb/example/func_tests/main.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include - -#include "core/task/include/task.hpp" -#include "core/util/include/util.hpp" -#include "tbb/example/include/ops_tbb.hpp" - -class NesterovATestTaskTBB : public ::testing::TestWithParam { - protected: - void SetUp() override { - std::ifstream test_file(ppc::util::GetAbsolutePath("tbb/example/data/test.txt")); - ASSERT_TRUE(test_file.is_open()) << "Failed to open input file"; - std::string line; - std::getline(test_file, line); - test_file.close(); - base_count = std::stoi(line); - } - - [[nodiscard]] size_t GetCount() const { return static_cast(base_count * GetParam()); } - - int base_count = 0; -}; - -TEST_P(NesterovATestTaskTBB, MatmulFromFile) { - const size_t count = GetCount(); - - std::vector in(count * count, 0); - for (size_t i = 0; i < count; ++i) { - in[(i * count) + i] = 1; - } - - nesterov_a_test_task_tbb::TestTaskTBB test_task_tbb(in); - ASSERT_TRUE(test_task_tbb.Validation()); - test_task_tbb.PreProcessing(); - test_task_tbb.Run(); - test_task_tbb.PostProcessing(); - - EXPECT_EQ(in, test_task_tbb.Get()); -} - -INSTANTIATE_TEST_SUITE_P_NOLINT(FileMatrixTestsTBB, NesterovATestTaskTBB, ::testing::Values(0.5, 1.0)); diff --git a/tasks/tbb/example/include/ops_tbb.hpp b/tasks/tbb/example/include/ops_tbb.hpp deleted file mode 100644 index 4df85defb..000000000 --- a/tasks/tbb/example/include/ops_tbb.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include - -#include "core/task/include/task.hpp" - -namespace nesterov_a_test_task_tbb { - -class TestTaskTBB : public ppc::core::Task { - public: - explicit TestTaskTBB(const std::vector& in) : input_(in) {} - bool ValidationImpl() override; - bool PreProcessingImpl() override; - bool RunImpl() override; - bool PostProcessingImpl() override; - std::vector Get(); - - private: - std::vector input_, output_; - int rc_size_{}; -}; - -} // namespace nesterov_a_test_task_tbb diff --git a/tasks/tbb/example/perf_tests/main.cpp b/tasks/tbb/example/perf_tests/main.cpp deleted file mode 100644 index ea5c00b55..000000000 --- a/tasks/tbb/example/perf_tests/main.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include - -#include -#include -#include -#include -#include - -#include "core/perf/include/perf.hpp" -#include "core/util/include/util.hpp" -#include "tbb/example/include/ops_tbb.hpp" - -class NesterovTaskTBBTest : public ::testing::TestWithParam { - protected: - static void RunTest(ppc::core::PerfResults::TypeOfRunning mode) { - constexpr size_t kCount = 450; - - // Create data - std::vector in(kCount * kCount, 0); - for (size_t i = 0; i < kCount; i++) { - in[(i * kCount) + i] = 1; - } - - // Create Task - auto test_task_tbb = std::make_shared(in); - - // Create Perf analyzer - ppc::core::Perf perf_analyzer(test_task_tbb); - - // Create Perf attributes - ppc::core::PerfAttr perf_attr; - const auto t0 = std::chrono::high_resolution_clock::now(); - perf_attr.current_timer = [&] { - auto current_time_point = std::chrono::high_resolution_clock::now(); - auto duration = std::chrono::duration_cast(current_time_point - t0).count(); - return static_cast(duration) * 1e-9; - }; - - if (mode == ppc::core::PerfResults::TypeOfRunning::kPipeline) { - perf_analyzer.PipelineRun(perf_attr); - } else { - perf_analyzer.TaskRun(perf_attr); - } - - perf_analyzer.PrintPerfStatistic(); - - ASSERT_EQ(in, test_task_tbb->Get()); - } -}; - -TEST_P(NesterovTaskTBBTest, RunModes) { RunTest(GetParam()); } - -INSTANTIATE_TEST_SUITE_P_NOLINT(NesterovTBBTests, NesterovTaskTBBTest, - ::testing::Values(ppc::core::PerfResults::TypeOfRunning::kPipeline, - ppc::core::PerfResults::TypeOfRunning::kTaskRun)); diff --git a/tasks/tbb/example/src/ops_tbb.cpp b/tasks/tbb/example/src/ops_tbb.cpp deleted file mode 100644 index 191dce5da..000000000 --- a/tasks/tbb/example/src/ops_tbb.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "tbb/example/include/ops_tbb.hpp" - -#include - -#include -#include -#include -#include - -#include "oneapi/tbb/parallel_for.h" - -namespace { -void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_vec) { - for (int i = 0; i < rc_size; ++i) { - for (int j = 0; j < rc_size; ++j) { - out_vec[(i * rc_size) + j] = 0; - for (int k = 0; k < rc_size; ++k) { - out_vec[(i * rc_size) + j] += in_vec[(i * rc_size) + k] * in_vec[(k * rc_size) + j]; - } - } - } -} -} // namespace - -bool nesterov_a_test_task_tbb::TestTaskTBB::ValidationImpl() { - auto sqrt_size = static_cast(std::sqrt(input_.size())); - return sqrt_size * sqrt_size == static_cast(input_.size()); -} - -bool nesterov_a_test_task_tbb::TestTaskTBB::PreProcessingImpl() { - rc_size_ = static_cast(std::sqrt(input_.size())); - output_ = std::vector(input_.size(), 0); - return true; -} - -bool nesterov_a_test_task_tbb::TestTaskTBB::RunImpl() { - tbb::parallel_for(0, ppc::util::GetPPCNumThreads(), [&](int i) { MatMul(input_, rc_size_ - i, output_); }); - MatMul(input_, rc_size_, output_); - return true; -} - -bool nesterov_a_test_task_tbb::TestTaskTBB::PostProcessingImpl() { return true; } - -std::vector nesterov_a_test_task_tbb::TestTaskTBB::Get() { return output_; } diff --git a/tasks/tbb/runner.cpp b/tasks/tbb/runner.cpp deleted file mode 100644 index 2020b5414..000000000 --- a/tasks/tbb/runner.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include - -#include "core/util/include/util.hpp" -#include "oneapi/tbb/global_control.h" - -int main(int argc, char** argv) { - // Limit the number of threads in TBB - tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetPPCNumThreads()); - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} From 276601b93a4638079e135ea28cf125c1d619eacf Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sat, 24 May 2025 14:06:18 +0200 Subject: [PATCH 016/141] unite binaries --- tasks/CMakeLists.txt | 71 ++++++++++---- tasks/example/CMakeLists.txt | 61 +++--------- tasks/example/tests/func_tests/main.cpp | 2 +- .../{example/tests => func_runner}/runner.cpp | 0 tasks/perf_runner/runner.cpp | 93 +++++++++++++++++++ 5 files changed, 162 insertions(+), 65 deletions(-) rename tasks/{example/tests => func_runner}/runner.cpp (100%) create mode 100644 tasks/perf_runner/runner.cpp diff --git a/tasks/CMakeLists.txt b/tasks/CMakeLists.txt index 9467d6cfa..a0d8e7631 100644 --- a/tasks/CMakeLists.txt +++ b/tasks/CMakeLists.txt @@ -1,26 +1,65 @@ message(STATUS "Student's tasks") -set(list_of_reverts "") +project("parallel_programming_course") +set(exec_func_tests "ppc_func_tests") +set(exec_perf_tests "ppc_perf_tests") + +# Init func tests executable files +set(list_of_exec_tests "") +if (USE_FUNC_TESTS) + add_executable(${exec_func_tests} "${CMAKE_CURRENT_SOURCE_DIR}/func_runner/runner.cpp") + list(APPEND list_of_exec_tests ${exec_func_tests}) +endif (USE_FUNC_TESTS) + +# Init perf tests executable files +if (USE_PERF_TESTS) + add_executable(${exec_perf_tests} "${CMAKE_CURRENT_SOURCE_DIR}/perf_runner/runner.cpp") + list(APPEND list_of_exec_tests ${exec_perf_tests}) +endif (USE_PERF_TESTS) SUBDIRLIST(subdirs ${CMAKE_CURRENT_LIST_DIR}) foreach(subd ${subdirs}) + if ((subd STREQUAL "func_runner") OR (subd STREQUAL "perf_runner")) + continue() + endif () add_subdirectory(${subd}) - foreach (dir_type "all" "mpi" "omp" "seq" "stl" "tbb") - set(base_dir "${CMAKE_CURRENT_SOURCE_DIR}/${subd}/${dir_type}_disabled") - if (NOT EXISTS "${base_dir}") - continue() - else () - list(APPEND list_of_reverts "${subd}_${dir_type}") - endif () - endforeach () endforeach() -set(output_file "${CMAKE_BINARY_DIR}/revert-list.txt") -file(WRITE ${output_file} "${CONTENT}") -message(STATUS "Revert list") -foreach (dir_name ${list_of_reverts}) - message(STATUS "-- ${dir_name}") - file(APPEND ${output_file} "${dir_name}\n") -endforeach() +# Link 3rdparty libraries +add_library(stb_image INTERFACE) + +foreach (exec_func ${list_of_exec_tests}) + target_link_libraries(${exec_func} PUBLIC Threads::Threads) + target_link_libraries(${exec_func} PUBLIC ${OpenMP_libomp_LIBRARY}) + if( MPI_COMPILE_FLAGS ) + set_target_properties(${exec_func} PROPERTIES COMPILE_FLAGS "${MPI_COMPILE_FLAGS}") + endif( MPI_COMPILE_FLAGS ) + + if( MPI_LINK_FLAGS ) + set_target_properties(${exec_func} PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}") + endif( MPI_LINK_FLAGS ) + target_link_libraries(${exec_func} PUBLIC ${MPI_LIBRARIES}) + + add_dependencies(${exec_func} ppc_onetbb) + target_link_directories(${exec_func} PUBLIC ${CMAKE_BINARY_DIR}/ppc_onetbb/install/lib) + if(NOT MSVC) + target_link_libraries(${exec_func} PUBLIC tbb) + endif() + + target_link_directories(stb_image INTERFACE ${CMAKE_SOURCE_DIR}/3rdparty/stb) + target_link_libraries(${exec_func} PUBLIC stb_image) + + add_dependencies(${exec_func} ppc_googletest) + target_link_directories(${exec_func} PUBLIC "${CMAKE_BINARY_DIR}/ppc_googletest/install/lib") + target_link_libraries(${exec_func} PUBLIC gtest gtest_main) + enable_testing() + add_test(NAME ${exec_func} COMMAND ${exec_func}) + + # Install the executable + install(TARGETS ${exec_func} RUNTIME DESTINATION bin) +endforeach () + +# Install the library +install(TARGETS ${name_lib} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) add_compile_definitions(PATH_TO_PPC_PROJECT="${CMAKE_SOURCE_DIR}") diff --git a/tasks/example/CMakeLists.txt b/tasks/example/CMakeLists.txt index 1885e09ed..4692312f4 100644 --- a/tasks/example/CMakeLists.txt +++ b/tasks/example/CMakeLists.txt @@ -1,28 +1,28 @@ -# Print student task name -get_filename_component(TASK_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) -message(STATUS "-- ${TASK_NAME}") - # Init project -project(${TASK_NAME}) -set(exec_func_tests "${TASK_NAME}_func_tests") -set(exec_perf_tests "${TASK_NAME}_perf_tests") +project("parallel_programming_course") +set(exec_func_tests "ppc_func_tests") +set(exec_perf_tests "ppc_perf_tests") set(test_base_dir "${CMAKE_CURRENT_SOURCE_DIR}/tests") # Init func tests executable files set(list_of_exec_tests "") if (USE_FUNC_TESTS) file(GLOB_RECURSE func_tests_source_files "${test_base_dir}/func_tests/*") - add_executable(${exec_func_tests} ${func_tests_source_files} "${test_base_dir}/runner.cpp") + target_sources(${exec_func_tests} PRIVATE ${func_tests_source_files}) list(APPEND list_of_exec_tests ${exec_func_tests}) endif (USE_FUNC_TESTS) # Init perf tests executable files if (USE_PERF_TESTS) file(GLOB_RECURSE perf_tests_source_files "${test_base_dir}/perf_tests/*") - add_executable(${exec_perf_tests} ${perf_tests_source_files} "${test_base_dir}/runner.cpp") + target_sources(${exec_perf_tests} PRIVATE ${perf_tests_source_files}) list(APPEND list_of_exec_tests ${exec_perf_tests}) endif (USE_PERF_TESTS) +# Print student task name +get_filename_component(TASK_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) +message(STATUS "-- ${TASK_NAME}") + # Create lib foreach (dir_type "all" "mpi" "omp" "seq" "stl" "tbb") # Check directory existing @@ -46,45 +46,10 @@ foreach (dir_type "all" "mpi" "omp" "seq" "stl" "tbb") add_library(${name_lib} STATIC ${lib_source_files}) endif() set_target_properties(${name_lib} PROPERTIES LINKER_LANGUAGE CXX) + target_link_libraries(${name_lib} PUBLIC core_module_lib) # Link core library - target_link_libraries(${exec_func_tests} PUBLIC ${name_lib} core_module_lib) - target_link_libraries(${exec_perf_tests} PUBLIC ${name_lib} core_module_lib) -endforeach () - -# Link 3rdparty libraries -add_library(stb_image INTERFACE) - -foreach (exec_func ${list_of_exec_tests}) - target_link_libraries(${exec_func} PUBLIC Threads::Threads) - target_link_libraries(${exec_func} PUBLIC ${OpenMP_libomp_LIBRARY}) - if( MPI_COMPILE_FLAGS ) - set_target_properties(${exec_func} PROPERTIES COMPILE_FLAGS "${MPI_COMPILE_FLAGS}") - endif( MPI_COMPILE_FLAGS ) - - if( MPI_LINK_FLAGS ) - set_target_properties(${exec_func} PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}") - endif( MPI_LINK_FLAGS ) - target_link_libraries(${exec_func} PUBLIC ${MPI_LIBRARIES}) - - add_dependencies(${exec_func} ppc_onetbb) - target_link_directories(${exec_func} PUBLIC ${CMAKE_BINARY_DIR}/ppc_onetbb/install/lib) - if(NOT MSVC) - target_link_libraries(${exec_func} PUBLIC tbb) - endif() - - target_link_directories(stb_image INTERFACE ${CMAKE_SOURCE_DIR}/3rdparty/stb) - target_link_libraries(${exec_func} PUBLIC stb_image) - - add_dependencies(${exec_func} ppc_googletest) - target_link_directories(${exec_func} PUBLIC "${CMAKE_BINARY_DIR}/ppc_googletest/install/lib") - target_link_libraries(${exec_func} PUBLIC gtest gtest_main) - enable_testing() - add_test(NAME ${exec_func} COMMAND ${exec_func}) - - # Install the executable - install(TARGETS ${exec_func} RUNTIME DESTINATION bin) + foreach (exec_func ${list_of_exec_tests}) + target_link_libraries(${exec_func} PUBLIC ${name_lib}) + endforeach () endforeach () - -# Install the library -install(TARGETS ${name_lib} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) diff --git a/tasks/example/tests/func_tests/main.cpp b/tasks/example/tests/func_tests/main.cpp index dd15ca1fd..fe7796eaa 100644 --- a/tasks/example/tests/func_tests/main.cpp +++ b/tasks/example/tests/func_tests/main.cpp @@ -22,7 +22,7 @@ class NesterovARunFuncTests : public ::testing::TestWithParam { protected: void SetUp() override { // Read image - std::string abs_path = ppc::util::GetAbsolutePath("all/example/data/pic_all.jpg"); + std::string abs_path = ppc::util::GetAbsolutePath("example/tests/data/pic_all.jpg"); data = stbi_load(abs_path.c_str(), &width, &height, &channels, 0); ASSERT_TRUE(data != nullptr) << "Failed to load image: " << stbi_failure_reason(); img = std::vector(data, data + (width * height * channels)); diff --git a/tasks/example/tests/runner.cpp b/tasks/func_runner/runner.cpp similarity index 100% rename from tasks/example/tests/runner.cpp rename to tasks/func_runner/runner.cpp diff --git a/tasks/perf_runner/runner.cpp b/tasks/perf_runner/runner.cpp new file mode 100644 index 000000000..5ea930ad8 --- /dev/null +++ b/tasks/perf_runner/runner.cpp @@ -0,0 +1,93 @@ +#include +#include + +#include +#include +#include +#include +#include + +#include "core/util/include/util.hpp" +#include "oneapi/tbb/global_control.h" + +class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { + public: + UnreadMessagesDetector() = default; + + void OnTestEnd(const ::testing::TestInfo& /*test_info*/) override { + int rank = -1; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + MPI_Barrier(MPI_COMM_WORLD); + + int flag = -1; + MPI_Status status; + + MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status); + + if (flag != 0) { + fprintf( + stderr, + "[ PROCESS %d ] [ FAILED ] %s.%s: MPI message queue has an unread message from process %d with tag %d\n", + rank, "test_suite_name", "test_name", status.MPI_SOURCE, status.MPI_TAG); + MPI_Finalize(); + exit(2); + } + + MPI_Barrier(MPI_COMM_WORLD); + } + + private: +}; + +class WorkerTestFailurePrinter : public ::testing::EmptyTestEventListener { + public: + explicit WorkerTestFailurePrinter(std::shared_ptr<::testing::TestEventListener> base) : base_(std::move(base)) {} + + void OnTestEnd(const ::testing::TestInfo& test_info) override { + if (test_info.result()->Passed()) { + return; + } + PrintProcessRank(); + base_->OnTestEnd(test_info); + } + + void OnTestPartResult(const ::testing::TestPartResult& test_part_result) override { + if (test_part_result.passed() || test_part_result.skipped()) { + return; + } + PrintProcessRank(); + base_->OnTestPartResult(test_part_result); + } + + private: + static void PrintProcessRank() { + int rank = -1; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + printf(" [ PROCESS %d ] ", rank); + } + + std::shared_ptr<::testing::TestEventListener> base_; +}; + +int main(int argc, char** argv) { + MPI_Init(&argc, &argv); + + // Limit the number of threads in TBB + tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetPPCNumThreads()); + + ::testing::InitGoogleTest(&argc, argv); + + auto& listeners = ::testing::UnitTest::GetInstance()->listeners(); + int rank = -1; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + if (rank != 0 && (argc < 2 || argv[1] != std::string("--print-workers"))) { + auto* listener = listeners.Release(listeners.default_result_printer()); + listeners.Append(new WorkerTestFailurePrinter(std::shared_ptr<::testing::TestEventListener>(listener))); + } + listeners.Append(new UnreadMessagesDetector()); + auto status = RUN_ALL_TESTS(); + + MPI_Finalize(); + return status; +} From 9cce2f3873a3b19e5792c7b4f312d8573883f4e1 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Thu, 29 May 2025 00:16:29 +0200 Subject: [PATCH 017/141] Refactor test parametrization and naming for clarity Refactored test parameter structs and macros to enhance readability and flexibility, including the addition of `FuncTestParam` and `PerfTestParam` types. Updated test case naming conventions with custom functions for better identification. Simplified utility functions and macros for improved code maintainability. --- modules/core/util/include/test_util.hpp | 44 ++++++++++++++++++------- modules/core/util/include/util.hpp | 34 +++++++++++-------- tasks/example/tests/func_tests/main.cpp | 36 ++++++++++++-------- tasks/example/tests/perf_tests/main.cpp | 28 +++++++++------- 4 files changed, 90 insertions(+), 52 deletions(-) diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/test_util.hpp index 9f8fa8e28..d680fc506 100644 --- a/modules/core/util/include/test_util.hpp +++ b/modules/core/util/include/test_util.hpp @@ -7,12 +7,32 @@ namespace ppc::util { +enum FuncTestParamIndex : uint8_t { kTaskGetter, kNameTest, kAddParams }; + +inline std::string GetStringParamName(ppc::core::PerfResults::TypeOfRunning type_of_running) { + if (type_of_running == core::PerfResults::kTaskRun) { + return "task_run"; + } + if (type_of_running == core::PerfResults::kPipeline) { + return "pipeline"; + } + return "none"; +} + +template +using FuncTestParam = std::tuple(InType)>, std::string, AddParams>; + template -using TestParam = std::tuple(InType)>, std::string>; +using PerfTestParam = FuncTestParam; template -class BaseRunPerfTests : public ::testing::TestWithParam> { +class BaseRunPerfTests : public ::testing::TestWithParam> { + public: + static std::string CustomPerfTestName(const ::testing::TestParamInfo>& info) { + return ppc::util::GetStringParamName(std::get(info.param)) + "_" + + std::get(info.param); + } + protected: virtual void SetPerfAttributes(ppc::core::PerfAttr& perf_attrs) = 0; virtual bool CheckTestOutputData(OutType& output_data) = 0; @@ -20,8 +40,8 @@ class BaseRunPerfTests : public ::testing::TestWithParam(InType)> task_getter, std::string test_name) { - task = task_getter(GetTestInputData()); - ppc::core::Perf perf(task); + task_ = task_getter(GetTestInputData()); + ppc::core::Perf perf(task_); ppc::core::PerfAttr perf_attr; SetPerfAttributes(perf_attr); @@ -40,18 +60,18 @@ class BaseRunPerfTests : public ::testing::TestWithParamGetOutput(); + OutType output_data = task_->GetOutput(); ASSERT_TRUE(CheckTestOutputData(output_data)); } private: - ppc::core::TaskPtr task; + ppc::core::TaskPtr task_; }; -#define ADD_MODES(TaskType, InputTypeParam) \ - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kPipeline, ppc::core::TaskGetter, \ - ppc::util::GetNamespace()), \ - std::make_tuple(ppc::core::PerfResults::TypeOfRunning::kTaskRun, \ - ppc::core::TaskGetter, ppc::util::GetNamespace()) +#define ADD_PERF_MODES(TaskType, InputTypeParam) \ + std::make_tuple(ppc::core::TaskGetter, ppc::util::GetNamespace(), \ + ppc::core::PerfResults::TypeOfRunning::kPipeline), \ + std::make_tuple(ppc::core::TaskGetter, ppc::util::GetNamespace(), \ + ppc::core::PerfResults::TypeOfRunning::kTaskRun) } // namespace ppc::util diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index 78af88acf..c2a56bea1 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -3,8 +3,8 @@ #include /* NOLINTBEGIN */ -#define INSTANTIATE_TEST_SUITE_P_NOLINT(prefix, test_case_name, generator) \ - INSTANTIATE_TEST_SUITE_P(prefix, test_case_name, generator) +#define INSTANTIATE_TEST_SUITE_P_NOLINT(prefix, test_case_name, generator, custom_test_name) \ + INSTANTIATE_TEST_SUITE_P(prefix, test_case_name, generator, custom_test_name) /* NOLINTEND */ /* NOLINTBEGIN */ @@ -16,29 +16,35 @@ namespace ppc::util { std::string GetAbsolutePath(const std::string &relative_path); int GetPPCNumThreads(); +#if defined(__clang__) || defined(__GNUC__) template consteval std::string_view GetNamespace() { -#if defined(__clang__) || defined(__GNUC__) - constexpr std::string_view func = __PRETTY_FUNCTION__; + constexpr std::string_view kFunc = __PRETTY_FUNCTION__; // example: "consteval std::string_view get_namespace() [with T = my_namespace::MyClass]" - constexpr std::string_view key = "T = "; + constexpr std::string_view kKey = "T = "; #elif defined(_MSC_VER) - constexpr std::string_view func = __FUNCSIG__; +template +constexpr std::string_view GetNamespace() { + constexpr std::string_view kFunc = __FUNCSIG__; // example: "class std::basic_string_view > __cdecl get_namespace(void)" - constexpr std::string_view key = "get_namespace<"; + constexpr std::string_view kKey = "get_namespace<"; #else - static_assert(false, "Unsupported compiler"); +static_assert(false, "Unsupported compiler"); #endif - auto start = func.find(key); - if (start == std::string_view::npos) return {}; - start += key.size(); + auto start = kFunc.find(kKey); + if (start == std::string_view::npos) { + return {}; + } + start += kKey.size(); - auto end = func.find("::", start); - if (end == std::string_view::npos) return {}; + auto end = kFunc.find("::", start); + if (end == std::string_view::npos) { + return {}; + } - return func.substr(start, end - start); + return kFunc.substr(start, end - start); } } // namespace ppc::util diff --git a/tasks/example/tests/func_tests/main.cpp b/tasks/example/tests/func_tests/main.cpp index fe7796eaa..ce2ad8279 100644 --- a/tasks/example/tests/func_tests/main.cpp +++ b/tasks/example/tests/func_tests/main.cpp @@ -1,10 +1,12 @@ #include +#include #include #include #include #include +#include "core/util/include/test_util.hpp" #include "core/util/include/util.hpp" #include "example/all/include/ops_all.hpp" #include "example/mpi/include/ops_mpi.hpp" @@ -16,25 +18,29 @@ using InType = std::vector; using OutType = std::vector; -using TestParam = std::tuple(InType)>>; +class NesterovARunFuncTests : public ::testing::TestWithParam> { + public: + static std::string CustomFuncTestName( + const ::testing::TestParamInfo>& info) { + return std::to_string(info.index); + } -class NesterovARunFuncTests : public ::testing::TestWithParam { protected: void SetUp() override { // Read image std::string abs_path = ppc::util::GetAbsolutePath("example/tests/data/pic_all.jpg"); data = stbi_load(abs_path.c_str(), &width, &height, &channels, 0); ASSERT_TRUE(data != nullptr) << "Failed to load image: " << stbi_failure_reason(); - img = std::vector(data, data + (width * height * channels)); + img = std::vector(data, data + (static_cast(width * height * channels))); stbi_image_free(data); ASSERT_EQ(width, height); - const int k_count = (width + height) / std::get<0>(GetParam()); - std::vector in(k_count * k_count, 0); + const int k_count = (width + height) / std::get(GetParam()); + std::vector in(static_cast::size_type>(k_count * k_count), 0); for (int i = 0; i < k_count; i++) { in[(i * k_count) + i] = 1; } - task = std::get<1>(GetParam())(in); + task = std::get(GetParam())(in); } void ExecuteTest() { @@ -53,13 +59,15 @@ class NesterovARunFuncTests : public ::testing::TestWithParam { TEST_P(NesterovARunFuncTests, MatmulFromPic) { ExecuteTest(); } -#define ADD_TASK(TASK) \ - std::make_tuple(5, ppc::core::TaskGetter), std::make_tuple(10, ppc::core::TaskGetter) +#define ADD_FUNC_TASK(TASK) \ + std::make_tuple(ppc::core::TaskGetter, "", 5), \ + std::make_tuple(ppc::core::TaskGetter, "", 10) INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTests, - ::testing::Values(ADD_TASK(nesterov_a_test_task_all::TestTaskALL), - ADD_TASK(nesterov_a_test_task_mpi::TestTaskMPI), - ADD_TASK(nesterov_a_test_task_omp::TestTaskOMP), - ADD_TASK(nesterov_a_test_task_seq::TestTaskSEQ), - ADD_TASK(nesterov_a_test_task_stl::TestTaskSTL), - ADD_TASK(nesterov_a_test_task_tbb::TestTaskTBB))); + ::testing::Values(ADD_FUNC_TASK(nesterov_a_test_task_all::TestTaskALL), + ADD_FUNC_TASK(nesterov_a_test_task_mpi::TestTaskMPI), + ADD_FUNC_TASK(nesterov_a_test_task_omp::TestTaskOMP), + ADD_FUNC_TASK(nesterov_a_test_task_seq::TestTaskSEQ), + ADD_FUNC_TASK(nesterov_a_test_task_stl::TestTaskSTL), + ADD_FUNC_TASK(nesterov_a_test_task_tbb::TestTaskTBB)), + NesterovARunFuncTests::CustomFuncTestName); diff --git a/tasks/example/tests/perf_tests/main.cpp b/tasks/example/tests/perf_tests/main.cpp index 2200e2ebb..e2ffcf1e4 100644 --- a/tasks/example/tests/perf_tests/main.cpp +++ b/tasks/example/tests/perf_tests/main.cpp @@ -20,12 +20,12 @@ using OutType = std::vector; class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { static constexpr int kCount = 400; - InType input_data; + InType input_data_; void SetUp() override { - input_data.assign(kCount * kCount, 0); + input_data_.assign(kCount * kCount, 0); for (int i = 0; i < kCount; ++i) { - input_data[(i * kCount) + i] = 1; + input_data_[(i * kCount) + i] = 1; } } @@ -38,19 +38,23 @@ class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { }; } - bool CheckTestOutputData(OutType& output_data) final { return input_data == output_data; } + bool CheckTestOutputData(OutType& output_data) final { return input_data_ == output_data; } - InType GetTestInputData() final { return input_data; } + InType GetTestInputData() final { return input_data_; } }; TEST_P(ExampleRunPerfTest, RunModes) { - ExecuteTest(std::get<0>(GetParam()), std::get<1>(GetParam()), std::get<2>(GetParam())); + auto task_getter = std::get(GetParam()); + auto test_name = std::get(GetParam()); + auto perf_type = std::get(GetParam()); + ExecuteTest(perf_type, task_getter, test_name); } INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, ExampleRunPerfTest, - ::testing::Values(ADD_MODES(nesterov_a_test_task_all::TestTaskALL, InType), - ADD_MODES(nesterov_a_test_task_mpi::TestTaskMPI, InType), - ADD_MODES(nesterov_a_test_task_omp::TestTaskOMP, InType), - ADD_MODES(nesterov_a_test_task_seq::TestTaskSEQ, InType), - ADD_MODES(nesterov_a_test_task_stl::TestTaskSTL, InType), - ADD_MODES(nesterov_a_test_task_tbb::TestTaskTBB, InType))); + ::testing::Values(ADD_PERF_MODES(nesterov_a_test_task_all::TestTaskALL, InType), + ADD_PERF_MODES(nesterov_a_test_task_mpi::TestTaskMPI, InType), + ADD_PERF_MODES(nesterov_a_test_task_omp::TestTaskOMP, InType), + ADD_PERF_MODES(nesterov_a_test_task_seq::TestTaskSEQ, InType), + ADD_PERF_MODES(nesterov_a_test_task_stl::TestTaskSTL, InType), + ADD_PERF_MODES(nesterov_a_test_task_tbb::TestTaskTBB, InType)), + ExampleRunPerfTest::CustomPerfTestName); From a8fdefdf7d0e51f2b3ef9232f50053e8131d6270 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Thu, 29 May 2025 00:51:11 +0200 Subject: [PATCH 018/141] Refactor test and script logic to improve task handling Updated functional tests and scripts to support dynamically filtering tasks by type. Refactored execution logic to reduce redundancy and improve maintainability. Adjusted macros and utility functions for better namespace resolution. --- modules/core/util/include/util.hpp | 2 +- scripts/run_tests.py | 35 +++++++++++-------------- tasks/example/tests/func_tests/main.cpp | 7 ++--- 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index c2a56bea1..4574e77e5 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -16,7 +16,7 @@ namespace ppc::util { std::string GetAbsolutePath(const std::string &relative_path); int GetPPCNumThreads(); -#if defined(__clang__) || defined(__GNUC__) +#if (defined(__clang__) || defined(__GNUC__)) && !defined(_MSC_VER) template consteval std::string_view GetNamespace() { constexpr std::string_view kFunc = __PRETTY_FUNCTION__; diff --git a/scripts/run_tests.py b/scripts/run_tests.py index a65d2a923..233b34329 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -53,27 +53,27 @@ def __run_exec(command): raise Exception(f"Subprocess return {result.returncode}.") @staticmethod - def __get_gtest_settings(repeats_count): + def __get_gtest_settings(repeats_count, type_task): command = f"--gtest_repeat={repeats_count} " command += "--gtest_recreate_environments_when_repeating " command += "--gtest_color=0 " + command += "--gtest_shuffle " + command += f"--gtest_filter=\"*{type_task}*\" " return command def run_threads(self): if platform.system() == "Linux" and not os.environ.get("ASAN_RUN"): - self.__run_exec(f"{self.valgrind_cmd} {self.work_dir / 'seq_func_tests'} {self.__get_gtest_settings(1)}") - self.__run_exec(f"{self.valgrind_cmd} {self.work_dir / 'stl_func_tests'} {self.__get_gtest_settings(1)}") + for task_type in ["seq", "stl"]: + self.__run_exec(f"{self.valgrind_cmd} {self.work_dir / 'ppc_func_tests'} {self.__get_gtest_settings(1, '_' + task_type + '_')}") - self.__run_exec(f"{self.work_dir / 'seq_func_tests'} {self.__get_gtest_settings(3)}") - self.__run_exec(f"{self.work_dir / 'stl_func_tests'} {self.__get_gtest_settings(3)}") - self.__run_exec(f"{self.work_dir / 'tbb_func_tests'} {self.__get_gtest_settings(3)}") - self.__run_exec(f"{self.work_dir / 'omp_func_tests'} {self.__get_gtest_settings(3)}") + for task_type in ["omp", "seq", "stl", "tbb"]: + self.__run_exec(f"{self.work_dir / 'ppc_func_tests'} {self.__get_gtest_settings(3, '_' + task_type + '_')}") def run_core(self): if platform.system() == "Linux" and not os.environ.get("ASAN_RUN"): - self.__run_exec(f"{self.valgrind_cmd} {self.work_dir / 'core_func_tests'} {self.__get_gtest_settings(1)}") + self.__run_exec(f"{self.valgrind_cmd} {self.work_dir / 'core_func_tests'} {self.__get_gtest_settings(1, '*')}") - self.__run_exec(f"{self.work_dir / 'core_func_tests'} {self.__get_gtest_settings(1)}") + self.__run_exec(f"{self.work_dir / 'core_func_tests'} {self.__get_gtest_settings(1, '*')}") def run_processes(self, additional_mpi_args): proc_count = os.environ.get("PROC_COUNT") @@ -82,8 +82,8 @@ def run_processes(self, additional_mpi_args): mpi_running = f"{self.mpi_exec} {additional_mpi_args} -np {proc_count}" if not os.environ.get("ASAN_RUN"): - self.__run_exec(f"{mpi_running} {self.work_dir / 'all_func_tests'} {self.__get_gtest_settings(10)}") - self.__run_exec(f"{mpi_running} {self.work_dir / 'mpi_func_tests'} {self.__get_gtest_settings(10)}") + for task_type in ["all", "mpi"]: + self.__run_exec(f"{mpi_running} {self.work_dir / 'ppc_func_tests'} {self.__get_gtest_settings(10, '_' + task_type)}") def run_performance(self): if not os.environ.get("ASAN_RUN"): @@ -91,17 +91,14 @@ def run_performance(self): if proc_count is None: raise EnvironmentError("Required environment variable 'PROC_COUNT' is not set.") mpi_running = f"{self.mpi_exec} -np {proc_count}" - self.__run_exec(f"{mpi_running} {self.work_dir / 'all_perf_tests'} {self.__get_gtest_settings(1)}") - self.__run_exec(f"{mpi_running} {self.work_dir / 'mpi_perf_tests'} {self.__get_gtest_settings(1)}") + for task_type in ["all", "mpi"]: + self.__run_exec(f"{mpi_running} {self.work_dir / 'ppc_perf_tests'} {self.__get_gtest_settings(1, '_' + task_type)}") - self.__run_exec(f"{self.work_dir / 'omp_perf_tests'} {self.__get_gtest_settings(1)}") - self.__run_exec(f"{self.work_dir / 'seq_perf_tests'} {self.__get_gtest_settings(1)}") - self.__run_exec(f"{self.work_dir / 'stl_perf_tests'} {self.__get_gtest_settings(1)}") - self.__run_exec(f"{self.work_dir / 'tbb_perf_tests'} {self.__get_gtest_settings(1)}") + for task_type in ["omp", "seq", "stl", "tbb"]: + self.__run_exec(f"{self.work_dir / 'ppc_perf_tests'} {self.__get_gtest_settings(1, '_' + task_type)}") def run_performance_list(self): - for task_type in ["all", "mpi", "omp", "seq", "stl", "tbb"]: - self.__run_exec(f"{self.work_dir / f'{task_type}_perf_tests'} --gtest_list_tests") + self.__run_exec(f"{self.work_dir / 'ppc_perf_tests'} --gtest_list_tests") if __name__ == "__main__": diff --git a/tasks/example/tests/func_tests/main.cpp b/tasks/example/tests/func_tests/main.cpp index ce2ad8279..187b581d3 100644 --- a/tasks/example/tests/func_tests/main.cpp +++ b/tasks/example/tests/func_tests/main.cpp @@ -22,7 +22,8 @@ class NesterovARunFuncTests : public ::testing::TestWithParam>& info) { - return std::to_string(info.index); + return std::get(info.param) + "_" + + std::to_string(std::get(info.param)); } protected: @@ -60,8 +61,8 @@ class NesterovARunFuncTests : public ::testing::TestWithParam, "", 5), \ - std::make_tuple(ppc::core::TaskGetter, "", 10) + std::make_tuple(ppc::core::TaskGetter, ppc::util::GetNamespace(), 5), \ + std::make_tuple(ppc::core::TaskGetter, ppc::util::GetNamespace(), 10) INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTests, ::testing::Values(ADD_FUNC_TASK(nesterov_a_test_task_all::TestTaskALL), From d4ed8d38eedd1137729b75e680773e120c1f6072 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Thu, 29 May 2025 00:55:46 +0200 Subject: [PATCH 019/141] Refactor test and script logic for improved readability Standardized line formatting in test definitions and Python scripts. Adjustments enhance code readability without altering functionality or behavior. --- scripts/run_tests.py | 14 +++++++++----- tasks/example/tests/func_tests/main.cpp | 4 ++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/scripts/run_tests.py b/scripts/run_tests.py index 233b34329..f1178854d 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -64,14 +64,16 @@ def __get_gtest_settings(repeats_count, type_task): def run_threads(self): if platform.system() == "Linux" and not os.environ.get("ASAN_RUN"): for task_type in ["seq", "stl"]: - self.__run_exec(f"{self.valgrind_cmd} {self.work_dir / 'ppc_func_tests'} {self.__get_gtest_settings(1, '_' + task_type + '_')}") + self.__run_exec(f"{self.valgrind_cmd} {self.work_dir / 'ppc_func_tests'} " + f"{self.__get_gtest_settings(1, '_' + task_type + '_')}") for task_type in ["omp", "seq", "stl", "tbb"]: self.__run_exec(f"{self.work_dir / 'ppc_func_tests'} {self.__get_gtest_settings(3, '_' + task_type + '_')}") def run_core(self): if platform.system() == "Linux" and not os.environ.get("ASAN_RUN"): - self.__run_exec(f"{self.valgrind_cmd} {self.work_dir / 'core_func_tests'} {self.__get_gtest_settings(1, '*')}") + self.__run_exec(f"{self.valgrind_cmd} {self.work_dir / 'core_func_tests'} " + f"{self.__get_gtest_settings(1, '*')}") self.__run_exec(f"{self.work_dir / 'core_func_tests'} {self.__get_gtest_settings(1, '*')}") @@ -83,7 +85,8 @@ def run_processes(self, additional_mpi_args): mpi_running = f"{self.mpi_exec} {additional_mpi_args} -np {proc_count}" if not os.environ.get("ASAN_RUN"): for task_type in ["all", "mpi"]: - self.__run_exec(f"{mpi_running} {self.work_dir / 'ppc_func_tests'} {self.__get_gtest_settings(10, '_' + task_type)}") + self.__run_exec(f"{mpi_running} {self.work_dir / 'ppc_func_tests'} " + f"{self.__get_gtest_settings(10, '_' + task_type)}") def run_performance(self): if not os.environ.get("ASAN_RUN"): @@ -92,13 +95,14 @@ def run_performance(self): raise EnvironmentError("Required environment variable 'PROC_COUNT' is not set.") mpi_running = f"{self.mpi_exec} -np {proc_count}" for task_type in ["all", "mpi"]: - self.__run_exec(f"{mpi_running} {self.work_dir / 'ppc_perf_tests'} {self.__get_gtest_settings(1, '_' + task_type)}") + self.__run_exec(f"{mpi_running} {self.work_dir / 'ppc_perf_tests'} " + f"{self.__get_gtest_settings(1, '_' + task_type)}") for task_type in ["omp", "seq", "stl", "tbb"]: self.__run_exec(f"{self.work_dir / 'ppc_perf_tests'} {self.__get_gtest_settings(1, '_' + task_type)}") def run_performance_list(self): - self.__run_exec(f"{self.work_dir / 'ppc_perf_tests'} --gtest_list_tests") + self.__run_exec(f"{self.work_dir / 'ppc_perf_tests'} --gtest_list_tests") if __name__ == "__main__": diff --git a/tasks/example/tests/func_tests/main.cpp b/tasks/example/tests/func_tests/main.cpp index 187b581d3..15771e354 100644 --- a/tasks/example/tests/func_tests/main.cpp +++ b/tasks/example/tests/func_tests/main.cpp @@ -23,7 +23,7 @@ class NesterovARunFuncTests : public ::testing::TestWithParam>& info) { return std::get(info.param) + "_" + - std::to_string(std::get(info.param)); + std::to_string(std::get(info.param)); } protected: @@ -60,7 +60,7 @@ class NesterovARunFuncTests : public ::testing::TestWithParam, ppc::util::GetNamespace(), 5), \ std::make_tuple(ppc::core::TaskGetter, ppc::util::GetNamespace(), 10) From cdca4e01e0b742ba024de772a33717745832004a Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Thu, 29 May 2025 01:02:30 +0200 Subject: [PATCH 020/141] Refactor performance test parameter handling. Simplify `ExecuteTest` by encapsulating parameters into a single struct. This reduces redundancy and improves code readability across test execution functions. Updated affected test cases to align with the new parameter structure. --- modules/core/util/include/test_util.hpp | 7 +++++-- tasks/example/tests/perf_tests/main.cpp | 7 +------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/test_util.hpp index d680fc506..12c5cdda8 100644 --- a/modules/core/util/include/test_util.hpp +++ b/modules/core/util/include/test_util.hpp @@ -38,8 +38,11 @@ class BaseRunPerfTests : public ::testing::TestWithParam(InType)> task_getter, std::string test_name) { + void ExecuteTest(const PerfTestParam& perfTestParam) { + auto task_getter = std::get(perfTestParam); + auto test_name = std::get(perfTestParam); + auto mode = std::get(perfTestParam); + task_ = task_getter(GetTestInputData()); ppc::core::Perf perf(task_); ppc::core::PerfAttr perf_attr; diff --git a/tasks/example/tests/perf_tests/main.cpp b/tasks/example/tests/perf_tests/main.cpp index e2ffcf1e4..6f9a53d0b 100644 --- a/tasks/example/tests/perf_tests/main.cpp +++ b/tasks/example/tests/perf_tests/main.cpp @@ -43,12 +43,7 @@ class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { InType GetTestInputData() final { return input_data_; } }; -TEST_P(ExampleRunPerfTest, RunModes) { - auto task_getter = std::get(GetParam()); - auto test_name = std::get(GetParam()); - auto perf_type = std::get(GetParam()); - ExecuteTest(perf_type, task_getter, test_name); -} +TEST_P(ExampleRunPerfTest, RunPerfModes) { ExecuteTest(GetParam()); } INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, ExampleRunPerfTest, ::testing::Values(ADD_PERF_MODES(nesterov_a_test_task_all::TestTaskALL, InType), From c6edfda8ccc7eeb13e7a992701e5a8b9e3006b83 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Thu, 29 May 2025 12:40:12 +0200 Subject: [PATCH 021/141] Refactor functional tests to use BaseRunFuncTests. Replaced direct handling of task pointers with BaseRunFuncTests for cleaner and reusable test logic. Renamed kAddParams to kTestParams for better semantic clarity. Improved test output validation by overriding CheckTestOutputData in derived test classes. --- modules/core/util/include/test_util.hpp | 27 ++++++++++++++++++++++--- tasks/example/tests/func_tests/main.cpp | 27 +++++++++++-------------- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/test_util.hpp index 12c5cdda8..178524f7a 100644 --- a/modules/core/util/include/test_util.hpp +++ b/modules/core/util/include/test_util.hpp @@ -7,7 +7,7 @@ namespace ppc::util { -enum FuncTestParamIndex : uint8_t { kTaskGetter, kNameTest, kAddParams }; +enum FuncTestParamIndex : uint8_t { kTaskGetter, kNameTest, kTestParams }; inline std::string GetStringParamName(ppc::core::PerfResults::TypeOfRunning type_of_running) { if (type_of_running == core::PerfResults::kTaskRun) { @@ -29,7 +29,7 @@ template class BaseRunPerfTests : public ::testing::TestWithParam> { public: static std::string CustomPerfTestName(const ::testing::TestParamInfo>& info) { - return ppc::util::GetStringParamName(std::get(info.param)) + "_" + + return ppc::util::GetStringParamName(std::get(info.param)) + "_" + std::get(info.param); } @@ -41,7 +41,7 @@ class BaseRunPerfTests : public ::testing::TestWithParam& perfTestParam) { auto task_getter = std::get(perfTestParam); auto test_name = std::get(perfTestParam); - auto mode = std::get(perfTestParam); + auto mode = std::get(perfTestParam); task_ = task_getter(GetTestInputData()); ppc::core::Perf perf(task_); @@ -77,4 +77,25 @@ class BaseRunPerfTests : public ::testing::TestWithParam, ppc::util::GetNamespace(), \ ppc::core::PerfResults::TypeOfRunning::kTaskRun) +template +class BaseRunFuncTests : public ::testing::TestWithParam> { + public: + virtual void CheckTestOutputData() = 0; + ppc::core::TaskPtr& GetTaskPtr() { + return task; + } + +protected: + void ExecuteTest() { + ASSERT_TRUE(task->Validation()); + ASSERT_TRUE(task->PreProcessing()); + ASSERT_TRUE(task->Run()); + ASSERT_TRUE(task->PostProcessing()); + CheckTestOutputData(); + } + + private: + ppc::core::TaskPtr task; +}; + } // namespace ppc::util diff --git a/tasks/example/tests/func_tests/main.cpp b/tasks/example/tests/func_tests/main.cpp index 15771e354..97fd8b24a 100644 --- a/tasks/example/tests/func_tests/main.cpp +++ b/tasks/example/tests/func_tests/main.cpp @@ -17,14 +17,16 @@ using InType = std::vector; using OutType = std::vector; +using TestType = int; -class NesterovARunFuncTests : public ::testing::TestWithParam> { +class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests { public: - static std::string CustomFuncTestName( - const ::testing::TestParamInfo>& info) { - return std::get(info.param) + "_" + - std::to_string(std::get(info.param)); - } + static std::string CustomFuncTestName( + const ::testing::TestParamInfo>& info) { + std::string test_name = std::get(info.param); + std::string test_param = std::to_string(std::get(info.param)); + return test_name + "_" + test_param; + } protected: void SetUp() override { @@ -36,23 +38,18 @@ class NesterovARunFuncTests : public ::testing::TestWithParam(GetParam()); + const int k_count = (width + height) / std::get(GetParam()); std::vector in(static_cast::size_type>(k_count * k_count), 0); for (int i = 0; i < k_count; i++) { in[(i * k_count) + i] = 1; } - task = std::get(GetParam())(in); + GetTaskPtr() = std::get(GetParam())(in); } - void ExecuteTest() { - ASSERT_TRUE(task->Validation()); - task->PreProcessing(); - task->Run(); - task->PostProcessing(); - EXPECT_EQ(task->GetInput(), task->GetOutput()); + void CheckTestOutputData() final { + EXPECT_EQ(GetTaskPtr()->GetInput(), GetTaskPtr()->GetOutput()); } - ppc::core::TaskPtr task; int width = -1, height = -1, channels = -1; unsigned char* data = nullptr; std::vector img; From 376dfa464b599cce8692a88695f82baa609011b6 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Thu, 29 May 2025 13:06:16 +0200 Subject: [PATCH 022/141] Refactor test utilities and improve image handling. Extracted data preparation logic into a dedicated function for better readability and modularization. Introduced a new input member in the base test class to streamline test input management. Adjusted lambda and tuple type naming for consistency and clarity. --- modules/core/util/include/test_util.hpp | 30 ++++++++-------- tasks/example/tests/func_tests/main.cpp | 47 +++++++++++++------------ 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/test_util.hpp index 178524f7a..6161e0b5b 100644 --- a/modules/core/util/include/test_util.hpp +++ b/modules/core/util/include/test_util.hpp @@ -19,8 +19,8 @@ inline std::string GetStringParamName(ppc::core::PerfResults::TypeOfRunning type return "none"; } -template -using FuncTestParam = std::tuple(InType)>, std::string, AddParams>; +template +using FuncTestParam = std::tuple(InType)>, std::string, TestType>; template using PerfTestParam = FuncTestParam; @@ -80,22 +80,22 @@ class BaseRunPerfTests : public ::testing::TestWithParam class BaseRunFuncTests : public ::testing::TestWithParam> { public: - virtual void CheckTestOutputData() = 0; - ppc::core::TaskPtr& GetTaskPtr() { - return task; - } - -protected: - void ExecuteTest() { - ASSERT_TRUE(task->Validation()); - ASSERT_TRUE(task->PreProcessing()); - ASSERT_TRUE(task->Run()); - ASSERT_TRUE(task->PostProcessing()); - CheckTestOutputData(); - } + virtual void CheckTestOutputData() = 0; + ppc::core::TaskPtr& GetTaskPtr() { return task; } + InType& GetTestInput() { return test_input_; } + + protected: + void ExecuteTest() { + ASSERT_TRUE(task->Validation()); + ASSERT_TRUE(task->PreProcessing()); + ASSERT_TRUE(task->Run()); + ASSERT_TRUE(task->PostProcessing()); + CheckTestOutputData(); + } private: ppc::core::TaskPtr task; + InType test_input_; }; } // namespace ppc::util diff --git a/tasks/example/tests/func_tests/main.cpp b/tasks/example/tests/func_tests/main.cpp index 97fd8b24a..3179ef8c5 100644 --- a/tasks/example/tests/func_tests/main.cpp +++ b/tasks/example/tests/func_tests/main.cpp @@ -21,38 +21,41 @@ using TestType = int; class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests { public: - static std::string CustomFuncTestName( - const ::testing::TestParamInfo>& info) { - std::string test_name = std::get(info.param); - std::string test_param = std::to_string(std::get(info.param)); - return test_name + "_" + test_param; - } + static std::string CustomFuncTestName( + const ::testing::TestParamInfo> &info) { + std::string test_name = std::get(info.param); + std::string test_param = std::to_string(std::get(info.param)); + return test_name + "_" + test_param; + } protected: void SetUp() override { + PrepareData(); + GetTaskPtr() = std::get(GetParam())(GetTestInput()); + } + + void PrepareData() { + int width = -1; + int height = -1; + int channels = -1; // Read image - std::string abs_path = ppc::util::GetAbsolutePath("example/tests/data/pic_all.jpg"); - data = stbi_load(abs_path.c_str(), &width, &height, &channels, 0); - ASSERT_TRUE(data != nullptr) << "Failed to load image: " << stbi_failure_reason(); - img = std::vector(data, data + (static_cast(width * height * channels))); - stbi_image_free(data); - ASSERT_EQ(width, height); + { + std::string abs_path = ppc::util::GetAbsolutePath("example/tests/data/pic_all.jpg"); + auto *data = stbi_load(abs_path.c_str(), &width, &height, &channels, 0); + ASSERT_TRUE(data != nullptr) << "Failed to load image: " << stbi_failure_reason(); + auto img = std::vector(data, data + (static_cast(width * height * channels))); + stbi_image_free(data); + ASSERT_EQ(width, height); + } const int k_count = (width + height) / std::get(GetParam()); - std::vector in(static_cast::size_type>(k_count * k_count), 0); + GetTestInput() = InType(static_cast::size_type>(k_count * k_count), 0); for (int i = 0; i < k_count; i++) { - in[(i * k_count) + i] = 1; + GetTestInput()[(i * k_count) + i] = 1; } - GetTaskPtr() = std::get(GetParam())(in); - } - - void CheckTestOutputData() final { - EXPECT_EQ(GetTaskPtr()->GetInput(), GetTaskPtr()->GetOutput()); } - int width = -1, height = -1, channels = -1; - unsigned char* data = nullptr; - std::vector img; + void CheckTestOutputData() final { EXPECT_EQ(GetTestInput(), GetTaskPtr()->GetOutput()); } }; TEST_P(NesterovARunFuncTests, MatmulFromPic) { ExecuteTest(); } From ee536fe715c6f09152071d4372980958512fb753 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Thu, 29 May 2025 13:33:31 +0200 Subject: [PATCH 023/141] Refactor test execution and data handling in func_tests Refactored the `BaseRunFuncTests` class to simplify and improve test execution and data handling. Replaced `GetTestInput` and `GetTaskPtr` with `GetTestInputData` and `CheckTestOutputData` for cleaner abstraction. Updated error handling and validation logic for better test reliability and maintainability. --- modules/core/util/include/test_util.hpp | 29 ++++++++++++------------- tasks/example/tests/func_tests/main.cpp | 24 ++++++++++---------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/test_util.hpp index 6161e0b5b..ea238912e 100644 --- a/modules/core/util/include/test_util.hpp +++ b/modules/core/util/include/test_util.hpp @@ -38,10 +38,10 @@ class BaseRunPerfTests : public ::testing::TestWithParam& perfTestParam) { - auto task_getter = std::get(perfTestParam); - auto test_name = std::get(perfTestParam); - auto mode = std::get(perfTestParam); + void ExecuteTest(const PerfTestParam& perf_test_param) { + auto task_getter = std::get(perf_test_param); + auto test_name = std::get(perf_test_param); + auto mode = std::get(perf_test_param); task_ = task_getter(GetTestInputData()); ppc::core::Perf perf(task_); @@ -80,22 +80,21 @@ class BaseRunPerfTests : public ::testing::TestWithParam class BaseRunFuncTests : public ::testing::TestWithParam> { public: - virtual void CheckTestOutputData() = 0; - ppc::core::TaskPtr& GetTaskPtr() { return task; } - InType& GetTestInput() { return test_input_; } + virtual bool CheckTestOutputData(OutType& output_data) = 0; + virtual InType GetTestInputData() = 0; protected: - void ExecuteTest() { - ASSERT_TRUE(task->Validation()); - ASSERT_TRUE(task->PreProcessing()); - ASSERT_TRUE(task->Run()); - ASSERT_TRUE(task->PostProcessing()); - CheckTestOutputData(); + void ExecuteTest(ppc::util::FuncTestParam test_param) { + task_ = std::get(test_param)(GetTestInputData()); + ASSERT_TRUE(task_->Validation()); + ASSERT_TRUE(task_->PreProcessing()); + ASSERT_TRUE(task_->Run()); + ASSERT_TRUE(task_->PostProcessing()); + ASSERT_TRUE(CheckTestOutputData(task_->GetOutput())); } private: - ppc::core::TaskPtr task; - InType test_input_; + ppc::core::TaskPtr task_; }; } // namespace ppc::util diff --git a/tasks/example/tests/func_tests/main.cpp b/tasks/example/tests/func_tests/main.cpp index 3179ef8c5..5efbdece0 100644 --- a/tasks/example/tests/func_tests/main.cpp +++ b/tasks/example/tests/func_tests/main.cpp @@ -20,6 +20,7 @@ using OutType = std::vector; using TestType = int; class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests { + InType input_data_; public: static std::string CustomFuncTestName( const ::testing::TestParamInfo> &info) { @@ -30,11 +31,6 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests(GetParam())(GetTestInput()); - } - - void PrepareData() { int width = -1; int height = -1; int channels = -1; @@ -42,23 +38,29 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests(data, data + (static_cast(width * height * channels))); stbi_image_free(data); - ASSERT_EQ(width, height); + if(width != height) { + throw std::runtime_error("width != height: "); + } } const int k_count = (width + height) / std::get(GetParam()); - GetTestInput() = InType(static_cast::size_type>(k_count * k_count), 0); + input_data_ = InType(static_cast::size_type>(k_count * k_count), 0); for (int i = 0; i < k_count; i++) { - GetTestInput()[(i * k_count) + i] = 1; + input_data_[(i * k_count) + i] = 1; } } - void CheckTestOutputData() final { EXPECT_EQ(GetTestInput(), GetTaskPtr()->GetOutput()); } + bool CheckTestOutputData(OutType& output_data) final { return input_data_ == output_data; } + + InType GetTestInputData() final { return input_data_; } }; -TEST_P(NesterovARunFuncTests, MatmulFromPic) { ExecuteTest(); } +TEST_P(NesterovARunFuncTests, MatmulFromPic) { ExecuteTest(GetParam()); } #define ADD_FUNC_TASK(TASK) \ std::make_tuple(ppc::core::TaskGetter, ppc::util::GetNamespace(), 5), \ From c81c99b2c7daeb1d3338776ab962b593e2fbc08a Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Thu, 29 May 2025 15:34:26 +0200 Subject: [PATCH 024/141] Refactor test suite instantiation for modularity. Replaced hardcoded task tuples with dynamic generation using templates for better scalability and reusability. Added utility functions to simplify tuple expansion for test parameterization, improving code maintainability. --- modules/core/util/include/test_util.hpp | 23 +++++++++++++++++++++++ tasks/example/tests/func_tests/main.cpp | 24 ++++++++++++------------ 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/test_util.hpp index ea238912e..0953ef13d 100644 --- a/modules/core/util/include/test_util.hpp +++ b/modules/core/util/include/test_util.hpp @@ -97,4 +97,27 @@ class BaseRunFuncTests : public ::testing::TestWithParam task_; }; +template +auto ExpandToValuesImpl(const Tuple& t, std::index_sequence) { + return ::testing::Values(std::get(t)...); +} + +template +auto ExpandToValues(const Tuple& t) { + constexpr std::size_t N = std::tuple_size_v; + return ExpandToValuesImpl(t, std::make_index_sequence{}); +} + +#define DEFINE_GEN_TASK_TUPLES(InTypeParam, SizesParam) \ + template \ + auto GenTaskTuplesImpl(std::index_sequence) { \ + return std::make_tuple(std::make_tuple(ppc::core::TaskGetter, ppc::util::GetNamespace(), \ + SizesParam[Is])...); \ + } \ + \ + template \ + auto GenTaskTuples() { \ + return GenTaskTuplesImpl(std::make_index_sequence{}); \ + } + } // namespace ppc::util diff --git a/tasks/example/tests/func_tests/main.cpp b/tasks/example/tests/func_tests/main.cpp index 5efbdece0..c37413d7f 100644 --- a/tasks/example/tests/func_tests/main.cpp +++ b/tasks/example/tests/func_tests/main.cpp @@ -21,6 +21,7 @@ using TestType = int; class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests { InType input_data_; + public: static std::string CustomFuncTestName( const ::testing::TestParamInfo> &info) { @@ -43,7 +44,7 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests(data, data + (static_cast(width * height * channels))); stbi_image_free(data); - if(width != height) { + if (width != height) { throw std::runtime_error("width != height: "); } } @@ -55,22 +56,21 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests, ppc::util::GetNamespace(), 5), \ - std::make_tuple(ppc::core::TaskGetter, ppc::util::GetNamespace(), 10) +constexpr std::array kTestParam = {5, 10, 15}; + +DEFINE_GEN_TASK_TUPLES(InType, kTestParam) + +static auto tasks_list = std::tuple_cat( + GenTaskTuples(), GenTaskTuples(), + GenTaskTuples(), GenTaskTuples(), + GenTaskTuples(), GenTaskTuples()); -INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTests, - ::testing::Values(ADD_FUNC_TASK(nesterov_a_test_task_all::TestTaskALL), - ADD_FUNC_TASK(nesterov_a_test_task_mpi::TestTaskMPI), - ADD_FUNC_TASK(nesterov_a_test_task_omp::TestTaskOMP), - ADD_FUNC_TASK(nesterov_a_test_task_seq::TestTaskSEQ), - ADD_FUNC_TASK(nesterov_a_test_task_stl::TestTaskSTL), - ADD_FUNC_TASK(nesterov_a_test_task_tbb::TestTaskTBB)), +INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTests, ppc::util::ExpandToValues(tasks_list), NesterovARunFuncTests::CustomFuncTestName); From 1148c77febf5f434af0943e73bea5c0901e63d67 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Thu, 29 May 2025 16:01:21 +0200 Subject: [PATCH 025/141] Refactor test parameters to use GTestFuncParam alias Replaced inline TestParamInfo definitions with the GTestFuncParam alias to improve readability and maintainability. This ensures consistent usage of type aliases across the codebase and reduces redundancy in test parameter handling. --- modules/core/util/include/test_util.hpp | 3 +++ tasks/example/tests/func_tests/main.cpp | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/test_util.hpp index 0953ef13d..5d6289c9f 100644 --- a/modules/core/util/include/test_util.hpp +++ b/modules/core/util/include/test_util.hpp @@ -22,6 +22,9 @@ inline std::string GetStringParamName(ppc::core::PerfResults::TypeOfRunning type template using FuncTestParam = std::tuple(InType)>, std::string, TestType>; +template +using GTestFuncParam = ::testing::TestParamInfo>; + template using PerfTestParam = FuncTestParam; diff --git a/tasks/example/tests/func_tests/main.cpp b/tasks/example/tests/func_tests/main.cpp index c37413d7f..fa568886e 100644 --- a/tasks/example/tests/func_tests/main.cpp +++ b/tasks/example/tests/func_tests/main.cpp @@ -23,8 +23,7 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests> &info) { + static std::string CustomFuncTestName(const ppc::util::GTestFuncParam &info) { std::string test_name = std::get(info.param); std::string test_param = std::to_string(std::get(info.param)); return test_name + "_" + test_param; From 929d3570ee3a5b7a69c94fd216180899fed4ba29 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Thu, 29 May 2025 16:17:33 +0200 Subject: [PATCH 026/141] Refactor task generation macro for clarity and simplicity Renamed `DEFINE_GEN_TASK_TUPLES` to `DEFINE_GEN_TASK` and updated associated functions to streamline task generation. Simplified code structure by adjusting macro usage and wrapping test cases in an anonymous namespace for better encapsulation. --- modules/core/util/include/test_util.hpp | 4 ++-- tasks/example/tests/func_tests/main.cpp | 16 ++++++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/test_util.hpp index 5d6289c9f..6a891093b 100644 --- a/modules/core/util/include/test_util.hpp +++ b/modules/core/util/include/test_util.hpp @@ -111,7 +111,7 @@ auto ExpandToValues(const Tuple& t) { return ExpandToValuesImpl(t, std::make_index_sequence{}); } -#define DEFINE_GEN_TASK_TUPLES(InTypeParam, SizesParam) \ +#define DEFINE_GEN_TASK(InTypeParam, SizesParam) \ template \ auto GenTaskTuplesImpl(std::index_sequence) { \ return std::make_tuple(std::make_tuple(ppc::core::TaskGetter, ppc::util::GetNamespace(), \ @@ -119,7 +119,7 @@ auto ExpandToValues(const Tuple& t) { } \ \ template \ - auto GenTaskTuples() { \ + auto GenTask() { \ return GenTaskTuplesImpl(std::make_index_sequence{}); \ } diff --git a/tasks/example/tests/func_tests/main.cpp b/tasks/example/tests/func_tests/main.cpp index fa568886e..bdaadf94c 100644 --- a/tasks/example/tests/func_tests/main.cpp +++ b/tasks/example/tests/func_tests/main.cpp @@ -60,16 +60,20 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests kTestParam = {5, 10, 15}; -DEFINE_GEN_TASK_TUPLES(InType, kTestParam) +DEFINE_GEN_TASK(InType, kTestParam) -static auto tasks_list = std::tuple_cat( - GenTaskTuples(), GenTaskTuples(), - GenTaskTuples(), GenTaskTuples(), - GenTaskTuples(), GenTaskTuples()); +const auto kTasksList = + std::tuple_cat(GenTask(), GenTask(), + GenTask(), GenTask(), + GenTask(), GenTask()); -INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTests, ppc::util::ExpandToValues(tasks_list), +INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTests, ppc::util::ExpandToValues(kTasksList), NesterovARunFuncTests::CustomFuncTestName); + +} // namespace From bb725d229e5331dd43e2d5416669e6a0e84a5d10 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Thu, 29 May 2025 18:39:34 +0200 Subject: [PATCH 027/141] Rename task classes and enums for improved clarity. Updated task class names across all modules to follow the NesterovATestTask* naming convention. Renamed the `FuncTestParamIndex` enum to `TestParamIndex` for consistency. Adjusted related function definitions and testing suits accordingly. --- modules/core/util/include/test_util.hpp | 18 +++++++------- tasks/example/all/include/ops_all.hpp | 4 +-- tasks/example/all/src/ops_all.cpp | 10 ++++---- tasks/example/mpi/include/ops_mpi.hpp | 4 +-- tasks/example/mpi/src/ops_mpi.cpp | 12 ++++----- tasks/example/omp/include/ops_omp.hpp | 4 +-- tasks/example/omp/src/ops_omp.cpp | 10 ++++---- tasks/example/seq/include/ops_seq.hpp | 4 +-- tasks/example/seq/src/ops_seq.cpp | 10 ++++---- tasks/example/stl/include/ops_stl.hpp | 4 +-- tasks/example/stl/src/ops_stl.cpp | 10 ++++---- tasks/example/tbb/include/ops_tbb.hpp | 4 +-- tasks/example/tbb/src/ops_tbb.cpp | 10 ++++---- tasks/example/tests/func_tests/main.cpp | 33 ++++++++++++------------- tasks/example/tests/perf_tests/main.cpp | 17 +++++++------ 15 files changed, 77 insertions(+), 77 deletions(-) diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/test_util.hpp index 6a891093b..39f747358 100644 --- a/modules/core/util/include/test_util.hpp +++ b/modules/core/util/include/test_util.hpp @@ -7,7 +7,7 @@ namespace ppc::util { -enum FuncTestParamIndex : uint8_t { kTaskGetter, kNameTest, kTestParams }; +enum TestParamIndex : uint8_t { kTaskGetter, kNameTest, kTestParams }; inline std::string GetStringParamName(ppc::core::PerfResults::TypeOfRunning type_of_running) { if (type_of_running == core::PerfResults::kTaskRun) { @@ -32,8 +32,8 @@ template class BaseRunPerfTests : public ::testing::TestWithParam> { public: static std::string CustomPerfTestName(const ::testing::TestParamInfo>& info) { - return ppc::util::GetStringParamName(std::get(info.param)) + "_" + - std::get(info.param); + return ppc::util::GetStringParamName(std::get(info.param)) + "_" + + std::get(info.param); } protected: @@ -42,9 +42,9 @@ class BaseRunPerfTests : public ::testing::TestWithParam& perf_test_param) { - auto task_getter = std::get(perf_test_param); - auto test_name = std::get(perf_test_param); - auto mode = std::get(perf_test_param); + auto task_getter = std::get(perf_test_param); + auto test_name = std::get(perf_test_param); + auto mode = std::get(perf_test_param); task_ = task_getter(GetTestInputData()); ppc::core::Perf perf(task_); @@ -88,7 +88,7 @@ class BaseRunFuncTests : public ::testing::TestWithParam test_param) { - task_ = std::get(test_param)(GetTestInputData()); + task_ = std::get(test_param)(GetTestInputData()); ASSERT_TRUE(task_->Validation()); ASSERT_TRUE(task_->PreProcessing()); ASSERT_TRUE(task_->Run()); @@ -111,7 +111,7 @@ auto ExpandToValues(const Tuple& t) { return ExpandToValuesImpl(t, std::make_index_sequence{}); } -#define DEFINE_GEN_TASK(InTypeParam, SizesParam) \ +#define INIT_TASK_GENERATOR(InTypeParam, SizesParam) \ template \ auto GenTaskTuplesImpl(std::index_sequence) { \ return std::make_tuple(std::make_tuple(ppc::core::TaskGetter, ppc::util::GetNamespace(), \ @@ -119,7 +119,7 @@ auto ExpandToValues(const Tuple& t) { } \ \ template \ - auto GenTask() { \ + auto TaskListGenerator() { \ return GenTaskTuplesImpl(std::make_index_sequence{}); \ } diff --git a/tasks/example/all/include/ops_all.hpp b/tasks/example/all/include/ops_all.hpp index 5d5163012..77f05b822 100644 --- a/tasks/example/all/include/ops_all.hpp +++ b/tasks/example/all/include/ops_all.hpp @@ -13,9 +13,9 @@ void MatMulTBB(const std::vector &in_vec, int rc_size, std::vector &ou using InType = std::vector; using OutType = std::vector; -class TestTaskALL : public ppc::core::Task { +class NesterovATestTaskALL : public ppc::core::Task { public: - explicit TestTaskALL(const InType &in); + explicit NesterovATestTaskALL(const InType &in); bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; diff --git a/tasks/example/all/src/ops_all.cpp b/tasks/example/all/src/ops_all.cpp index 8ef7285ef..190a7ead0 100644 --- a/tasks/example/all/src/ops_all.cpp +++ b/tasks/example/all/src/ops_all.cpp @@ -27,21 +27,21 @@ void nesterov_a_test_task_all::MatMulTBB(const InType &in_vec, int rc_size, OutT MatMul(in_vec, rc_size, out_vec); } -nesterov_a_test_task_all::TestTaskALL::TestTaskALL(const InType &in) { GetInput() = in; } +nesterov_a_test_task_all::NesterovATestTaskALL::NesterovATestTaskALL(const InType &in) { GetInput() = in; } -bool nesterov_a_test_task_all::TestTaskALL::ValidationImpl() { +bool nesterov_a_test_task_all::NesterovATestTaskALL::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task_all::TestTaskALL::PreProcessingImpl() { +bool nesterov_a_test_task_all::NesterovATestTaskALL::PreProcessingImpl() { // Init value for input and output rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task_all::TestTaskALL::RunImpl() { +bool nesterov_a_test_task_all::NesterovATestTaskALL::RunImpl() { int rank = -1; MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { @@ -65,4 +65,4 @@ bool nesterov_a_test_task_all::TestTaskALL::RunImpl() { return true; } -bool nesterov_a_test_task_all::TestTaskALL::PostProcessingImpl() { return true; } +bool nesterov_a_test_task_all::NesterovATestTaskALL::PostProcessingImpl() { return true; } diff --git a/tasks/example/mpi/include/ops_mpi.hpp b/tasks/example/mpi/include/ops_mpi.hpp index e0e3d5863..b608a9c28 100644 --- a/tasks/example/mpi/include/ops_mpi.hpp +++ b/tasks/example/mpi/include/ops_mpi.hpp @@ -13,9 +13,9 @@ void MultiplyColumnMajor(const std::vector &in, std::vector &out, int using InType = std::vector; using OutType = std::vector; -class TestTaskMPI : public ppc::core::Task { +class NesterovATestTaskMPI : public ppc::core::Task { public: - explicit TestTaskMPI(const InType &in); + explicit NesterovATestTaskMPI(const InType &in); bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; diff --git a/tasks/example/mpi/src/ops_mpi.cpp b/tasks/example/mpi/src/ops_mpi.cpp index 1be470a83..c88709aaa 100644 --- a/tasks/example/mpi/src/ops_mpi.cpp +++ b/tasks/example/mpi/src/ops_mpi.cpp @@ -26,28 +26,28 @@ void nesterov_a_test_task_mpi::MultiplyColumnMajor(const InType &in, OutType &ou } } -nesterov_a_test_task_mpi::TestTaskMPI::TestTaskMPI(const InType &in) { GetInput() = in; } +nesterov_a_test_task_mpi::NesterovATestTaskMPI::NesterovATestTaskMPI(const InType &in) { GetInput() = in; } -bool nesterov_a_test_task_mpi::TestTaskMPI::ValidationImpl() { +bool nesterov_a_test_task_mpi::NesterovATestTaskMPI::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task_mpi::TestTaskMPI::PreProcessingImpl() { +bool nesterov_a_test_task_mpi::NesterovATestTaskMPI::PreProcessingImpl() { // Init value for input and output rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task_mpi::TestTaskMPI::RunImpl() { +bool nesterov_a_test_task_mpi::NesterovATestTaskMPI::RunImpl() { MultiplyMatrixBasedOnRank(); return true; } -bool nesterov_a_test_task_mpi::TestTaskMPI::PostProcessingImpl() { return true; } +bool nesterov_a_test_task_mpi::NesterovATestTaskMPI::PostProcessingImpl() { return true; } -void nesterov_a_test_task_mpi::TestTaskMPI::MultiplyMatrixBasedOnRank() { +void nesterov_a_test_task_mpi::NesterovATestTaskMPI::MultiplyMatrixBasedOnRank() { int rank = -1; MPI_Comm_rank(MPI_COMM_WORLD, &rank); diff --git a/tasks/example/omp/include/ops_omp.hpp b/tasks/example/omp/include/ops_omp.hpp index e043e39c0..a7fcf8c93 100644 --- a/tasks/example/omp/include/ops_omp.hpp +++ b/tasks/example/omp/include/ops_omp.hpp @@ -10,9 +10,9 @@ namespace nesterov_a_test_task_omp { using InType = std::vector; using OutType = std::vector; -class TestTaskOMP : public ppc::core::Task { +class NesterovATestTaskOMP : public ppc::core::Task { public: - explicit TestTaskOMP(const InType& in); + explicit NesterovATestTaskOMP(const InType& in); bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; diff --git a/tasks/example/omp/src/ops_omp.cpp b/tasks/example/omp/src/ops_omp.cpp index 87cf9cee1..568841c44 100644 --- a/tasks/example/omp/src/ops_omp.cpp +++ b/tasks/example/omp/src/ops_omp.cpp @@ -4,20 +4,20 @@ #include #include -nesterov_a_test_task_omp::TestTaskOMP::TestTaskOMP(const InType& in) { GetInput() = in; } +nesterov_a_test_task_omp::NesterovATestTaskOMP::NesterovATestTaskOMP(const InType& in) { GetInput() = in; } -bool nesterov_a_test_task_omp::TestTaskOMP::ValidationImpl() { +bool nesterov_a_test_task_omp::NesterovATestTaskOMP::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task_omp::TestTaskOMP::PreProcessingImpl() { +bool nesterov_a_test_task_omp::NesterovATestTaskOMP::PreProcessingImpl() { rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task_omp::TestTaskOMP::RunImpl() { +bool nesterov_a_test_task_omp::NesterovATestTaskOMP::RunImpl() { #pragma omp parallel default(none) { #pragma omp critical @@ -36,4 +36,4 @@ bool nesterov_a_test_task_omp::TestTaskOMP::RunImpl() { return true; } -bool nesterov_a_test_task_omp::TestTaskOMP::PostProcessingImpl() { return true; } +bool nesterov_a_test_task_omp::NesterovATestTaskOMP::PostProcessingImpl() { return true; } diff --git a/tasks/example/seq/include/ops_seq.hpp b/tasks/example/seq/include/ops_seq.hpp index ac5f3cb1e..904214480 100644 --- a/tasks/example/seq/include/ops_seq.hpp +++ b/tasks/example/seq/include/ops_seq.hpp @@ -10,9 +10,9 @@ namespace nesterov_a_test_task_seq { using InType = std::vector; using OutType = std::vector; -class TestTaskSEQ : public ppc::core::Task { +class NesterovATestTaskSEQ : public ppc::core::Task { public: - explicit TestTaskSEQ(const InType& in); + explicit NesterovATestTaskSEQ(const InType& in); bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; diff --git a/tasks/example/seq/src/ops_seq.cpp b/tasks/example/seq/src/ops_seq.cpp index dfe608328..26b95ec81 100644 --- a/tasks/example/seq/src/ops_seq.cpp +++ b/tasks/example/seq/src/ops_seq.cpp @@ -4,20 +4,20 @@ #include #include -nesterov_a_test_task_seq::TestTaskSEQ::TestTaskSEQ(const InType& in) { GetInput() = in; } +nesterov_a_test_task_seq::NesterovATestTaskSEQ::NesterovATestTaskSEQ(const InType& in) { GetInput() = in; } -bool nesterov_a_test_task_seq::TestTaskSEQ::ValidationImpl() { +bool nesterov_a_test_task_seq::NesterovATestTaskSEQ::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task_seq::TestTaskSEQ::PreProcessingImpl() { +bool nesterov_a_test_task_seq::NesterovATestTaskSEQ::PreProcessingImpl() { rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task_seq::TestTaskSEQ::RunImpl() { +bool nesterov_a_test_task_seq::NesterovATestTaskSEQ::RunImpl() { // Multiply matrices for (int i = 0; i < rc_size_; ++i) { for (int j = 0; j < rc_size_; ++j) { @@ -29,4 +29,4 @@ bool nesterov_a_test_task_seq::TestTaskSEQ::RunImpl() { return true; } -bool nesterov_a_test_task_seq::TestTaskSEQ::PostProcessingImpl() { return true; } +bool nesterov_a_test_task_seq::NesterovATestTaskSEQ::PostProcessingImpl() { return true; } diff --git a/tasks/example/stl/include/ops_stl.hpp b/tasks/example/stl/include/ops_stl.hpp index 8932b18f2..c33ae78ed 100644 --- a/tasks/example/stl/include/ops_stl.hpp +++ b/tasks/example/stl/include/ops_stl.hpp @@ -10,9 +10,9 @@ namespace nesterov_a_test_task_stl { using InType = std::vector; using OutType = std::vector; -class TestTaskSTL : public ppc::core::Task { +class NesterovATestTaskSTL : public ppc::core::Task { public: - explicit TestTaskSTL(const InType& in); + explicit NesterovATestTaskSTL(const InType& in); bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; diff --git a/tasks/example/stl/src/ops_stl.cpp b/tasks/example/stl/src/ops_stl.cpp index 83fa2e0cf..e7abb2ff7 100644 --- a/tasks/example/stl/src/ops_stl.cpp +++ b/tasks/example/stl/src/ops_stl.cpp @@ -21,20 +21,20 @@ void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_v } } // namespace -nesterov_a_test_task_stl::TestTaskSTL::TestTaskSTL(const InType &in) { GetInput() = in; } +nesterov_a_test_task_stl::NesterovATestTaskSTL::NesterovATestTaskSTL(const InType &in) { GetInput() = in; } -bool nesterov_a_test_task_stl::TestTaskSTL::ValidationImpl() { +bool nesterov_a_test_task_stl::NesterovATestTaskSTL::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task_stl::TestTaskSTL::PreProcessingImpl() { +bool nesterov_a_test_task_stl::NesterovATestTaskSTL::PreProcessingImpl() { rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task_stl::TestTaskSTL::RunImpl() { +bool nesterov_a_test_task_stl::NesterovATestTaskSTL::RunImpl() { const int num_threads = ppc::util::GetPPCNumThreads(); std::vector threads(num_threads); for (int i = 0; i < num_threads; i++) { @@ -44,4 +44,4 @@ bool nesterov_a_test_task_stl::TestTaskSTL::RunImpl() { return true; } -bool nesterov_a_test_task_stl::TestTaskSTL::PostProcessingImpl() { return true; } +bool nesterov_a_test_task_stl::NesterovATestTaskSTL::PostProcessingImpl() { return true; } diff --git a/tasks/example/tbb/include/ops_tbb.hpp b/tasks/example/tbb/include/ops_tbb.hpp index ce6449f96..bf4408510 100644 --- a/tasks/example/tbb/include/ops_tbb.hpp +++ b/tasks/example/tbb/include/ops_tbb.hpp @@ -10,9 +10,9 @@ namespace nesterov_a_test_task_tbb { using InType = std::vector; using OutType = std::vector; -class TestTaskTBB : public ppc::core::Task { +class NesterovATestTaskTBB : public ppc::core::Task { public: - explicit TestTaskTBB(const InType& in); + explicit NesterovATestTaskTBB(const InType& in); bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; diff --git a/tasks/example/tbb/src/ops_tbb.cpp b/tasks/example/tbb/src/ops_tbb.cpp index 51d6bd079..4c26f09bd 100644 --- a/tasks/example/tbb/src/ops_tbb.cpp +++ b/tasks/example/tbb/src/ops_tbb.cpp @@ -22,23 +22,23 @@ void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_v } } // namespace -nesterov_a_test_task_tbb::TestTaskTBB::TestTaskTBB(const InType &in) { GetInput() = in; } +nesterov_a_test_task_tbb::NesterovATestTaskTBB::NesterovATestTaskTBB(const InType &in) { GetInput() = in; } -bool nesterov_a_test_task_tbb::TestTaskTBB::ValidationImpl() { +bool nesterov_a_test_task_tbb::NesterovATestTaskTBB::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task_tbb::TestTaskTBB::PreProcessingImpl() { +bool nesterov_a_test_task_tbb::NesterovATestTaskTBB::PreProcessingImpl() { rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task_tbb::TestTaskTBB::RunImpl() { +bool nesterov_a_test_task_tbb::NesterovATestTaskTBB::RunImpl() { tbb::parallel_for(0, ppc::util::GetPPCNumThreads(), [&](int i) { MatMul(GetInput(), rc_size_ - i, GetOutput()); }); MatMul(GetInput(), rc_size_, GetOutput()); return true; } -bool nesterov_a_test_task_tbb::TestTaskTBB::PostProcessingImpl() { return true; } +bool nesterov_a_test_task_tbb::NesterovATestTaskTBB::PostProcessingImpl() { return true; } diff --git a/tasks/example/tests/func_tests/main.cpp b/tasks/example/tests/func_tests/main.cpp index bdaadf94c..85eb06564 100644 --- a/tasks/example/tests/func_tests/main.cpp +++ b/tasks/example/tests/func_tests/main.cpp @@ -22,13 +22,6 @@ using TestType = int; class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests { InType input_data_; - public: - static std::string CustomFuncTestName(const ppc::util::GTestFuncParam &info) { - std::string test_name = std::get(info.param); - std::string test_param = std::to_string(std::get(info.param)); - return test_name + "_" + test_param; - } - protected: void SetUp() override { int width = -1; @@ -48,7 +41,7 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests(GetParam()); + const int k_count = (width + height) / std::get(GetParam()); input_data_ = InType(static_cast::size_type>(k_count * k_count), 0); for (int i = 0; i < k_count; i++) { input_data_[(i * k_count) + i] = 1; @@ -66,14 +59,20 @@ TEST_P(NesterovARunFuncTests, MatmulFromPic) { ExecuteTest(GetParam()); } constexpr std::array kTestParam = {5, 10, 15}; -DEFINE_GEN_TASK(InType, kTestParam) - -const auto kTasksList = - std::tuple_cat(GenTask(), GenTask(), - GenTask(), GenTask(), - GenTask(), GenTask()); - -INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTests, ppc::util::ExpandToValues(kTasksList), - NesterovARunFuncTests::CustomFuncTestName); +INIT_TASK_GENERATOR(InType, kTestParam) + +const auto kTestTasksList = std::tuple_cat(TaskListGenerator(), + TaskListGenerator(), + TaskListGenerator(), + TaskListGenerator(), + TaskListGenerator(), + TaskListGenerator()); + +INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTests, ppc::util::ExpandToValues(kTestTasksList), + [](const auto &info) { + std::string test_name = std::get(info.param); + TestType test_param = std::get(info.param); + return test_name + "_" + std::to_string(test_param); + }); } // namespace diff --git a/tasks/example/tests/perf_tests/main.cpp b/tasks/example/tests/perf_tests/main.cpp index 6f9a53d0b..1437b254e 100644 --- a/tasks/example/tests/perf_tests/main.cpp +++ b/tasks/example/tests/perf_tests/main.cpp @@ -45,11 +45,12 @@ class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { TEST_P(ExampleRunPerfTest, RunPerfModes) { ExecuteTest(GetParam()); } -INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, ExampleRunPerfTest, - ::testing::Values(ADD_PERF_MODES(nesterov_a_test_task_all::TestTaskALL, InType), - ADD_PERF_MODES(nesterov_a_test_task_mpi::TestTaskMPI, InType), - ADD_PERF_MODES(nesterov_a_test_task_omp::TestTaskOMP, InType), - ADD_PERF_MODES(nesterov_a_test_task_seq::TestTaskSEQ, InType), - ADD_PERF_MODES(nesterov_a_test_task_stl::TestTaskSTL, InType), - ADD_PERF_MODES(nesterov_a_test_task_tbb::TestTaskTBB, InType)), - ExampleRunPerfTest::CustomPerfTestName); +INSTANTIATE_TEST_SUITE_P_NOLINT( + RunModeTests, ExampleRunPerfTest, + ::testing::Values(ADD_PERF_MODES(nesterov_a_test_task_all::NesterovATestTaskALL, InType), + ADD_PERF_MODES(nesterov_a_test_task_mpi::NesterovATestTaskMPI, InType), + ADD_PERF_MODES(nesterov_a_test_task_omp::NesterovATestTaskOMP, InType), + ADD_PERF_MODES(nesterov_a_test_task_seq::NesterovATestTaskSEQ, InType), + ADD_PERF_MODES(nesterov_a_test_task_stl::NesterovATestTaskSTL, InType), + ADD_PERF_MODES(nesterov_a_test_task_tbb::NesterovATestTaskTBB, InType)), + ExampleRunPerfTest::CustomPerfTestName); From 21f1dcf0dfbc6a1051320105fd8144d818faf479 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Thu, 29 May 2025 19:23:56 +0200 Subject: [PATCH 028/141] Refactor test parameter handling for clarity and flexibility Simplified the `FuncTestParam` type usage by removing redundant namespace prefixes and updated the test name generation logic for better reuse. Introduced a static interface requirement and concept check to ensure derived classes implement `PrintTestParam`. These changes improve code readability and enforce clearer contracts for test classes. --- modules/core/util/include/test_util.hpp | 38 ++++++++++++++++++------- tasks/example/tests/func_tests/main.cpp | 12 ++++---- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/test_util.hpp index 39f747358..f46df2a22 100644 --- a/modules/core/util/include/test_util.hpp +++ b/modules/core/util/include/test_util.hpp @@ -23,7 +23,7 @@ template using FuncTestParam = std::tuple(InType)>, std::string, TestType>; template -using GTestFuncParam = ::testing::TestParamInfo>; +using GTestFuncParam = ::testing::TestParamInfo>; template using PerfTestParam = FuncTestParam; @@ -42,9 +42,9 @@ class BaseRunPerfTests : public ::testing::TestWithParam& perf_test_param) { - auto task_getter = std::get(perf_test_param); - auto test_name = std::get(perf_test_param); - auto mode = std::get(perf_test_param); + auto task_getter = std::get(perf_test_param); + auto test_name = std::get(perf_test_param); + auto mode = std::get(perf_test_param); task_ = task_getter(GetTestInputData()); ppc::core::Perf perf(task_); @@ -80,15 +80,33 @@ class BaseRunPerfTests : public ::testing::TestWithParam, ppc::util::GetNamespace(), \ ppc::core::PerfResults::TypeOfRunning::kTaskRun) +template +concept HasPrintTestParam = requires(TestType value) { + { T::PrintTestParam(value) } -> std::same_as; +}; + template -class BaseRunFuncTests : public ::testing::TestWithParam> { +class BaseRunFuncTests : public ::testing::TestWithParam> { public: virtual bool CheckTestOutputData(OutType& output_data) = 0; virtual InType GetTestInputData() = 0; + template + static void require_static_interface() { + static_assert(HasPrintTestParam, + "Derived class must implement: static std::string PrintTestParam(TestType)"); + } + + template + static std::string PrintFuncTestName(const GTestFuncParam& info) { + require_static_interface(); + TestType test_param = std::get(info.param); + return std::get(info.param) + "_" + Derived::PrintTestParam(test_param); + } + protected: - void ExecuteTest(ppc::util::FuncTestParam test_param) { - task_ = std::get(test_param)(GetTestInputData()); + void ExecuteTest(FuncTestParam test_param) { + task_ = std::get(test_param)(GetTestInputData()); ASSERT_TRUE(task_->Validation()); ASSERT_TRUE(task_->PreProcessing()); ASSERT_TRUE(task_->Run()); @@ -101,14 +119,14 @@ class BaseRunFuncTests : public ::testing::TestWithParam -auto ExpandToValuesImpl(const Tuple& t, std::index_sequence) { +auto ExpandToValuesImpl(const Tuple& t, std::index_sequence /*unused*/) { return ::testing::Values(std::get(t)...); } template auto ExpandToValues(const Tuple& t) { - constexpr std::size_t N = std::tuple_size_v; - return ExpandToValuesImpl(t, std::make_index_sequence{}); + constexpr std::size_t kN = std::tuple_size_v; + return ExpandToValuesImpl(t, std::make_index_sequence{}); } #define INIT_TASK_GENERATOR(InTypeParam, SizesParam) \ diff --git a/tasks/example/tests/func_tests/main.cpp b/tasks/example/tests/func_tests/main.cpp index 85eb06564..615594cf5 100644 --- a/tasks/example/tests/func_tests/main.cpp +++ b/tasks/example/tests/func_tests/main.cpp @@ -22,6 +22,9 @@ using TestType = int; class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests { InType input_data_; + public: + static std::string PrintTestParam(TestType test_param) { return std::to_string(test_param); } + protected: void SetUp() override { int width = -1; @@ -41,7 +44,8 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests(GetParam()); + TestType divider = std::get(GetParam()); + const int k_count = (width + height) / divider; input_data_ = InType(static_cast::size_type>(k_count * k_count), 0); for (int i = 0; i < k_count; i++) { input_data_[(i * k_count) + i] = 1; @@ -69,10 +73,6 @@ const auto kTestTasksList = std::tuple_cat(TaskListGenerator()); INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTests, ppc::util::ExpandToValues(kTestTasksList), - [](const auto &info) { - std::string test_name = std::get(info.param); - TestType test_param = std::get(info.param); - return test_name + "_" + std::to_string(test_param); - }); + NesterovARunFuncTests::PrintFuncTestName); } // namespace From 5016f3d4bcb6472a32f184621fd238bcbff8a315 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Thu, 29 May 2025 19:36:57 +0200 Subject: [PATCH 029/141] Refactor type usage and improve code clarity. Replaced `int` with `unsigned` for clearer intent in loop variables and constants. Added explicit type casting and updated static method naming for better alignment with naming conventions. These changes enhance code readability and maintain consistency. --- modules/core/util/include/test_util.hpp | 4 ++-- tasks/example/tests/perf_tests/main.cpp | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/test_util.hpp index f46df2a22..a4fbaf215 100644 --- a/modules/core/util/include/test_util.hpp +++ b/modules/core/util/include/test_util.hpp @@ -92,14 +92,14 @@ class BaseRunFuncTests : public ::testing::TestWithParam - static void require_static_interface() { + static void RequireStaticInterface() { static_assert(HasPrintTestParam, "Derived class must implement: static std::string PrintTestParam(TestType)"); } template static std::string PrintFuncTestName(const GTestFuncParam& info) { - require_static_interface(); + RequireStaticInterface(); TestType test_param = std::get(info.param); return std::get(info.param) + "_" + Derived::PrintTestParam(test_param); } diff --git a/tasks/example/tests/perf_tests/main.cpp b/tasks/example/tests/perf_tests/main.cpp index 1437b254e..d6f5db02a 100644 --- a/tasks/example/tests/perf_tests/main.cpp +++ b/tasks/example/tests/perf_tests/main.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -19,12 +20,12 @@ using InType = std::vector; using OutType = std::vector; class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { - static constexpr int kCount = 400; + static constexpr unsigned kCount = 400; InType input_data_; void SetUp() override { - input_data_.assign(kCount * kCount, 0); - for (int i = 0; i < kCount; ++i) { + input_data_.assign(static_cast::size_type>(kCount * kCount), 0); + for (unsigned i = 0; i < kCount; ++i) { input_data_[(i * kCount) + i] = 1; } } From 9172d07af7d1d4079535f2c09f2eeb5b26b8e507 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Thu, 29 May 2025 19:43:41 +0200 Subject: [PATCH 030/141] Refactor test parameter handling and fix type consistency. Updated `TestType` to a tuple for enhanced parameter flexibility and adjusted related logic accordingly. Also fixed mismatched integer types in performance tests for improved consistency and correctness. --- tasks/example/tests/func_tests/main.cpp | 13 ++++++++----- tasks/example/tests/perf_tests/main.cpp | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tasks/example/tests/func_tests/main.cpp b/tasks/example/tests/func_tests/main.cpp index 615594cf5..74f3fcfc5 100644 --- a/tasks/example/tests/func_tests/main.cpp +++ b/tasks/example/tests/func_tests/main.cpp @@ -17,13 +17,15 @@ using InType = std::vector; using OutType = std::vector; -using TestType = int; +using TestType = std::tuple; class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests { InType input_data_; public: - static std::string PrintTestParam(TestType test_param) { return std::to_string(test_param); } + static std::string PrintTestParam(TestType test_param) { + return std::to_string(std::get<0>(test_param)) + "_" + std::get<1>(test_param); + } protected: void SetUp() override { @@ -44,8 +46,8 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests(GetParam()); - const int k_count = (width + height) / divider; + TestType params = std::get(GetParam()); + const int k_count = ((width + height) / std::get<0>(params)) * std::stoi(std::get<1>(params)); input_data_ = InType(static_cast::size_type>(k_count * k_count), 0); for (int i = 0; i < k_count; i++) { input_data_[(i * k_count) + i] = 1; @@ -61,7 +63,8 @@ namespace { TEST_P(NesterovARunFuncTests, MatmulFromPic) { ExecuteTest(GetParam()); } -constexpr std::array kTestParam = {5, 10, 15}; +constexpr std::array kTestParam = {std::make_tuple(5, "5"), std::make_tuple(10, "10"), + std::make_tuple(15, "15")}; INIT_TASK_GENERATOR(InType, kTestParam) diff --git a/tasks/example/tests/perf_tests/main.cpp b/tasks/example/tests/perf_tests/main.cpp index d6f5db02a..09280e699 100644 --- a/tasks/example/tests/perf_tests/main.cpp +++ b/tasks/example/tests/perf_tests/main.cpp @@ -24,7 +24,7 @@ class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { InType input_data_; void SetUp() override { - input_data_.assign(static_cast::size_type>(kCount * kCount), 0); + input_data_.assign(static_cast::size_type>(kCount * kCount), 0u); for (unsigned i = 0; i < kCount; ++i) { input_data_[(i * kCount) + i] = 1; } From f05e6a8cc57f3a1a7db841f0ecc3d3e54502f656 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Thu, 29 May 2025 19:58:55 +0200 Subject: [PATCH 031/141] Refactor index types to use `std::vector::size_type`. Updated index and count variables to consistently use `std::vector::size_type` for better type safety and clarity. This change ensures alignment with container type requirements and prevents potential implicit type casting issues. --- tasks/example/tests/func_tests/main.cpp | 10 ++++++---- tasks/example/tests/perf_tests/main.cpp | 6 +++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/tasks/example/tests/func_tests/main.cpp b/tasks/example/tests/func_tests/main.cpp index 74f3fcfc5..a7773dd32 100644 --- a/tasks/example/tests/func_tests/main.cpp +++ b/tasks/example/tests/func_tests/main.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "core/util/include/test_util.hpp" @@ -41,15 +42,16 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests(data, data + (static_cast(width * height * channels))); stbi_image_free(data); - if (width != height) { + if (std::cmp_not_equal(width, height)) { throw std::runtime_error("width != height: "); } } TestType params = std::get(GetParam()); - const int k_count = ((width + height) / std::get<0>(params)) * std::stoi(std::get<1>(params)); - input_data_ = InType(static_cast::size_type>(k_count * k_count), 0); - for (int i = 0; i < k_count; i++) { + const auto k_count = static_cast::size_type>(((width + height) / std::get<0>(params)) * + std::stoi(std::get<1>(params))); + input_data_ = InType(k_count * k_count, 0); + for (std::vector::size_type i = 0; i < k_count; i++) { input_data_[(i * k_count) + i] = 1; } } diff --git a/tasks/example/tests/perf_tests/main.cpp b/tasks/example/tests/perf_tests/main.cpp index 09280e699..469f73f27 100644 --- a/tasks/example/tests/perf_tests/main.cpp +++ b/tasks/example/tests/perf_tests/main.cpp @@ -20,12 +20,12 @@ using InType = std::vector; using OutType = std::vector; class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { - static constexpr unsigned kCount = 400; + static constexpr std::vector::size_type kCount = 400; InType input_data_; void SetUp() override { - input_data_.assign(static_cast::size_type>(kCount * kCount), 0u); - for (unsigned i = 0; i < kCount; ++i) { + input_data_.assign(kCount * kCount, 0U); + for (std::vector::size_type i = 0; i < kCount; ++i) { input_data_[(i * kCount) + i] = 1; } } From 84cc08324a5592534c792e41960d7fc27cde8131 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Fri, 30 May 2025 18:33:30 +0200 Subject: [PATCH 032/141] Use std::abort instead of std::exit for termination Replaced std::exit with std::abort in the custom termination handler to better align with modern C++ practices and avoid the need for specific exit codes. Also removed a redundant self-include to clean up the header file. --- modules/core/task/include/task.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/core/task/include/task.hpp b/modules/core/task/include/task.hpp index 6a6cf20e0..5069a6ec3 100644 --- a/modules/core/task/include/task.hpp +++ b/modules/core/task/include/task.hpp @@ -13,8 +13,6 @@ #include #include -#include "core/task/include/task.hpp" - using namespace std::chrono; namespace ppc::core { @@ -30,7 +28,7 @@ class Task { auto custom_terminate = []() { std::cerr << "ORDER OF FUNCTIONS IS NOT RIGHT! \n" "Expected - \"Validation\", \"PreProcessing\", \"Run\", \"PostProcessing\" \n"; - std::exit(404); + std::abort(); }; std::set_terminate(custom_terminate); functions_order_.clear(); From e240d5154bff50afdac944ac51d1608a20b19cf6 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 1 Jun 2025 00:47:41 +0200 Subject: [PATCH 033/141] Unify task namespaces and refactor common functionality. Replaced per-implementation task namespaces with a unified namespace `nesterov_a_test_task`. Introduced a common header to centralize shared definitions. Standardized task inheritance by introducing `BaseTask` and refactored related boilerplate for consistency. --- modules/core/perf/include/perf.hpp | 4 +- modules/core/task/include/task.hpp | 10 +++- modules/core/util/include/test_util.hpp | 74 +++++++++++++++++-------- tasks/example/all/include/ops_all.hpp | 12 ++-- tasks/example/all/src/ops_all.cpp | 14 ++--- tasks/example/common/include/common.hpp | 20 +++++++ tasks/example/mpi/include/ops_mpi.hpp | 11 ++-- tasks/example/mpi/src/ops_mpi.cpp | 16 +++--- tasks/example/omp/include/ops_omp.hpp | 11 ++-- tasks/example/omp/src/ops_omp.cpp | 10 ++-- tasks/example/seq/include/ops_seq.hpp | 11 ++-- tasks/example/seq/src/ops_seq.cpp | 10 ++-- tasks/example/stl/include/ops_stl.hpp | 11 ++-- tasks/example/stl/src/ops_stl.cpp | 10 ++-- tasks/example/tbb/include/ops_tbb.hpp | 11 ++-- tasks/example/tbb/src/ops_tbb.cpp | 10 ++-- tasks/example/tests/func_tests/main.cpp | 20 +++---- tasks/example/tests/perf_tests/main.cpp | 16 +++--- 18 files changed, 161 insertions(+), 120 deletions(-) create mode 100644 tasks/example/common/include/common.hpp diff --git a/modules/core/perf/include/perf.hpp b/modules/core/perf/include/perf.hpp index 6830ae4de..7ce1770ac 100644 --- a/modules/core/perf/include/perf.hpp +++ b/modules/core/perf/include/perf.hpp @@ -24,9 +24,9 @@ struct PerfResults { template class Perf { public: - // Init performance analysis with initialized task and initialized data + // Init performance analysis with an initialized task and initialized data explicit Perf(const TaskPtr& task_ptr) : task_(task_ptr) { - task_ptr->GetStateOfTesting() = Task::StateOfTesting::kPerf; + task_ptr->GetStateOfTesting() = StateOfTesting::kPerf; } // Check performance of full task's pipeline: PreProcessing() -> // Validation() -> Run() -> PostProcessing() diff --git a/modules/core/task/include/task.hpp b/modules/core/task/include/task.hpp index 5069a6ec3..84ef2a1f6 100644 --- a/modules/core/task/include/task.hpp +++ b/modules/core/task/include/task.hpp @@ -17,13 +17,14 @@ using namespace std::chrono; namespace ppc::core { -// Memory of inputs and outputs need to be initialized before create object of +enum TypeOfTask : uint8_t { kALL, kMPI, kOMP, kSEQ, kSTL, kTBB, kUnknown }; +enum StateOfTesting : uint8_t { kFunc, kPerf }; + +// Memory of inputs and outputs need to be initialized before create an object of // Task class template class Task { public: - enum StateOfTesting : uint8_t { kFunc, kPerf }; - explicit Task(StateOfTesting /*state_of_testing*/ = StateOfTesting::kFunc) { auto custom_terminate = []() { std::cerr << "ORDER OF FUNCTIONS IS NOT RIGHT! \n" @@ -67,6 +68,9 @@ class Task { // get state of testing StateOfTesting &GetStateOfTesting() { return state_of_testing_; } + // get a type of task + static constexpr TypeOfTask GetTypeOfTask() { return TypeOfTask::kUnknown; } + InType &GetInput() { return input_; } OutType &GetOutput() { return output_; } diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/test_util.hpp index a4fbaf215..0a8cc6df2 100644 --- a/modules/core/util/include/test_util.hpp +++ b/modules/core/util/include/test_util.hpp @@ -7,7 +7,7 @@ namespace ppc::util { -enum TestParamIndex : uint8_t { kTaskGetter, kNameTest, kTestParams }; +enum GTestParamIndex : uint8_t { kTaskGetter, kNameTest, kTestParams }; inline std::string GetStringParamName(ppc::core::PerfResults::TypeOfRunning type_of_running) { if (type_of_running == core::PerfResults::kTaskRun) { @@ -19,6 +19,28 @@ inline std::string GetStringParamName(ppc::core::PerfResults::TypeOfRunning type return "none"; } +inline std::string GetStringTaskType(ppc::core::TypeOfTask type_of_task) { + if (type_of_task == ppc::core::TypeOfTask::kALL) { + return "all"; + } + if (type_of_task == ppc::core::TypeOfTask::kSTL) { + return "stl"; + } + if (type_of_task == ppc::core::TypeOfTask::kOMP) { + return "omp"; + } + if (type_of_task == ppc::core::TypeOfTask::kMPI) { + return "mpi"; + } + if (type_of_task == ppc::core::TypeOfTask::kTBB) { + return "tbb"; + } + if (type_of_task == ppc::core::TypeOfTask::kSEQ) { + return "seq"; + } + return "unknown"; +} + template using FuncTestParam = std::tuple(InType)>, std::string, TestType>; @@ -32,8 +54,8 @@ template class BaseRunPerfTests : public ::testing::TestWithParam> { public: static std::string CustomPerfTestName(const ::testing::TestParamInfo>& info) { - return ppc::util::GetStringParamName(std::get(info.param)) + "_" + - std::get(info.param); + return ppc::util::GetStringParamName(std::get(info.param)) + "_" + + std::get(info.param); } protected: @@ -42,9 +64,9 @@ class BaseRunPerfTests : public ::testing::TestWithParam& perf_test_param) { - auto task_getter = std::get(perf_test_param); - auto test_name = std::get(perf_test_param); - auto mode = std::get(perf_test_param); + auto task_getter = std::get(perf_test_param); + auto test_name = std::get(perf_test_param); + auto mode = std::get(perf_test_param); task_ = task_getter(GetTestInputData()); ppc::core::Perf perf(task_); @@ -74,10 +96,14 @@ class BaseRunPerfTests : public ::testing::TestWithParam task_; }; -#define ADD_PERF_MODES(TaskType, InputTypeParam) \ - std::make_tuple(ppc::core::TaskGetter, ppc::util::GetNamespace(), \ - ppc::core::PerfResults::TypeOfRunning::kPipeline), \ - std::make_tuple(ppc::core::TaskGetter, ppc::util::GetNamespace(), \ +#define ADD_PERF_MODES(TaskType, InputTypeParam) \ + std::make_tuple(ppc::core::TaskGetter, \ + std::string(ppc::util::GetNamespace()) + std::string("_") + \ + ppc::util::GetStringTaskType(TaskType::GetTypeOfTask()), \ + ppc::core::PerfResults::TypeOfRunning::kPipeline), \ + std::make_tuple(ppc::core::TaskGetter, \ + std::string(ppc::util::GetNamespace()) + std::string("_") + \ + ppc::util::GetStringTaskType(TaskType::GetTypeOfTask()), \ ppc::core::PerfResults::TypeOfRunning::kTaskRun) template @@ -100,13 +126,13 @@ class BaseRunFuncTests : public ::testing::TestWithParam static std::string PrintFuncTestName(const GTestFuncParam& info) { RequireStaticInterface(); - TestType test_param = std::get(info.param); - return std::get(info.param) + "_" + Derived::PrintTestParam(test_param); + TestType test_param = std::get(info.param); + return std::get(info.param) + "_" + Derived::PrintTestParam(test_param); } protected: void ExecuteTest(FuncTestParam test_param) { - task_ = std::get(test_param)(GetTestInputData()); + task_ = std::get(test_param)(GetTestInputData()); ASSERT_TRUE(task_->Validation()); ASSERT_TRUE(task_->PreProcessing()); ASSERT_TRUE(task_->Run()); @@ -129,16 +155,18 @@ auto ExpandToValues(const Tuple& t) { return ExpandToValuesImpl(t, std::make_index_sequence{}); } -#define INIT_TASK_GENERATOR(InTypeParam, SizesParam) \ - template \ - auto GenTaskTuplesImpl(std::index_sequence) { \ - return std::make_tuple(std::make_tuple(ppc::core::TaskGetter, ppc::util::GetNamespace(), \ - SizesParam[Is])...); \ - } \ - \ - template \ - auto TaskListGenerator() { \ - return GenTaskTuplesImpl(std::make_index_sequence{}); \ +#define INIT_TASK_GENERATOR(InTypeParam, SizesParam) \ + template \ + auto GenTaskTuplesImpl(std::index_sequence) { \ + return std::make_tuple(std::make_tuple(ppc::core::TaskGetter, \ + std::string(ppc::util::GetNamespace()) + std::string("_") + \ + ppc::util::GetStringTaskType(Task::GetTypeOfTask()), \ + SizesParam[Is])...); \ + } \ + \ + template \ + auto TaskListGenerator() { \ + return GenTaskTuplesImpl(std::make_index_sequence{}); \ } } // namespace ppc::util diff --git a/tasks/example/all/include/ops_all.hpp b/tasks/example/all/include/ops_all.hpp index 77f05b822..8242fa6c7 100644 --- a/tasks/example/all/include/ops_all.hpp +++ b/tasks/example/all/include/ops_all.hpp @@ -3,18 +3,16 @@ #include #include -#include "core/task/include/task.hpp" +#include "example/common/include/common.hpp" -namespace nesterov_a_test_task_all { +namespace nesterov_a_test_task { void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_vec); void MatMulTBB(const std::vector &in_vec, int rc_size, std::vector &out_vec); -using InType = std::vector; -using OutType = std::vector; - -class NesterovATestTaskALL : public ppc::core::Task { +class NesterovATestTaskALL : public BaseTask { public: + static constexpr ppc::core::TypeOfTask GetTypeOfTask() { return ppc::core::TypeOfTask::kALL; } explicit NesterovATestTaskALL(const InType &in); bool ValidationImpl() override; bool PreProcessingImpl() override; @@ -25,4 +23,4 @@ class NesterovATestTaskALL : public ppc::core::Task { int rc_size_{}; }; -} // namespace nesterov_a_test_task_all +} // namespace nesterov_a_test_task diff --git a/tasks/example/all/src/ops_all.cpp b/tasks/example/all/src/ops_all.cpp index 190a7ead0..528fb5402 100644 --- a/tasks/example/all/src/ops_all.cpp +++ b/tasks/example/all/src/ops_all.cpp @@ -11,7 +11,7 @@ #include "core/util/include/util.hpp" #include "oneapi/tbb/parallel_for.h" -void nesterov_a_test_task_all::MatMul(const InType &in_vec, int rc_size, OutType &out_vec) { +void nesterov_a_test_task::MatMul(const InType &in_vec, int rc_size, OutType &out_vec) { for (int i = 0; i < rc_size; ++i) { for (int j = 0; j < rc_size; ++j) { out_vec[(i * rc_size) + j] = 0; @@ -22,26 +22,26 @@ void nesterov_a_test_task_all::MatMul(const InType &in_vec, int rc_size, OutType } } -void nesterov_a_test_task_all::MatMulTBB(const InType &in_vec, int rc_size, OutType &out_vec) { +void nesterov_a_test_task::MatMulTBB(const InType &in_vec, int rc_size, OutType &out_vec) { tbb::parallel_for(0, ppc::util::GetPPCNumThreads(), [&](int i) { MatMul(in_vec, rc_size - i, out_vec); }); MatMul(in_vec, rc_size, out_vec); } -nesterov_a_test_task_all::NesterovATestTaskALL::NesterovATestTaskALL(const InType &in) { GetInput() = in; } +nesterov_a_test_task::NesterovATestTaskALL::NesterovATestTaskALL(const InType &in) { GetInput() = in; } -bool nesterov_a_test_task_all::NesterovATestTaskALL::ValidationImpl() { +bool nesterov_a_test_task::NesterovATestTaskALL::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task_all::NesterovATestTaskALL::PreProcessingImpl() { +bool nesterov_a_test_task::NesterovATestTaskALL::PreProcessingImpl() { // Init value for input and output rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task_all::NesterovATestTaskALL::RunImpl() { +bool nesterov_a_test_task::NesterovATestTaskALL::RunImpl() { int rank = -1; MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { @@ -65,4 +65,4 @@ bool nesterov_a_test_task_all::NesterovATestTaskALL::RunImpl() { return true; } -bool nesterov_a_test_task_all::NesterovATestTaskALL::PostProcessingImpl() { return true; } +bool nesterov_a_test_task::NesterovATestTaskALL::PostProcessingImpl() { return true; } diff --git a/tasks/example/common/include/common.hpp b/tasks/example/common/include/common.hpp new file mode 100644 index 000000000..ab671f7ab --- /dev/null +++ b/tasks/example/common/include/common.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +#include "core/task/include/task.hpp" +#include "core/util/include/test_util.hpp" +#include "core/util/include/util.hpp" + +namespace nesterov_a_test_task { + +using InType = std::vector; +using OutType = std::vector; +using TestType = std::tuple; + +using BaseTask = ppc::core::Task; +using BasePerfTests = ppc::util::BaseRunPerfTests; +using BaseFuncTests = ppc::util::BaseRunFuncTests; + +} // namespace nesterov_a_test_task diff --git a/tasks/example/mpi/include/ops_mpi.hpp b/tasks/example/mpi/include/ops_mpi.hpp index b608a9c28..6f7c75ecb 100644 --- a/tasks/example/mpi/include/ops_mpi.hpp +++ b/tasks/example/mpi/include/ops_mpi.hpp @@ -4,17 +4,16 @@ #include #include "core/task/include/task.hpp" +#include "example/common/include/common.hpp" -namespace nesterov_a_test_task_mpi { +namespace nesterov_a_test_task { void MultiplyRowMajor(const std::vector &in, std::vector &out, int rc_size); void MultiplyColumnMajor(const std::vector &in, std::vector &out, int rc_size); -using InType = std::vector; -using OutType = std::vector; - -class NesterovATestTaskMPI : public ppc::core::Task { +class NesterovATestTaskMPI : public BaseTask { public: + static constexpr ppc::core::TypeOfTask GetTypeOfTask() { return ppc::core::TypeOfTask::kMPI; } explicit NesterovATestTaskMPI(const InType &in); bool ValidationImpl() override; bool PreProcessingImpl() override; @@ -27,4 +26,4 @@ class NesterovATestTaskMPI : public ppc::core::Task { void MultiplyMatrixBasedOnRank(); }; -} // namespace nesterov_a_test_task_mpi +} // namespace nesterov_a_test_task diff --git a/tasks/example/mpi/src/ops_mpi.cpp b/tasks/example/mpi/src/ops_mpi.cpp index c88709aaa..f505c06fd 100644 --- a/tasks/example/mpi/src/ops_mpi.cpp +++ b/tasks/example/mpi/src/ops_mpi.cpp @@ -6,7 +6,7 @@ #include #include -void nesterov_a_test_task_mpi::MultiplyRowMajor(const InType &in, OutType &out, int rc_size) { +void nesterov_a_test_task::MultiplyRowMajor(const InType &in, OutType &out, int rc_size) { for (int i = 0; i < rc_size; ++i) { for (int j = 0; j < rc_size; ++j) { for (int k = 0; k < rc_size; ++k) { @@ -16,7 +16,7 @@ void nesterov_a_test_task_mpi::MultiplyRowMajor(const InType &in, OutType &out, } } -void nesterov_a_test_task_mpi::MultiplyColumnMajor(const InType &in, OutType &out, int rc_size) { +void nesterov_a_test_task::MultiplyColumnMajor(const InType &in, OutType &out, int rc_size) { for (int j = 0; j < rc_size; ++j) { for (int k = 0; k < rc_size; ++k) { for (int i = 0; i < rc_size; ++i) { @@ -26,28 +26,28 @@ void nesterov_a_test_task_mpi::MultiplyColumnMajor(const InType &in, OutType &ou } } -nesterov_a_test_task_mpi::NesterovATestTaskMPI::NesterovATestTaskMPI(const InType &in) { GetInput() = in; } +nesterov_a_test_task::NesterovATestTaskMPI::NesterovATestTaskMPI(const InType &in) { GetInput() = in; } -bool nesterov_a_test_task_mpi::NesterovATestTaskMPI::ValidationImpl() { +bool nesterov_a_test_task::NesterovATestTaskMPI::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task_mpi::NesterovATestTaskMPI::PreProcessingImpl() { +bool nesterov_a_test_task::NesterovATestTaskMPI::PreProcessingImpl() { // Init value for input and output rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task_mpi::NesterovATestTaskMPI::RunImpl() { +bool nesterov_a_test_task::NesterovATestTaskMPI::RunImpl() { MultiplyMatrixBasedOnRank(); return true; } -bool nesterov_a_test_task_mpi::NesterovATestTaskMPI::PostProcessingImpl() { return true; } +bool nesterov_a_test_task::NesterovATestTaskMPI::PostProcessingImpl() { return true; } -void nesterov_a_test_task_mpi::NesterovATestTaskMPI::MultiplyMatrixBasedOnRank() { +void nesterov_a_test_task::NesterovATestTaskMPI::MultiplyMatrixBasedOnRank() { int rank = -1; MPI_Comm_rank(MPI_COMM_WORLD, &rank); diff --git a/tasks/example/omp/include/ops_omp.hpp b/tasks/example/omp/include/ops_omp.hpp index cca4313c4..b32296681 100644 --- a/tasks/example/omp/include/ops_omp.hpp +++ b/tasks/example/omp/include/ops_omp.hpp @@ -4,14 +4,13 @@ #include #include "core/task/include/task.hpp" +#include "example/common/include/common.hpp" -namespace nesterov_a_test_task_omp { +namespace nesterov_a_test_task { -using InType = std::vector; -using OutType = std::vector; - -class NesterovATestTaskOMP : public ppc::core::Task { +class NesterovATestTaskOMP : public BaseTask { public: + static constexpr ppc::core::TypeOfTask GetTypeOfTask() { return ppc::core::TypeOfTask::kOMP; } explicit NesterovATestTaskOMP(const InType& in); bool ValidationImpl() override; bool PreProcessingImpl() override; @@ -22,4 +21,4 @@ class NesterovATestTaskOMP : public ppc::core::Task { int rc_size_{}; }; -} // namespace nesterov_a_test_task_omp +} // namespace nesterov_a_test_task diff --git a/tasks/example/omp/src/ops_omp.cpp b/tasks/example/omp/src/ops_omp.cpp index 568841c44..6bbef4440 100644 --- a/tasks/example/omp/src/ops_omp.cpp +++ b/tasks/example/omp/src/ops_omp.cpp @@ -4,20 +4,20 @@ #include #include -nesterov_a_test_task_omp::NesterovATestTaskOMP::NesterovATestTaskOMP(const InType& in) { GetInput() = in; } +nesterov_a_test_task::NesterovATestTaskOMP::NesterovATestTaskOMP(const InType& in) { GetInput() = in; } -bool nesterov_a_test_task_omp::NesterovATestTaskOMP::ValidationImpl() { +bool nesterov_a_test_task::NesterovATestTaskOMP::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task_omp::NesterovATestTaskOMP::PreProcessingImpl() { +bool nesterov_a_test_task::NesterovATestTaskOMP::PreProcessingImpl() { rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task_omp::NesterovATestTaskOMP::RunImpl() { +bool nesterov_a_test_task::NesterovATestTaskOMP::RunImpl() { #pragma omp parallel default(none) { #pragma omp critical @@ -36,4 +36,4 @@ bool nesterov_a_test_task_omp::NesterovATestTaskOMP::RunImpl() { return true; } -bool nesterov_a_test_task_omp::NesterovATestTaskOMP::PostProcessingImpl() { return true; } +bool nesterov_a_test_task::NesterovATestTaskOMP::PostProcessingImpl() { return true; } diff --git a/tasks/example/seq/include/ops_seq.hpp b/tasks/example/seq/include/ops_seq.hpp index 1285ae415..c9e6fa870 100644 --- a/tasks/example/seq/include/ops_seq.hpp +++ b/tasks/example/seq/include/ops_seq.hpp @@ -4,14 +4,13 @@ #include #include "core/task/include/task.hpp" +#include "example/common/include/common.hpp" -namespace nesterov_a_test_task_seq { +namespace nesterov_a_test_task { -using InType = std::vector; -using OutType = std::vector; - -class NesterovATestTaskSEQ : public ppc::core::Task { +class NesterovATestTaskSEQ : public BaseTask { public: + static constexpr ppc::core::TypeOfTask GetTypeOfTask() { return ppc::core::TypeOfTask::kSEQ; } explicit NesterovATestTaskSEQ(const InType& in); bool ValidationImpl() override; bool PreProcessingImpl() override; @@ -22,4 +21,4 @@ class NesterovATestTaskSEQ : public ppc::core::Task { int rc_size_{}; }; -} // namespace nesterov_a_test_task_seq +} // namespace nesterov_a_test_task diff --git a/tasks/example/seq/src/ops_seq.cpp b/tasks/example/seq/src/ops_seq.cpp index 26b95ec81..427c436a9 100644 --- a/tasks/example/seq/src/ops_seq.cpp +++ b/tasks/example/seq/src/ops_seq.cpp @@ -4,20 +4,20 @@ #include #include -nesterov_a_test_task_seq::NesterovATestTaskSEQ::NesterovATestTaskSEQ(const InType& in) { GetInput() = in; } +nesterov_a_test_task::NesterovATestTaskSEQ::NesterovATestTaskSEQ(const InType& in) { GetInput() = in; } -bool nesterov_a_test_task_seq::NesterovATestTaskSEQ::ValidationImpl() { +bool nesterov_a_test_task::NesterovATestTaskSEQ::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task_seq::NesterovATestTaskSEQ::PreProcessingImpl() { +bool nesterov_a_test_task::NesterovATestTaskSEQ::PreProcessingImpl() { rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task_seq::NesterovATestTaskSEQ::RunImpl() { +bool nesterov_a_test_task::NesterovATestTaskSEQ::RunImpl() { // Multiply matrices for (int i = 0; i < rc_size_; ++i) { for (int j = 0; j < rc_size_; ++j) { @@ -29,4 +29,4 @@ bool nesterov_a_test_task_seq::NesterovATestTaskSEQ::RunImpl() { return true; } -bool nesterov_a_test_task_seq::NesterovATestTaskSEQ::PostProcessingImpl() { return true; } +bool nesterov_a_test_task::NesterovATestTaskSEQ::PostProcessingImpl() { return true; } diff --git a/tasks/example/stl/include/ops_stl.hpp b/tasks/example/stl/include/ops_stl.hpp index c33ae78ed..597c7ccbe 100644 --- a/tasks/example/stl/include/ops_stl.hpp +++ b/tasks/example/stl/include/ops_stl.hpp @@ -4,14 +4,13 @@ #include #include "core/task/include/task.hpp" +#include "example/common/include/common.hpp" -namespace nesterov_a_test_task_stl { +namespace nesterov_a_test_task { -using InType = std::vector; -using OutType = std::vector; - -class NesterovATestTaskSTL : public ppc::core::Task { +class NesterovATestTaskSTL : public BaseTask { public: + static constexpr ppc::core::TypeOfTask GetTypeOfTask() { return ppc::core::TypeOfTask::kSTL; } explicit NesterovATestTaskSTL(const InType& in); bool ValidationImpl() override; bool PreProcessingImpl() override; @@ -22,4 +21,4 @@ class NesterovATestTaskSTL : public ppc::core::Task { int rc_size_{}; }; -} // namespace nesterov_a_test_task_stl +} // namespace nesterov_a_test_task diff --git a/tasks/example/stl/src/ops_stl.cpp b/tasks/example/stl/src/ops_stl.cpp index e7abb2ff7..3ecd9ea9b 100644 --- a/tasks/example/stl/src/ops_stl.cpp +++ b/tasks/example/stl/src/ops_stl.cpp @@ -21,20 +21,20 @@ void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_v } } // namespace -nesterov_a_test_task_stl::NesterovATestTaskSTL::NesterovATestTaskSTL(const InType &in) { GetInput() = in; } +nesterov_a_test_task::NesterovATestTaskSTL::NesterovATestTaskSTL(const InType &in) { GetInput() = in; } -bool nesterov_a_test_task_stl::NesterovATestTaskSTL::ValidationImpl() { +bool nesterov_a_test_task::NesterovATestTaskSTL::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task_stl::NesterovATestTaskSTL::PreProcessingImpl() { +bool nesterov_a_test_task::NesterovATestTaskSTL::PreProcessingImpl() { rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task_stl::NesterovATestTaskSTL::RunImpl() { +bool nesterov_a_test_task::NesterovATestTaskSTL::RunImpl() { const int num_threads = ppc::util::GetPPCNumThreads(); std::vector threads(num_threads); for (int i = 0; i < num_threads; i++) { @@ -44,4 +44,4 @@ bool nesterov_a_test_task_stl::NesterovATestTaskSTL::RunImpl() { return true; } -bool nesterov_a_test_task_stl::NesterovATestTaskSTL::PostProcessingImpl() { return true; } +bool nesterov_a_test_task::NesterovATestTaskSTL::PostProcessingImpl() { return true; } diff --git a/tasks/example/tbb/include/ops_tbb.hpp b/tasks/example/tbb/include/ops_tbb.hpp index bf4408510..f66d121d7 100644 --- a/tasks/example/tbb/include/ops_tbb.hpp +++ b/tasks/example/tbb/include/ops_tbb.hpp @@ -4,14 +4,13 @@ #include #include "core/task/include/task.hpp" +#include "example/common/include/common.hpp" -namespace nesterov_a_test_task_tbb { +namespace nesterov_a_test_task { -using InType = std::vector; -using OutType = std::vector; - -class NesterovATestTaskTBB : public ppc::core::Task { +class NesterovATestTaskTBB : public BaseTask { public: + static constexpr ppc::core::TypeOfTask GetTypeOfTask() { return ppc::core::TypeOfTask::kTBB; } explicit NesterovATestTaskTBB(const InType& in); bool ValidationImpl() override; bool PreProcessingImpl() override; @@ -22,4 +21,4 @@ class NesterovATestTaskTBB : public ppc::core::Task { int rc_size_{}; }; -} // namespace nesterov_a_test_task_tbb +} // namespace nesterov_a_test_task diff --git a/tasks/example/tbb/src/ops_tbb.cpp b/tasks/example/tbb/src/ops_tbb.cpp index 4c26f09bd..acff91110 100644 --- a/tasks/example/tbb/src/ops_tbb.cpp +++ b/tasks/example/tbb/src/ops_tbb.cpp @@ -22,23 +22,23 @@ void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_v } } // namespace -nesterov_a_test_task_tbb::NesterovATestTaskTBB::NesterovATestTaskTBB(const InType &in) { GetInput() = in; } +nesterov_a_test_task::NesterovATestTaskTBB::NesterovATestTaskTBB(const InType &in) { GetInput() = in; } -bool nesterov_a_test_task_tbb::NesterovATestTaskTBB::ValidationImpl() { +bool nesterov_a_test_task::NesterovATestTaskTBB::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task_tbb::NesterovATestTaskTBB::PreProcessingImpl() { +bool nesterov_a_test_task::NesterovATestTaskTBB::PreProcessingImpl() { rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task_tbb::NesterovATestTaskTBB::RunImpl() { +bool nesterov_a_test_task::NesterovATestTaskTBB::RunImpl() { tbb::parallel_for(0, ppc::util::GetPPCNumThreads(), [&](int i) { MatMul(GetInput(), rc_size_ - i, GetOutput()); }); MatMul(GetInput(), rc_size_, GetOutput()); return true; } -bool nesterov_a_test_task_tbb::NesterovATestTaskTBB::PostProcessingImpl() { return true; } +bool nesterov_a_test_task::NesterovATestTaskTBB::PostProcessingImpl() { return true; } diff --git a/tasks/example/tests/func_tests/main.cpp b/tasks/example/tests/func_tests/main.cpp index a7773dd32..16c34dd18 100644 --- a/tasks/example/tests/func_tests/main.cpp +++ b/tasks/example/tests/func_tests/main.cpp @@ -16,11 +16,9 @@ #include "example/stl/include/ops_stl.hpp" #include "example/tbb/include/ops_tbb.hpp" -using InType = std::vector; -using OutType = std::vector; -using TestType = std::tuple; +namespace nesterov_a_test_task { -class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests { +class NesterovARunFuncTests : public BaseFuncTests { InType input_data_; public: @@ -47,7 +45,7 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests(GetParam()); + TestType params = std::get(GetParam()); const auto k_count = static_cast::size_type>(((width + height) / std::get<0>(params)) * std::stoi(std::get<1>(params))); input_data_ = InType(k_count * k_count, 0); @@ -70,14 +68,14 @@ constexpr std::array kTestParam = {std::make_tuple(5, "5"), std::ma INIT_TASK_GENERATOR(InType, kTestParam) -const auto kTestTasksList = std::tuple_cat(TaskListGenerator(), - TaskListGenerator(), - TaskListGenerator(), - TaskListGenerator(), - TaskListGenerator(), - TaskListGenerator()); +const auto kTestTasksList = + std::tuple_cat(TaskListGenerator(), TaskListGenerator(), + TaskListGenerator(), TaskListGenerator(), + TaskListGenerator(), TaskListGenerator()); INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTests, ppc::util::ExpandToValues(kTestTasksList), NesterovARunFuncTests::PrintFuncTestName); } // namespace + +} // namespace nesterov_a_test_task diff --git a/tasks/example/tests/perf_tests/main.cpp b/tasks/example/tests/perf_tests/main.cpp index 469f73f27..8d1a6e99e 100644 --- a/tasks/example/tests/perf_tests/main.cpp +++ b/tasks/example/tests/perf_tests/main.cpp @@ -16,10 +16,9 @@ #include "example/stl/include/ops_stl.hpp" #include "example/tbb/include/ops_tbb.hpp" -using InType = std::vector; -using OutType = std::vector; +namespace nesterov_a_test_task { -class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { +class ExampleRunPerfTest : public BasePerfTests { static constexpr std::vector::size_type kCount = 400; InType input_data_; @@ -48,10 +47,9 @@ TEST_P(ExampleRunPerfTest, RunPerfModes) { ExecuteTest(GetParam()); } INSTANTIATE_TEST_SUITE_P_NOLINT( RunModeTests, ExampleRunPerfTest, - ::testing::Values(ADD_PERF_MODES(nesterov_a_test_task_all::NesterovATestTaskALL, InType), - ADD_PERF_MODES(nesterov_a_test_task_mpi::NesterovATestTaskMPI, InType), - ADD_PERF_MODES(nesterov_a_test_task_omp::NesterovATestTaskOMP, InType), - ADD_PERF_MODES(nesterov_a_test_task_seq::NesterovATestTaskSEQ, InType), - ADD_PERF_MODES(nesterov_a_test_task_stl::NesterovATestTaskSTL, InType), - ADD_PERF_MODES(nesterov_a_test_task_tbb::NesterovATestTaskTBB, InType)), + ::testing::Values(ADD_PERF_MODES(NesterovATestTaskALL, InType), ADD_PERF_MODES(NesterovATestTaskMPI, InType), + ADD_PERF_MODES(NesterovATestTaskOMP, InType), ADD_PERF_MODES(NesterovATestTaskSEQ, InType), + ADD_PERF_MODES(NesterovATestTaskSTL, InType), ADD_PERF_MODES(NesterovATestTaskTBB, InType)), ExampleRunPerfTest::CustomPerfTestName); + +} // namespace nesterov_a_test_task From d8f9a4999f58698a785d8ae0b5a03491bdc22a3b Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 1 Jun 2025 01:34:34 +0200 Subject: [PATCH 034/141] Refactor task type handling and improve performance tracking. Replaced `GetTypeOfTask` with `GetStaticTypeOfTask` for clarity and added `SetTypeOfTask` and `GetDynamicTypeOfTask` to support dynamic task type management. Enhanced performance tracking with task-specific timing implementations (TBB, MPI, OMP, etc.). --- modules/core/perf/include/perf.hpp | 2 +- modules/core/task/include/task.hpp | 11 +++++++-- modules/core/util/include/test_util.hpp | 33 ++++++++++++++++++++++--- tasks/example/all/include/ops_all.hpp | 2 +- tasks/example/all/src/ops_all.cpp | 5 +++- tasks/example/mpi/include/ops_mpi.hpp | 2 +- tasks/example/mpi/src/ops_mpi.cpp | 5 +++- tasks/example/omp/include/ops_omp.hpp | 2 +- tasks/example/omp/src/ops_omp.cpp | 5 +++- tasks/example/seq/include/ops_seq.hpp | 2 +- tasks/example/seq/src/ops_seq.cpp | 5 +++- tasks/example/stl/include/ops_stl.hpp | 2 +- tasks/example/stl/src/ops_stl.cpp | 7 ++++-- tasks/example/tbb/include/ops_tbb.hpp | 2 +- tasks/example/tbb/src/ops_tbb.cpp | 5 +++- tasks/example/tests/perf_tests/main.cpp | 9 ------- 16 files changed, 70 insertions(+), 29 deletions(-) diff --git a/modules/core/perf/include/perf.hpp b/modules/core/perf/include/perf.hpp index 7ce1770ac..db01ed92c 100644 --- a/modules/core/perf/include/perf.hpp +++ b/modules/core/perf/include/perf.hpp @@ -11,7 +11,7 @@ namespace ppc::core { struct PerfAttr { // count of task's running uint64_t num_running = 10; - std::function current_timer = [&] { return 0.0; }; + std::function current_timer = [&] { return -1.0; }; }; struct PerfResults { diff --git a/modules/core/task/include/task.hpp b/modules/core/task/include/task.hpp index 84ef2a1f6..1491cdad4 100644 --- a/modules/core/task/include/task.hpp +++ b/modules/core/task/include/task.hpp @@ -68,8 +68,14 @@ class Task { // get state of testing StateOfTesting &GetStateOfTesting() { return state_of_testing_; } - // get a type of task - static constexpr TypeOfTask GetTypeOfTask() { return TypeOfTask::kUnknown; } + // set a type of task + void SetTypeOfTask(TypeOfTask type_of_task) { type_of_task_ = type_of_task; } + + // get a dynamic type of task + TypeOfTask GetDynamicTypeOfTask() { return type_of_task_; } + + // get a static type of task + static constexpr TypeOfTask GetStaticTypeOfTask() { return TypeOfTask::kUnknown; } InType &GetInput() { return input_; } @@ -130,6 +136,7 @@ class Task { InType input_; OutType output_; StateOfTesting state_of_testing_ = kFunc; + TypeOfTask type_of_task_ = kUnknown; std::vector functions_order_; std::vector right_functions_order_ = {"Validation", "PreProcessing", "Run", "PostProcessing"}; static constexpr double kMaxTestTime = 1.0; diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/test_util.hpp index 0a8cc6df2..9c2d98de8 100644 --- a/modules/core/util/include/test_util.hpp +++ b/modules/core/util/include/test_util.hpp @@ -2,6 +2,8 @@ #include #include +#include +#include #include "core/perf/include/perf.hpp" @@ -59,10 +61,33 @@ class BaseRunPerfTests : public ::testing::TestWithParamGetDynamicTypeOfTask() == ppc::core::TypeOfTask::kTBB) { + const tbb::tick_count t0 = tbb::tick_count::now(); + perf_attrs.current_timer = [t0] { return (tbb::tick_count::now() - t0).seconds(); }; + } else if (task_->GetDynamicTypeOfTask() == ppc::core::TypeOfTask::kMPI || + task_->GetDynamicTypeOfTask() == ppc::core::TypeOfTask::kALL) { + const double t0 = MPI_Wtime(); + perf_attrs.current_timer = [t0] { return MPI_Wtime() - t0; }; + } else if (task_->GetDynamicTypeOfTask() == ppc::core::TypeOfTask::kOMP) { + const double t0 = omp_get_wtime(); + perf_attrs.current_timer = [t0] { return omp_get_wtime() - t0; }; + } else if (task_->GetDynamicTypeOfTask() == ppc::core::TypeOfTask::kSEQ || + task_->GetDynamicTypeOfTask() == ppc::core::TypeOfTask::kSTL) { + const auto t0 = std::chrono::high_resolution_clock::now(); + perf_attrs.current_timer = [&] { + auto now = std::chrono::high_resolution_clock::now(); + auto ns = std::chrono::duration_cast(now - t0).count(); + return static_cast(ns) * 1e-9; + }; + } else { + throw std::runtime_error("The task type is not supported for performance testing."); + } + } + void ExecuteTest(const PerfTestParam& perf_test_param) { auto task_getter = std::get(perf_test_param); auto test_name = std::get(perf_test_param); @@ -99,11 +124,11 @@ class BaseRunPerfTests : public ::testing::TestWithParam, \ std::string(ppc::util::GetNamespace()) + std::string("_") + \ - ppc::util::GetStringTaskType(TaskType::GetTypeOfTask()), \ + ppc::util::GetStringTaskType(TaskType::GetStaticTypeOfTask()), \ ppc::core::PerfResults::TypeOfRunning::kPipeline), \ std::make_tuple(ppc::core::TaskGetter, \ std::string(ppc::util::GetNamespace()) + std::string("_") + \ - ppc::util::GetStringTaskType(TaskType::GetTypeOfTask()), \ + ppc::util::GetStringTaskType(TaskType::GetStaticTypeOfTask()), \ ppc::core::PerfResults::TypeOfRunning::kTaskRun) template @@ -160,7 +185,7 @@ auto ExpandToValues(const Tuple& t) { auto GenTaskTuplesImpl(std::index_sequence) { \ return std::make_tuple(std::make_tuple(ppc::core::TaskGetter, \ std::string(ppc::util::GetNamespace()) + std::string("_") + \ - ppc::util::GetStringTaskType(Task::GetTypeOfTask()), \ + ppc::util::GetStringTaskType(Task::GetStaticTypeOfTask()), \ SizesParam[Is])...); \ } \ \ diff --git a/tasks/example/all/include/ops_all.hpp b/tasks/example/all/include/ops_all.hpp index 8242fa6c7..8295248bc 100644 --- a/tasks/example/all/include/ops_all.hpp +++ b/tasks/example/all/include/ops_all.hpp @@ -12,7 +12,7 @@ void MatMulTBB(const std::vector &in_vec, int rc_size, std::vector &ou class NesterovATestTaskALL : public BaseTask { public: - static constexpr ppc::core::TypeOfTask GetTypeOfTask() { return ppc::core::TypeOfTask::kALL; } + static constexpr ppc::core::TypeOfTask GetStaticTypeOfTask() { return ppc::core::TypeOfTask::kALL; } explicit NesterovATestTaskALL(const InType &in); bool ValidationImpl() override; bool PreProcessingImpl() override; diff --git a/tasks/example/all/src/ops_all.cpp b/tasks/example/all/src/ops_all.cpp index 528fb5402..130843508 100644 --- a/tasks/example/all/src/ops_all.cpp +++ b/tasks/example/all/src/ops_all.cpp @@ -27,7 +27,10 @@ void nesterov_a_test_task::MatMulTBB(const InType &in_vec, int rc_size, OutType MatMul(in_vec, rc_size, out_vec); } -nesterov_a_test_task::NesterovATestTaskALL::NesterovATestTaskALL(const InType &in) { GetInput() = in; } +nesterov_a_test_task::NesterovATestTaskALL::NesterovATestTaskALL(const InType &in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; +} bool nesterov_a_test_task::NesterovATestTaskALL::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); diff --git a/tasks/example/mpi/include/ops_mpi.hpp b/tasks/example/mpi/include/ops_mpi.hpp index 6f7c75ecb..37abd083f 100644 --- a/tasks/example/mpi/include/ops_mpi.hpp +++ b/tasks/example/mpi/include/ops_mpi.hpp @@ -13,7 +13,7 @@ void MultiplyColumnMajor(const std::vector &in, std::vector &out, int class NesterovATestTaskMPI : public BaseTask { public: - static constexpr ppc::core::TypeOfTask GetTypeOfTask() { return ppc::core::TypeOfTask::kMPI; } + static constexpr ppc::core::TypeOfTask GetStaticTypeOfTask() { return ppc::core::TypeOfTask::kMPI; } explicit NesterovATestTaskMPI(const InType &in); bool ValidationImpl() override; bool PreProcessingImpl() override; diff --git a/tasks/example/mpi/src/ops_mpi.cpp b/tasks/example/mpi/src/ops_mpi.cpp index f505c06fd..80176061e 100644 --- a/tasks/example/mpi/src/ops_mpi.cpp +++ b/tasks/example/mpi/src/ops_mpi.cpp @@ -26,7 +26,10 @@ void nesterov_a_test_task::MultiplyColumnMajor(const InType &in, OutType &out, i } } -nesterov_a_test_task::NesterovATestTaskMPI::NesterovATestTaskMPI(const InType &in) { GetInput() = in; } +nesterov_a_test_task::NesterovATestTaskMPI::NesterovATestTaskMPI(const InType &in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; +} bool nesterov_a_test_task::NesterovATestTaskMPI::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); diff --git a/tasks/example/omp/include/ops_omp.hpp b/tasks/example/omp/include/ops_omp.hpp index b32296681..c9bc80699 100644 --- a/tasks/example/omp/include/ops_omp.hpp +++ b/tasks/example/omp/include/ops_omp.hpp @@ -10,7 +10,7 @@ namespace nesterov_a_test_task { class NesterovATestTaskOMP : public BaseTask { public: - static constexpr ppc::core::TypeOfTask GetTypeOfTask() { return ppc::core::TypeOfTask::kOMP; } + static constexpr ppc::core::TypeOfTask GetStaticTypeOfTask() { return ppc::core::TypeOfTask::kOMP; } explicit NesterovATestTaskOMP(const InType& in); bool ValidationImpl() override; bool PreProcessingImpl() override; diff --git a/tasks/example/omp/src/ops_omp.cpp b/tasks/example/omp/src/ops_omp.cpp index 6bbef4440..0e94a2073 100644 --- a/tasks/example/omp/src/ops_omp.cpp +++ b/tasks/example/omp/src/ops_omp.cpp @@ -4,7 +4,10 @@ #include #include -nesterov_a_test_task::NesterovATestTaskOMP::NesterovATestTaskOMP(const InType& in) { GetInput() = in; } +nesterov_a_test_task::NesterovATestTaskOMP::NesterovATestTaskOMP(const InType& in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; +} bool nesterov_a_test_task::NesterovATestTaskOMP::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); diff --git a/tasks/example/seq/include/ops_seq.hpp b/tasks/example/seq/include/ops_seq.hpp index c9e6fa870..5dfa2869f 100644 --- a/tasks/example/seq/include/ops_seq.hpp +++ b/tasks/example/seq/include/ops_seq.hpp @@ -10,7 +10,7 @@ namespace nesterov_a_test_task { class NesterovATestTaskSEQ : public BaseTask { public: - static constexpr ppc::core::TypeOfTask GetTypeOfTask() { return ppc::core::TypeOfTask::kSEQ; } + static constexpr ppc::core::TypeOfTask GetStaticTypeOfTask() { return ppc::core::TypeOfTask::kSEQ; } explicit NesterovATestTaskSEQ(const InType& in); bool ValidationImpl() override; bool PreProcessingImpl() override; diff --git a/tasks/example/seq/src/ops_seq.cpp b/tasks/example/seq/src/ops_seq.cpp index 427c436a9..8cf480a39 100644 --- a/tasks/example/seq/src/ops_seq.cpp +++ b/tasks/example/seq/src/ops_seq.cpp @@ -4,7 +4,10 @@ #include #include -nesterov_a_test_task::NesterovATestTaskSEQ::NesterovATestTaskSEQ(const InType& in) { GetInput() = in; } +nesterov_a_test_task::NesterovATestTaskSEQ::NesterovATestTaskSEQ(const InType& in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; +} bool nesterov_a_test_task::NesterovATestTaskSEQ::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); diff --git a/tasks/example/stl/include/ops_stl.hpp b/tasks/example/stl/include/ops_stl.hpp index 597c7ccbe..4e100e9b5 100644 --- a/tasks/example/stl/include/ops_stl.hpp +++ b/tasks/example/stl/include/ops_stl.hpp @@ -10,7 +10,7 @@ namespace nesterov_a_test_task { class NesterovATestTaskSTL : public BaseTask { public: - static constexpr ppc::core::TypeOfTask GetTypeOfTask() { return ppc::core::TypeOfTask::kSTL; } + static constexpr ppc::core::TypeOfTask GetStaticTypeOfTask() { return ppc::core::TypeOfTask::kSTL; } explicit NesterovATestTaskSTL(const InType& in); bool ValidationImpl() override; bool PreProcessingImpl() override; diff --git a/tasks/example/stl/src/ops_stl.cpp b/tasks/example/stl/src/ops_stl.cpp index 3ecd9ea9b..b4b13f45e 100644 --- a/tasks/example/stl/src/ops_stl.cpp +++ b/tasks/example/stl/src/ops_stl.cpp @@ -21,7 +21,10 @@ void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_v } } // namespace -nesterov_a_test_task::NesterovATestTaskSTL::NesterovATestTaskSTL(const InType &in) { GetInput() = in; } +nesterov_a_test_task::NesterovATestTaskSTL::NesterovATestTaskSTL(const InType &in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; +} bool nesterov_a_test_task::NesterovATestTaskSTL::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); @@ -38,7 +41,7 @@ bool nesterov_a_test_task::NesterovATestTaskSTL::RunImpl() { const int num_threads = ppc::util::GetPPCNumThreads(); std::vector threads(num_threads); for (int i = 0; i < num_threads; i++) { - threads[i] = std::thread(MatMul, std::cref(GetInput()), rc_size_, std::ref(GetOutput())); + threads[i] = std::thread(MatMul, GetInput(), rc_size_, std::ref(GetOutput())); threads[i].join(); } return true; diff --git a/tasks/example/tbb/include/ops_tbb.hpp b/tasks/example/tbb/include/ops_tbb.hpp index f66d121d7..43533ccd5 100644 --- a/tasks/example/tbb/include/ops_tbb.hpp +++ b/tasks/example/tbb/include/ops_tbb.hpp @@ -10,7 +10,7 @@ namespace nesterov_a_test_task { class NesterovATestTaskTBB : public BaseTask { public: - static constexpr ppc::core::TypeOfTask GetTypeOfTask() { return ppc::core::TypeOfTask::kTBB; } + static constexpr ppc::core::TypeOfTask GetStaticTypeOfTask() { return ppc::core::TypeOfTask::kTBB; } explicit NesterovATestTaskTBB(const InType& in); bool ValidationImpl() override; bool PreProcessingImpl() override; diff --git a/tasks/example/tbb/src/ops_tbb.cpp b/tasks/example/tbb/src/ops_tbb.cpp index acff91110..d3407a2e6 100644 --- a/tasks/example/tbb/src/ops_tbb.cpp +++ b/tasks/example/tbb/src/ops_tbb.cpp @@ -22,7 +22,10 @@ void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_v } } // namespace -nesterov_a_test_task::NesterovATestTaskTBB::NesterovATestTaskTBB(const InType &in) { GetInput() = in; } +nesterov_a_test_task::NesterovATestTaskTBB::NesterovATestTaskTBB(const InType &in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; +} bool nesterov_a_test_task::NesterovATestTaskTBB::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); diff --git a/tasks/example/tests/perf_tests/main.cpp b/tasks/example/tests/perf_tests/main.cpp index 8d1a6e99e..9f503e4fa 100644 --- a/tasks/example/tests/perf_tests/main.cpp +++ b/tasks/example/tests/perf_tests/main.cpp @@ -29,15 +29,6 @@ class ExampleRunPerfTest : public BasePerfTests { } } - void SetPerfAttributes(ppc::core::PerfAttr& perf_attrs) final { - const auto t0 = std::chrono::high_resolution_clock::now(); - perf_attrs.current_timer = [&] { - auto now = std::chrono::high_resolution_clock::now(); - auto ns = std::chrono::duration_cast(now - t0).count(); - return static_cast(ns) * 1e-9; - }; - } - bool CheckTestOutputData(OutType& output_data) final { return input_data_ == output_data; } InType GetTestInputData() final { return input_data_; } From 2a6f8fcfedee76e66b7546bfd274c9c2ca67088f Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 1 Jun 2025 01:43:25 +0200 Subject: [PATCH 035/141] Refactor code to consistently use namespaces. Unified the usage of the `nesterov_a_test_task` namespace across all files, removing redundant namespace qualifiers and wrapping implementations within the namespace. This enhances readability, consistency, and maintainability of the codebase. --- tasks/example/all/src/ops_all.cpp | 18 +++++++++++------- tasks/example/mpi/src/ops_mpi.cpp | 19 +++++++++++-------- tasks/example/omp/src/ops_omp.cpp | 14 +++++++++----- tasks/example/seq/src/ops_seq.cpp | 14 +++++++++----- tasks/example/stl/src/ops_stl.cpp | 14 +++++++++----- tasks/example/tbb/src/ops_tbb.cpp | 14 +++++++++----- 6 files changed, 58 insertions(+), 35 deletions(-) diff --git a/tasks/example/all/src/ops_all.cpp b/tasks/example/all/src/ops_all.cpp index 130843508..f31572898 100644 --- a/tasks/example/all/src/ops_all.cpp +++ b/tasks/example/all/src/ops_all.cpp @@ -11,7 +11,9 @@ #include "core/util/include/util.hpp" #include "oneapi/tbb/parallel_for.h" -void nesterov_a_test_task::MatMul(const InType &in_vec, int rc_size, OutType &out_vec) { +namespace nesterov_a_test_task { + +void MatMul(const InType &in_vec, int rc_size, OutType &out_vec) { for (int i = 0; i < rc_size; ++i) { for (int j = 0; j < rc_size; ++j) { out_vec[(i * rc_size) + j] = 0; @@ -22,29 +24,29 @@ void nesterov_a_test_task::MatMul(const InType &in_vec, int rc_size, OutType &ou } } -void nesterov_a_test_task::MatMulTBB(const InType &in_vec, int rc_size, OutType &out_vec) { +void MatMulTBB(const InType &in_vec, int rc_size, OutType &out_vec) { tbb::parallel_for(0, ppc::util::GetPPCNumThreads(), [&](int i) { MatMul(in_vec, rc_size - i, out_vec); }); MatMul(in_vec, rc_size, out_vec); } -nesterov_a_test_task::NesterovATestTaskALL::NesterovATestTaskALL(const InType &in) { +NesterovATestTaskALL::NesterovATestTaskALL(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; } -bool nesterov_a_test_task::NesterovATestTaskALL::ValidationImpl() { +bool NesterovATestTaskALL::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task::NesterovATestTaskALL::PreProcessingImpl() { +bool NesterovATestTaskALL::PreProcessingImpl() { // Init value for input and output rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task::NesterovATestTaskALL::RunImpl() { +bool NesterovATestTaskALL::RunImpl() { int rank = -1; MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { @@ -68,4 +70,6 @@ bool nesterov_a_test_task::NesterovATestTaskALL::RunImpl() { return true; } -bool nesterov_a_test_task::NesterovATestTaskALL::PostProcessingImpl() { return true; } +bool NesterovATestTaskALL::PostProcessingImpl() { return true; } + +} // namespace nesterov_a_test_task diff --git a/tasks/example/mpi/src/ops_mpi.cpp b/tasks/example/mpi/src/ops_mpi.cpp index 80176061e..cae5081f3 100644 --- a/tasks/example/mpi/src/ops_mpi.cpp +++ b/tasks/example/mpi/src/ops_mpi.cpp @@ -5,8 +5,9 @@ #include #include #include +namespace nesterov_a_test_task { -void nesterov_a_test_task::MultiplyRowMajor(const InType &in, OutType &out, int rc_size) { +void MultiplyRowMajor(const InType &in, OutType &out, int rc_size) { for (int i = 0; i < rc_size; ++i) { for (int j = 0; j < rc_size; ++j) { for (int k = 0; k < rc_size; ++k) { @@ -16,7 +17,7 @@ void nesterov_a_test_task::MultiplyRowMajor(const InType &in, OutType &out, int } } -void nesterov_a_test_task::MultiplyColumnMajor(const InType &in, OutType &out, int rc_size) { +void MultiplyColumnMajor(const InType &in, OutType &out, int rc_size) { for (int j = 0; j < rc_size; ++j) { for (int k = 0; k < rc_size; ++k) { for (int i = 0; i < rc_size; ++i) { @@ -26,31 +27,31 @@ void nesterov_a_test_task::MultiplyColumnMajor(const InType &in, OutType &out, i } } -nesterov_a_test_task::NesterovATestTaskMPI::NesterovATestTaskMPI(const InType &in) { +NesterovATestTaskMPI::NesterovATestTaskMPI(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; } -bool nesterov_a_test_task::NesterovATestTaskMPI::ValidationImpl() { +bool NesterovATestTaskMPI::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task::NesterovATestTaskMPI::PreProcessingImpl() { +bool NesterovATestTaskMPI::PreProcessingImpl() { // Init value for input and output rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task::NesterovATestTaskMPI::RunImpl() { +bool NesterovATestTaskMPI::RunImpl() { MultiplyMatrixBasedOnRank(); return true; } -bool nesterov_a_test_task::NesterovATestTaskMPI::PostProcessingImpl() { return true; } +bool NesterovATestTaskMPI::PostProcessingImpl() { return true; } -void nesterov_a_test_task::NesterovATestTaskMPI::MultiplyMatrixBasedOnRank() { +void NesterovATestTaskMPI::MultiplyMatrixBasedOnRank() { int rank = -1; MPI_Comm_rank(MPI_COMM_WORLD, &rank); @@ -61,3 +62,5 @@ void nesterov_a_test_task::NesterovATestTaskMPI::MultiplyMatrixBasedOnRank() { } MPI_Barrier(MPI_COMM_WORLD); } + +} // namespace nesterov_a_test_task diff --git a/tasks/example/omp/src/ops_omp.cpp b/tasks/example/omp/src/ops_omp.cpp index 0e94a2073..a1871cfee 100644 --- a/tasks/example/omp/src/ops_omp.cpp +++ b/tasks/example/omp/src/ops_omp.cpp @@ -4,23 +4,25 @@ #include #include -nesterov_a_test_task::NesterovATestTaskOMP::NesterovATestTaskOMP(const InType& in) { +namespace nesterov_a_test_task { + +NesterovATestTaskOMP::NesterovATestTaskOMP(const InType& in) { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; } -bool nesterov_a_test_task::NesterovATestTaskOMP::ValidationImpl() { +bool NesterovATestTaskOMP::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task::NesterovATestTaskOMP::PreProcessingImpl() { +bool NesterovATestTaskOMP::PreProcessingImpl() { rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task::NesterovATestTaskOMP::RunImpl() { +bool NesterovATestTaskOMP::RunImpl() { #pragma omp parallel default(none) { #pragma omp critical @@ -39,4 +41,6 @@ bool nesterov_a_test_task::NesterovATestTaskOMP::RunImpl() { return true; } -bool nesterov_a_test_task::NesterovATestTaskOMP::PostProcessingImpl() { return true; } +bool NesterovATestTaskOMP::PostProcessingImpl() { return true; } + +} // namespace nesterov_a_test_task diff --git a/tasks/example/seq/src/ops_seq.cpp b/tasks/example/seq/src/ops_seq.cpp index 8cf480a39..3b9d401d8 100644 --- a/tasks/example/seq/src/ops_seq.cpp +++ b/tasks/example/seq/src/ops_seq.cpp @@ -4,23 +4,25 @@ #include #include -nesterov_a_test_task::NesterovATestTaskSEQ::NesterovATestTaskSEQ(const InType& in) { +namespace nesterov_a_test_task { + +NesterovATestTaskSEQ::NesterovATestTaskSEQ(const InType& in) { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; } -bool nesterov_a_test_task::NesterovATestTaskSEQ::ValidationImpl() { +bool NesterovATestTaskSEQ::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task::NesterovATestTaskSEQ::PreProcessingImpl() { +bool NesterovATestTaskSEQ::PreProcessingImpl() { rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task::NesterovATestTaskSEQ::RunImpl() { +bool NesterovATestTaskSEQ::RunImpl() { // Multiply matrices for (int i = 0; i < rc_size_; ++i) { for (int j = 0; j < rc_size_; ++j) { @@ -32,4 +34,6 @@ bool nesterov_a_test_task::NesterovATestTaskSEQ::RunImpl() { return true; } -bool nesterov_a_test_task::NesterovATestTaskSEQ::PostProcessingImpl() { return true; } +bool NesterovATestTaskSEQ::PostProcessingImpl() { return true; } + +} // namespace nesterov_a_test_task diff --git a/tasks/example/stl/src/ops_stl.cpp b/tasks/example/stl/src/ops_stl.cpp index b4b13f45e..3a1d9a565 100644 --- a/tasks/example/stl/src/ops_stl.cpp +++ b/tasks/example/stl/src/ops_stl.cpp @@ -8,6 +8,8 @@ #include "core/util/include/util.hpp" +namespace nesterov_a_test_task { + namespace { void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_vec) { for (int i = 0; i < rc_size; ++i) { @@ -21,23 +23,23 @@ void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_v } } // namespace -nesterov_a_test_task::NesterovATestTaskSTL::NesterovATestTaskSTL(const InType &in) { +NesterovATestTaskSTL::NesterovATestTaskSTL(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; } -bool nesterov_a_test_task::NesterovATestTaskSTL::ValidationImpl() { +bool NesterovATestTaskSTL::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task::NesterovATestTaskSTL::PreProcessingImpl() { +bool NesterovATestTaskSTL::PreProcessingImpl() { rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task::NesterovATestTaskSTL::RunImpl() { +bool NesterovATestTaskSTL::RunImpl() { const int num_threads = ppc::util::GetPPCNumThreads(); std::vector threads(num_threads); for (int i = 0; i < num_threads; i++) { @@ -47,4 +49,6 @@ bool nesterov_a_test_task::NesterovATestTaskSTL::RunImpl() { return true; } -bool nesterov_a_test_task::NesterovATestTaskSTL::PostProcessingImpl() { return true; } +bool NesterovATestTaskSTL::PostProcessingImpl() { return true; } + +} // namespace nesterov_a_test_task diff --git a/tasks/example/tbb/src/ops_tbb.cpp b/tasks/example/tbb/src/ops_tbb.cpp index d3407a2e6..6fd49bcb7 100644 --- a/tasks/example/tbb/src/ops_tbb.cpp +++ b/tasks/example/tbb/src/ops_tbb.cpp @@ -9,6 +9,8 @@ #include "oneapi/tbb/parallel_for.h" +namespace nesterov_a_test_task { + namespace { void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_vec) { for (int i = 0; i < rc_size; ++i) { @@ -22,26 +24,28 @@ void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_v } } // namespace -nesterov_a_test_task::NesterovATestTaskTBB::NesterovATestTaskTBB(const InType &in) { +NesterovATestTaskTBB::NesterovATestTaskTBB(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; } -bool nesterov_a_test_task::NesterovATestTaskTBB::ValidationImpl() { +bool NesterovATestTaskTBB::ValidationImpl() { auto sqrt_size = static_cast(std::sqrt(GetInput().size())); return sqrt_size * sqrt_size == static_cast(GetInput().size()); } -bool nesterov_a_test_task::NesterovATestTaskTBB::PreProcessingImpl() { +bool NesterovATestTaskTBB::PreProcessingImpl() { rc_size_ = static_cast(std::sqrt(GetInput().size())); GetOutput() = OutType(GetInput().size(), 0); return true; } -bool nesterov_a_test_task::NesterovATestTaskTBB::RunImpl() { +bool NesterovATestTaskTBB::RunImpl() { tbb::parallel_for(0, ppc::util::GetPPCNumThreads(), [&](int i) { MatMul(GetInput(), rc_size_ - i, GetOutput()); }); MatMul(GetInput(), rc_size_, GetOutput()); return true; } -bool nesterov_a_test_task::NesterovATestTaskTBB::PostProcessingImpl() { return true; } +bool NesterovATestTaskTBB::PostProcessingImpl() { return true; } + +} // namespace nesterov_a_test_task From c5881e880141173709c48151ee828eb95826f78b Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Mon, 2 Jun 2025 08:45:18 +0200 Subject: [PATCH 036/141] Refactor test file structure for consistency Renamed directories and files related to functional and performance tests for better clarity and consistency. Updated CMakeLists accordingly to reflect the new structure and file paths. This avoids ambiguity and improves maintainability of the test infrastructure. --- tasks/CMakeLists.txt | 6 +++--- tasks/example/CMakeLists.txt | 4 ++-- tasks/example/tests/{func_tests => functional}/main.cpp | 0 tasks/example/tests/{perf_tests => performance}/main.cpp | 0 tasks/{func_runner/runner.cpp => runners/functional.cpp} | 0 tasks/{perf_runner/runner.cpp => runners/performance.cpp} | 0 6 files changed, 5 insertions(+), 5 deletions(-) rename tasks/example/tests/{func_tests => functional}/main.cpp (100%) rename tasks/example/tests/{perf_tests => performance}/main.cpp (100%) rename tasks/{func_runner/runner.cpp => runners/functional.cpp} (100%) rename tasks/{perf_runner/runner.cpp => runners/performance.cpp} (100%) diff --git a/tasks/CMakeLists.txt b/tasks/CMakeLists.txt index a0d8e7631..0aad3007e 100644 --- a/tasks/CMakeLists.txt +++ b/tasks/CMakeLists.txt @@ -7,19 +7,19 @@ set(exec_perf_tests "ppc_perf_tests") # Init func tests executable files set(list_of_exec_tests "") if (USE_FUNC_TESTS) - add_executable(${exec_func_tests} "${CMAKE_CURRENT_SOURCE_DIR}/func_runner/runner.cpp") + add_executable(${exec_func_tests} "${CMAKE_CURRENT_SOURCE_DIR}/runners/functional.cpp") list(APPEND list_of_exec_tests ${exec_func_tests}) endif (USE_FUNC_TESTS) # Init perf tests executable files if (USE_PERF_TESTS) - add_executable(${exec_perf_tests} "${CMAKE_CURRENT_SOURCE_DIR}/perf_runner/runner.cpp") + add_executable(${exec_perf_tests} "${CMAKE_CURRENT_SOURCE_DIR}/runners/performance.cpp") list(APPEND list_of_exec_tests ${exec_perf_tests}) endif (USE_PERF_TESTS) SUBDIRLIST(subdirs ${CMAKE_CURRENT_LIST_DIR}) foreach(subd ${subdirs}) - if ((subd STREQUAL "func_runner") OR (subd STREQUAL "perf_runner")) + if (subd STREQUAL "runners") continue() endif () add_subdirectory(${subd}) diff --git a/tasks/example/CMakeLists.txt b/tasks/example/CMakeLists.txt index 4692312f4..d92f95460 100644 --- a/tasks/example/CMakeLists.txt +++ b/tasks/example/CMakeLists.txt @@ -7,14 +7,14 @@ set(test_base_dir "${CMAKE_CURRENT_SOURCE_DIR}/tests") # Init func tests executable files set(list_of_exec_tests "") if (USE_FUNC_TESTS) - file(GLOB_RECURSE func_tests_source_files "${test_base_dir}/func_tests/*") + file(GLOB_RECURSE func_tests_source_files "${test_base_dir}/functional/*") target_sources(${exec_func_tests} PRIVATE ${func_tests_source_files}) list(APPEND list_of_exec_tests ${exec_func_tests}) endif (USE_FUNC_TESTS) # Init perf tests executable files if (USE_PERF_TESTS) - file(GLOB_RECURSE perf_tests_source_files "${test_base_dir}/perf_tests/*") + file(GLOB_RECURSE perf_tests_source_files "${test_base_dir}/performance/*") target_sources(${exec_perf_tests} PRIVATE ${perf_tests_source_files}) list(APPEND list_of_exec_tests ${exec_perf_tests}) endif (USE_PERF_TESTS) diff --git a/tasks/example/tests/func_tests/main.cpp b/tasks/example/tests/functional/main.cpp similarity index 100% rename from tasks/example/tests/func_tests/main.cpp rename to tasks/example/tests/functional/main.cpp diff --git a/tasks/example/tests/perf_tests/main.cpp b/tasks/example/tests/performance/main.cpp similarity index 100% rename from tasks/example/tests/perf_tests/main.cpp rename to tasks/example/tests/performance/main.cpp diff --git a/tasks/func_runner/runner.cpp b/tasks/runners/functional.cpp similarity index 100% rename from tasks/func_runner/runner.cpp rename to tasks/runners/functional.cpp diff --git a/tasks/perf_runner/runner.cpp b/tasks/runners/performance.cpp similarity index 100% rename from tasks/perf_runner/runner.cpp rename to tasks/runners/performance.cpp From 12436c37234414a59264cc465ff4f8e3852186cc Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Mon, 2 Jun 2025 08:48:18 +0200 Subject: [PATCH 037/141] Rename and update image file path in functional test. The image file was moved from `tests/data` to `data` for better organization. Updated the file path in the test code to reflect this change, ensuring the tests reference the correct location. --- tasks/example/{tests => }/data/pic_all.jpg | Bin tasks/example/tests/functional/main.cpp | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tasks/example/{tests => }/data/pic_all.jpg (100%) diff --git a/tasks/example/tests/data/pic_all.jpg b/tasks/example/data/pic_all.jpg similarity index 100% rename from tasks/example/tests/data/pic_all.jpg rename to tasks/example/data/pic_all.jpg diff --git a/tasks/example/tests/functional/main.cpp b/tasks/example/tests/functional/main.cpp index 16c34dd18..244e20dd9 100644 --- a/tasks/example/tests/functional/main.cpp +++ b/tasks/example/tests/functional/main.cpp @@ -33,7 +33,7 @@ class NesterovARunFuncTests : public BaseFuncTests { int channels = -1; // Read image { - std::string abs_path = ppc::util::GetAbsolutePath("example/tests/data/pic_all.jpg"); + std::string abs_path = ppc::util::GetAbsolutePath("example/data/pic_all.jpg"); auto *data = stbi_load(abs_path.c_str(), &width, &height, &channels, 0); if (data == nullptr) { throw std::runtime_error("Failed to load image: " + std::string(stbi_failure_reason())); From 6a29e89127c87778b8d68a35722fa238fd7faad0 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Mon, 2 Jun 2025 22:31:16 +0200 Subject: [PATCH 038/141] Refactor: Replace GetPPCNumThreads with GetNumThreads Standardize thread count retrieval by replacing ppc::util::GetPPCNumThreads with ppc::util::GetNumThreads across all relevant files. This ensures consistent usage of the updated utility function and improves code maintainability. --- tasks/example/all/src/ops_all.cpp | 4 ++-- tasks/example/stl/src/ops_stl.cpp | 2 +- tasks/example/tbb/src/ops_tbb.cpp | 2 +- tasks/runners/performance.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tasks/example/all/src/ops_all.cpp b/tasks/example/all/src/ops_all.cpp index f31572898..221fa4221 100644 --- a/tasks/example/all/src/ops_all.cpp +++ b/tasks/example/all/src/ops_all.cpp @@ -25,7 +25,7 @@ void MatMul(const InType &in_vec, int rc_size, OutType &out_vec) { } void MatMulTBB(const InType &in_vec, int rc_size, OutType &out_vec) { - tbb::parallel_for(0, ppc::util::GetPPCNumThreads(), [&](int i) { MatMul(in_vec, rc_size - i, out_vec); }); + tbb::parallel_for(0, ppc::util::GetNumThreads(), [&](int i) { MatMul(in_vec, rc_size - i, out_vec); }); MatMul(in_vec, rc_size, out_vec); } @@ -59,7 +59,7 @@ bool NesterovATestTaskALL::RunImpl() { MatMulTBB(GetInput(), rc_size_, GetOutput()); } - const int num_threads = ppc::util::GetPPCNumThreads(); + const int num_threads = ppc::util::GetNumThreads(); std::vector threads(num_threads); for (int i = 0; i < num_threads; i++) { threads[i] = std::thread(MatMul, std::cref(GetInput()), rc_size_, std::ref(GetOutput())); diff --git a/tasks/example/stl/src/ops_stl.cpp b/tasks/example/stl/src/ops_stl.cpp index 3a1d9a565..572d3e788 100644 --- a/tasks/example/stl/src/ops_stl.cpp +++ b/tasks/example/stl/src/ops_stl.cpp @@ -40,7 +40,7 @@ bool NesterovATestTaskSTL::PreProcessingImpl() { } bool NesterovATestTaskSTL::RunImpl() { - const int num_threads = ppc::util::GetPPCNumThreads(); + const int num_threads = ppc::util::GetNumThreads(); std::vector threads(num_threads); for (int i = 0; i < num_threads; i++) { threads[i] = std::thread(MatMul, GetInput(), rc_size_, std::ref(GetOutput())); diff --git a/tasks/example/tbb/src/ops_tbb.cpp b/tasks/example/tbb/src/ops_tbb.cpp index 6fd49bcb7..e00410214 100644 --- a/tasks/example/tbb/src/ops_tbb.cpp +++ b/tasks/example/tbb/src/ops_tbb.cpp @@ -41,7 +41,7 @@ bool NesterovATestTaskTBB::PreProcessingImpl() { } bool NesterovATestTaskTBB::RunImpl() { - tbb::parallel_for(0, ppc::util::GetPPCNumThreads(), [&](int i) { MatMul(GetInput(), rc_size_ - i, GetOutput()); }); + tbb::parallel_for(0, ppc::util::GetNumThreads(), [&](int i) { MatMul(GetInput(), rc_size_ - i, GetOutput()); }); MatMul(GetInput(), rc_size_, GetOutput()); return true; } diff --git a/tasks/runners/performance.cpp b/tasks/runners/performance.cpp index 5ea930ad8..0ba891220 100644 --- a/tasks/runners/performance.cpp +++ b/tasks/runners/performance.cpp @@ -74,7 +74,7 @@ int main(int argc, char** argv) { MPI_Init(&argc, &argv); // Limit the number of threads in TBB - tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetPPCNumThreads()); + tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetNumThreads()); ::testing::InitGoogleTest(&argc, argv); From 65a88804bb91fdd748ca501f1738e43b4c521296 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 3 Jun 2025 13:49:33 +0200 Subject: [PATCH 039/141] Add JSON integration and task status/type handling Integrated nlohmann/json for flexible task settings and added new enums to handle task status and type dynamically. Refactored logic to utilize settings.json for task configuration and adjusted functional/performance tests to account for new statuses, skipping disabled tasks. Updated CMake and added JSON dependency setup to streamline project builds. --- .gitmodules | 3 ++ 3rdparty/json | 1 + CMakeLists.txt | 1 + cmake/json.cmake | 12 +++++ modules/core/task/include/task.hpp | 51 +++++++++++++++++++- modules/core/util/include/test_util.hpp | 45 ++++++++--------- tasks/CMakeLists.txt | 4 ++ tasks/example/CMakeLists.txt | 11 +++-- tasks/example/data/{pic_all.jpg => pic.jpg} | Bin tasks/example/info.json | 8 +++ tasks/example/settings.json | 18 +++++++ tasks/example/tests/functional/main.cpp | 2 +- 12 files changed, 126 insertions(+), 30 deletions(-) create mode 160000 3rdparty/json create mode 100644 cmake/json.cmake rename tasks/example/data/{pic_all.jpg => pic.jpg} (100%) create mode 100644 tasks/example/info.json create mode 100644 tasks/example/settings.json diff --git a/.gitmodules b/.gitmodules index 5f55e2008..f17182474 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "3rdparty/stb"] path = 3rdparty/stb url = https://github.com/nothings/stb +[submodule "3rdparty/json"] + path = 3rdparty/json + url = https://github.com/nlohmann/json diff --git a/3rdparty/json b/3rdparty/json new file mode 160000 index 000000000..c633693d3 --- /dev/null +++ b/3rdparty/json @@ -0,0 +1 @@ +Subproject commit c633693d3e2ab81fa186c691c452c47ced107845 diff --git a/CMakeLists.txt b/CMakeLists.txt index a19d5840f..ea4f23bba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,7 @@ message( STATUS "PPC step: First configures" ) include(cmake/configure.cmake) include(cmake/modes.cmake) include(cmake/sanitizers.cmake) +include(cmake/json.cmake) ################# Parallel programming technologies ################# diff --git a/cmake/json.cmake b/cmake/json.cmake new file mode 100644 index 000000000..446699658 --- /dev/null +++ b/cmake/json.cmake @@ -0,0 +1,12 @@ +include_directories(${CMAKE_SOURCE_DIR}/3rdparty/json/include) +include(ExternalProject) +ExternalProject_Add(ppc_json + SOURCE_DIR "${CMAKE_SOURCE_DIR}/3rdparty/json" + PREFIX "${CMAKE_CURRENT_BINARY_DIR}/ppc_json" + BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/build" + INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/install" + CONFIGURE_COMMAND "${CMAKE_COMMAND}" -S "${CMAKE_SOURCE_DIR}/3rdparty/json/" -B "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/build/" + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -G${CMAKE_GENERATOR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} + BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/build" --config ${CMAKE_BUILD_TYPE} --parallel + INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/install") diff --git a/modules/core/task/include/task.hpp b/modules/core/task/include/task.hpp index 1491cdad4..aff76e89c 100644 --- a/modules/core/task/include/task.hpp +++ b/modules/core/task/include/task.hpp @@ -6,18 +6,63 @@ #include #include #include +#include #include #include #include #include #include #include +#include "nlohmann/json.hpp" using namespace std::chrono; namespace ppc::core { enum TypeOfTask : uint8_t { kALL, kMPI, kOMP, kSEQ, kSTL, kTBB, kUnknown }; +enum StatusOfTask : uint8_t { kEnabled, kDisabled }; + +inline std::string GetStringTaskStatus(StatusOfTask status_of_task) { + if (status_of_task == kDisabled) { + return "disabled"; + } else { + return "enabled"; + } +} + +inline std::string GetStringTaskType(TypeOfTask type_of_task, std::string settings_file_path) { + std::ifstream file(settings_file_path); + if (!file.is_open()) { + throw std::runtime_error("Failed to open file settings.json"); + } + nlohmann::json list_settings; + file >> list_settings; + + auto to_type_str = [&](std::string type) -> std::string { + return type + "_" + std::string(list_settings["tasks"][type]); + }; + + if (type_of_task == TypeOfTask::kALL) { + return to_type_str("all"); + } + if (type_of_task == TypeOfTask::kSTL) { + return to_type_str("stl"); + } + if (type_of_task == TypeOfTask::kOMP) { + return to_type_str("omp"); + } + if (type_of_task == TypeOfTask::kMPI) { + return to_type_str("mpi"); + } + if (type_of_task == TypeOfTask::kTBB) { + return to_type_str("tbb"); + } + if (type_of_task == TypeOfTask::kSEQ) { + return to_type_str("seq"); + } + return "unknown"; +} + enum StateOfTesting : uint8_t { kFunc, kPerf }; // Memory of inputs and outputs need to be initialized before create an object of @@ -74,6 +119,9 @@ class Task { // get a dynamic type of task TypeOfTask GetDynamicTypeOfTask() { return type_of_task_; } + // get a dynamic type of task + StatusOfTask GetStatusOfTask() { return status_of_task_; } + // get a static type of task static constexpr TypeOfTask GetStaticTypeOfTask() { return TypeOfTask::kUnknown; } @@ -137,6 +185,7 @@ class Task { OutType output_; StateOfTesting state_of_testing_ = kFunc; TypeOfTask type_of_task_ = kUnknown; + StatusOfTask status_of_task_ = kEnabled; std::vector functions_order_; std::vector right_functions_order_ = {"Validation", "PreProcessing", "Run", "PostProcessing"}; static constexpr double kMaxTestTime = 1.0; @@ -156,7 +205,7 @@ class Task { }; template -using TaskPtr = std::shared_ptr>; +using TaskPtr = std::shared_ptr>; template std::shared_ptr TaskGetter(InType in) { diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/test_util.hpp index 9c2d98de8..ea756a438 100644 --- a/modules/core/util/include/test_util.hpp +++ b/modules/core/util/include/test_util.hpp @@ -5,7 +5,13 @@ #include #include +#include +#include +#include + #include "core/perf/include/perf.hpp" +#include "core/util/include/util.hpp" +#include "nlohmann/json.hpp" namespace ppc::util { @@ -21,28 +27,6 @@ inline std::string GetStringParamName(ppc::core::PerfResults::TypeOfRunning type return "none"; } -inline std::string GetStringTaskType(ppc::core::TypeOfTask type_of_task) { - if (type_of_task == ppc::core::TypeOfTask::kALL) { - return "all"; - } - if (type_of_task == ppc::core::TypeOfTask::kSTL) { - return "stl"; - } - if (type_of_task == ppc::core::TypeOfTask::kOMP) { - return "omp"; - } - if (type_of_task == ppc::core::TypeOfTask::kMPI) { - return "mpi"; - } - if (type_of_task == ppc::core::TypeOfTask::kTBB) { - return "tbb"; - } - if (type_of_task == ppc::core::TypeOfTask::kSEQ) { - return "seq"; - } - return "unknown"; -} - template using FuncTestParam = std::tuple(InType)>, std::string, TestType>; @@ -93,6 +77,11 @@ class BaseRunPerfTests : public ::testing::TestWithParam(perf_test_param); auto mode = std::get(perf_test_param); + ASSERT_FALSE(test_name.find("unknown") != std::string::npos); + if (test_name.find("disabled") != std::string::npos) { + GTEST_SKIP(); + } + task_ = task_getter(GetTestInputData()); ppc::core::Perf perf(task_); ppc::core::PerfAttr perf_attr; @@ -124,11 +113,11 @@ class BaseRunPerfTests : public ::testing::TestWithParam, \ std::string(ppc::util::GetNamespace()) + std::string("_") + \ - ppc::util::GetStringTaskType(TaskType::GetStaticTypeOfTask()), \ + ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), PPC_STUDENT_SETTINGS), \ ppc::core::PerfResults::TypeOfRunning::kPipeline), \ std::make_tuple(ppc::core::TaskGetter, \ std::string(ppc::util::GetNamespace()) + std::string("_") + \ - ppc::util::GetStringTaskType(TaskType::GetStaticTypeOfTask()), \ + ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), PPC_STUDENT_SETTINGS), \ ppc::core::PerfResults::TypeOfRunning::kTaskRun) template @@ -156,7 +145,13 @@ class BaseRunFuncTests : public ::testing::TestWithParam test_param) { + ASSERT_FALSE(std::get(test_param).find("unknown") != std::string::npos); + if (std::get(test_param).find("disabled") != std::string::npos) { + GTEST_SKIP(); + } + task_ = std::get(test_param)(GetTestInputData()); ASSERT_TRUE(task_->Validation()); ASSERT_TRUE(task_->PreProcessing()); @@ -185,7 +180,7 @@ auto ExpandToValues(const Tuple& t) { auto GenTaskTuplesImpl(std::index_sequence) { \ return std::make_tuple(std::make_tuple(ppc::core::TaskGetter, \ std::string(ppc::util::GetNamespace()) + std::string("_") + \ - ppc::util::GetStringTaskType(Task::GetStaticTypeOfTask()), \ + ppc::core::GetStringTaskType(Task::GetStaticTypeOfTask(), PPC_STUDENT_SETTINGS), \ SizesParam[Is])...); \ } \ \ diff --git a/tasks/CMakeLists.txt b/tasks/CMakeLists.txt index 0aad3007e..6c60c582b 100644 --- a/tasks/CMakeLists.txt +++ b/tasks/CMakeLists.txt @@ -52,6 +52,10 @@ foreach (exec_func ${list_of_exec_tests}) add_dependencies(${exec_func} ppc_googletest) target_link_directories(${exec_func} PUBLIC "${CMAKE_BINARY_DIR}/ppc_googletest/install/lib") target_link_libraries(${exec_func} PUBLIC gtest gtest_main) + + add_dependencies(${exec_func} ppc_json) + target_link_directories(${exec_func} INTERFACE "${CMAKE_BINARY_DIR}/ppc_json/install/include") + enable_testing() add_test(NAME ${exec_func} COMMAND ${exec_func}) diff --git a/tasks/example/CMakeLists.txt b/tasks/example/CMakeLists.txt index d92f95460..57951303d 100644 --- a/tasks/example/CMakeLists.txt +++ b/tasks/example/CMakeLists.txt @@ -1,5 +1,10 @@ -# Init project -project("parallel_programming_course") +get_filename_component(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) +project(CURRENT_DIR_NAME) + +add_library("${CURRENT_DIR_NAME}_common" INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/common/include/common.hpp") +get_filename_component(SETTINGS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/settings.json" ABSOLUTE) +target_compile_definitions("${CURRENT_DIR_NAME}_common" INTERFACE PPC_STUDENT_SETTINGS=\"${SETTINGS_PATH}\") + set(exec_func_tests "ppc_func_tests") set(exec_perf_tests "ppc_perf_tests") set(test_base_dir "${CMAKE_CURRENT_SOURCE_DIR}/tests") @@ -46,7 +51,7 @@ foreach (dir_type "all" "mpi" "omp" "seq" "stl" "tbb") add_library(${name_lib} STATIC ${lib_source_files}) endif() set_target_properties(${name_lib} PROPERTIES LINKER_LANGUAGE CXX) - target_link_libraries(${name_lib} PUBLIC core_module_lib) + target_link_libraries(${name_lib} PUBLIC core_module_lib "${CURRENT_DIR_NAME}_common") # Link core library foreach (exec_func ${list_of_exec_tests}) diff --git a/tasks/example/data/pic_all.jpg b/tasks/example/data/pic.jpg similarity index 100% rename from tasks/example/data/pic_all.jpg rename to tasks/example/data/pic.jpg diff --git a/tasks/example/info.json b/tasks/example/info.json new file mode 100644 index 000000000..9d0020dbc --- /dev/null +++ b/tasks/example/info.json @@ -0,0 +1,8 @@ +{ + "student": { + "first_name": "Нестеров", + "last_name": "Александр", + "middle_name": "Юрьевич", + "group_number": "АБВ-123" + } +} \ No newline at end of file diff --git a/tasks/example/settings.json b/tasks/example/settings.json new file mode 100644 index 000000000..254c571d4 --- /dev/null +++ b/tasks/example/settings.json @@ -0,0 +1,18 @@ +{ + "tasks": { + "mpi": "enabled", + "omp": "enabled", + "seq": "enabled", + "all": "enabled", + "stl": "enabled", + "tbb": "enabled" + }, + "plagiarism": { + "mpi": "original", + "omp": "plagiarized", + "seq": "original", + "all": "original", + "stl": "original", + "tbb": "original" + } +} \ No newline at end of file diff --git a/tasks/example/tests/functional/main.cpp b/tasks/example/tests/functional/main.cpp index 244e20dd9..a50d026b7 100644 --- a/tasks/example/tests/functional/main.cpp +++ b/tasks/example/tests/functional/main.cpp @@ -33,7 +33,7 @@ class NesterovARunFuncTests : public BaseFuncTests { int channels = -1; // Read image { - std::string abs_path = ppc::util::GetAbsolutePath("example/data/pic_all.jpg"); + std::string abs_path = ppc::util::GetAbsolutePath("example/data/pic.jpg"); auto *data = stbi_load(abs_path.c_str(), &width, &height, &channels, 0); if (data == nullptr) { throw std::runtime_error("Failed to load image: " + std::string(stbi_failure_reason())); From 5b91f8e5303b472b0061003c548801e372141efc Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 3 Jun 2025 15:29:51 +0200 Subject: [PATCH 040/141] Refactor: Move and adjust `GetStringParamName` function Relocated `GetStringParamName` from `test_util.hpp` to `perf.hpp` to improve code modularity and reduce dependency overlap. Updated corresponding references to ensure functionality remains intact. --- modules/core/perf/include/perf.hpp | 10 +++++++ modules/core/task/include/task.hpp | 3 +- modules/core/util/include/test_util.hpp | 38 +++++++++---------------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/modules/core/perf/include/perf.hpp b/modules/core/perf/include/perf.hpp index db01ed92c..117783094 100644 --- a/modules/core/perf/include/perf.hpp +++ b/modules/core/perf/include/perf.hpp @@ -101,4 +101,14 @@ class Perf { } }; +inline std::string GetStringParamName(ppc::core::PerfResults::TypeOfRunning type_of_running) { + if (type_of_running == core::PerfResults::kTaskRun) { + return "task_run"; + } + if (type_of_running == core::PerfResults::kPipeline) { + return "pipeline"; + } + return "none"; +} + } // namespace ppc::core diff --git a/modules/core/task/include/task.hpp b/modules/core/task/include/task.hpp index aff76e89c..88ec04620 100644 --- a/modules/core/task/include/task.hpp +++ b/modules/core/task/include/task.hpp @@ -5,14 +5,15 @@ #include #include #include -#include #include +#include #include #include #include #include #include #include + #include "nlohmann/json.hpp" using namespace std::chrono; diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/test_util.hpp index ea756a438..d47e342a1 100644 --- a/modules/core/util/include/test_util.hpp +++ b/modules/core/util/include/test_util.hpp @@ -17,16 +17,6 @@ namespace ppc::util { enum GTestParamIndex : uint8_t { kTaskGetter, kNameTest, kTestParams }; -inline std::string GetStringParamName(ppc::core::PerfResults::TypeOfRunning type_of_running) { - if (type_of_running == core::PerfResults::kTaskRun) { - return "task_run"; - } - if (type_of_running == core::PerfResults::kPipeline) { - return "pipeline"; - } - return "none"; -} - template using FuncTestParam = std::tuple(InType)>, std::string, TestType>; @@ -40,7 +30,7 @@ template class BaseRunPerfTests : public ::testing::TestWithParam> { public: static std::string CustomPerfTestName(const ::testing::TestParamInfo>& info) { - return ppc::util::GetStringParamName(std::get(info.param)) + "_" + + return ppc::core::GetStringParamName(std::get(info.param)) + "_" + std::get(info.param); } @@ -110,14 +100,14 @@ class BaseRunPerfTests : public ::testing::TestWithParam task_; }; -#define ADD_PERF_MODES(TaskType, InputTypeParam) \ - std::make_tuple(ppc::core::TaskGetter, \ - std::string(ppc::util::GetNamespace()) + std::string("_") + \ - ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), PPC_STUDENT_SETTINGS), \ - ppc::core::PerfResults::TypeOfRunning::kPipeline), \ - std::make_tuple(ppc::core::TaskGetter, \ - std::string(ppc::util::GetNamespace()) + std::string("_") + \ - ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), PPC_STUDENT_SETTINGS), \ +#define ADD_PERF_MODES(TaskType, InputTypeParam) \ + std::make_tuple(ppc::core::TaskGetter, \ + std::string(ppc::util::GetNamespace()) + std::string("_") + \ + ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), PPC_STUDENT_SETTINGS), \ + ppc::core::PerfResults::TypeOfRunning::kPipeline), \ + std::make_tuple(ppc::core::TaskGetter, \ + std::string(ppc::util::GetNamespace()) + std::string("_") + \ + ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), PPC_STUDENT_SETTINGS), \ ppc::core::PerfResults::TypeOfRunning::kTaskRun) template @@ -145,7 +135,6 @@ class BaseRunFuncTests : public ::testing::TestWithParam test_param) { ASSERT_FALSE(std::get(test_param).find("unknown") != std::string::npos); if (std::get(test_param).find("disabled") != std::string::npos) { @@ -178,10 +167,11 @@ auto ExpandToValues(const Tuple& t) { #define INIT_TASK_GENERATOR(InTypeParam, SizesParam) \ template \ auto GenTaskTuplesImpl(std::index_sequence) { \ - return std::make_tuple(std::make_tuple(ppc::core::TaskGetter, \ - std::string(ppc::util::GetNamespace()) + std::string("_") + \ - ppc::core::GetStringTaskType(Task::GetStaticTypeOfTask(), PPC_STUDENT_SETTINGS), \ - SizesParam[Is])...); \ + return std::make_tuple( \ + std::make_tuple(ppc::core::TaskGetter, \ + std::string(ppc::util::GetNamespace()) + std::string("_") + \ + ppc::core::GetStringTaskType(Task::GetStaticTypeOfTask(), PPC_STUDENT_SETTINGS), \ + SizesParam[Is])...); \ } \ \ template \ From 4340dd448e21b811a160d377793e4cf76bb684a7 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 3 Jun 2025 15:31:37 +0200 Subject: [PATCH 041/141] Rename macro ADD_PERF_MODES to ADD_PERF_TASK. This change updates the macro name for better clarity and consistency across the codebase. The change ensures descriptive and unified naming conventions within performance-related test utilities. --- modules/core/util/include/test_util.hpp | 2 +- tasks/example/tests/performance/main.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/test_util.hpp index d47e342a1..c4fe0fd05 100644 --- a/modules/core/util/include/test_util.hpp +++ b/modules/core/util/include/test_util.hpp @@ -100,7 +100,7 @@ class BaseRunPerfTests : public ::testing::TestWithParam task_; }; -#define ADD_PERF_MODES(TaskType, InputTypeParam) \ +#define ADD_PERF_TASK(TaskType, InputTypeParam) \ std::make_tuple(ppc::core::TaskGetter, \ std::string(ppc::util::GetNamespace()) + std::string("_") + \ ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), PPC_STUDENT_SETTINGS), \ diff --git a/tasks/example/tests/performance/main.cpp b/tasks/example/tests/performance/main.cpp index 9f503e4fa..c99611b74 100644 --- a/tasks/example/tests/performance/main.cpp +++ b/tasks/example/tests/performance/main.cpp @@ -38,9 +38,9 @@ TEST_P(ExampleRunPerfTest, RunPerfModes) { ExecuteTest(GetParam()); } INSTANTIATE_TEST_SUITE_P_NOLINT( RunModeTests, ExampleRunPerfTest, - ::testing::Values(ADD_PERF_MODES(NesterovATestTaskALL, InType), ADD_PERF_MODES(NesterovATestTaskMPI, InType), - ADD_PERF_MODES(NesterovATestTaskOMP, InType), ADD_PERF_MODES(NesterovATestTaskSEQ, InType), - ADD_PERF_MODES(NesterovATestTaskSTL, InType), ADD_PERF_MODES(NesterovATestTaskTBB, InType)), + ::testing::Values(ADD_PERF_TASK(NesterovATestTaskALL, InType), ADD_PERF_TASK(NesterovATestTaskMPI, InType), + ADD_PERF_TASK(NesterovATestTaskOMP, InType), ADD_PERF_TASK(NesterovATestTaskSEQ, InType), + ADD_PERF_TASK(NesterovATestTaskSTL, InType), ADD_PERF_TASK(NesterovATestTaskTBB, InType)), ExampleRunPerfTest::CustomPerfTestName); } // namespace nesterov_a_test_task From 1ce11d294163f2b5ce93b55cb1f3718253713711 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 3 Jun 2025 15:59:07 +0200 Subject: [PATCH 042/141] Refactor and modularize test utilities. Separated functional and performance test logic into distinct headers (`func_test_util.hpp` and `perf_test_util.hpp`) for clearer structure and better modularity. Updated references and improved clarity in test implementation. --- modules/core/util/include/func_test_util.hpp | 93 +++++++++++++++++++ .../{test_util.hpp => perf_test_util.hpp} | 82 +--------------- modules/core/util/include/util.hpp | 2 + tasks/example/common/include/common.hpp | 4 - tasks/example/tests/functional/main.cpp | 9 +- tasks/example/tests/performance/main.cpp | 4 +- 6 files changed, 105 insertions(+), 89 deletions(-) create mode 100644 modules/core/util/include/func_test_util.hpp rename modules/core/util/include/{test_util.hpp => perf_test_util.hpp} (52%) diff --git a/modules/core/util/include/func_test_util.hpp b/modules/core/util/include/func_test_util.hpp new file mode 100644 index 000000000..bd6a5cf93 --- /dev/null +++ b/modules/core/util/include/func_test_util.hpp @@ -0,0 +1,93 @@ +#pragma once + +#include +#include +#include +#include + +#include +#include +#include + +#include "core/perf/include/perf.hpp" +#include "core/util/include/util.hpp" +#include "nlohmann/json.hpp" + +namespace ppc::util { + +template +using FuncTestParam = std::tuple(InType)>, std::string, TestType>; + +template +using GTestFuncParam = ::testing::TestParamInfo>; + +template +concept HasPrintTestParam = requires(TestType value) { + { T::PrintTestParam(value) } -> std::same_as; +}; + +template +class BaseRunFuncTests : public ::testing::TestWithParam> { + public: + virtual bool CheckTestOutputData(OutType& output_data) = 0; + virtual InType GetTestInputData() = 0; + + template + static void RequireStaticInterface() { + static_assert(HasPrintTestParam, + "Derived class must implement: static std::string PrintTestParam(TestType)"); + } + + template + static std::string PrintFuncTestName(const GTestFuncParam& info) { + RequireStaticInterface(); + TestType test_param = std::get(info.param); + return std::get(info.param) + "_" + Derived::PrintTestParam(test_param); + } + + protected: + void ExecuteTest(FuncTestParam test_param) { + ASSERT_FALSE(std::get(test_param).find("unknown") != std::string::npos); + if (std::get(test_param).find("disabled") != std::string::npos) { + GTEST_SKIP(); + } + + task_ = std::get(test_param)(GetTestInputData()); + ASSERT_TRUE(task_->Validation()); + ASSERT_TRUE(task_->PreProcessing()); + ASSERT_TRUE(task_->Run()); + ASSERT_TRUE(task_->PostProcessing()); + ASSERT_TRUE(CheckTestOutputData(task_->GetOutput())); + } + + private: + ppc::core::TaskPtr task_; +}; + +template +auto ExpandToValuesImpl(const Tuple& t, std::index_sequence /*unused*/) { + return ::testing::Values(std::get(t)...); +} + +template +auto ExpandToValues(const Tuple& t) { + constexpr std::size_t kN = std::tuple_size_v; + return ExpandToValuesImpl(t, std::make_index_sequence{}); +} + +#define INIT_TASK_GENERATOR(InTypeParam, SizesParam) \ + template \ + auto GenTaskTuplesImpl(std::index_sequence) { \ + return std::make_tuple( \ + std::make_tuple(ppc::core::TaskGetter, \ + std::string(ppc::util::GetNamespace()) + std::string("_") + \ + ppc::core::GetStringTaskType(Task::GetStaticTypeOfTask(), PPC_STUDENT_SETTINGS), \ + SizesParam[Is])...); \ + } \ + \ + template \ + auto TaskListGenerator() { \ + return GenTaskTuplesImpl(std::make_index_sequence{}); \ + } + +} // namespace ppc::util diff --git a/modules/core/util/include/test_util.hpp b/modules/core/util/include/perf_test_util.hpp similarity index 52% rename from modules/core/util/include/test_util.hpp rename to modules/core/util/include/perf_test_util.hpp index c4fe0fd05..b4bb29c48 100644 --- a/modules/core/util/include/test_util.hpp +++ b/modules/core/util/include/perf_test_util.hpp @@ -15,16 +15,9 @@ namespace ppc::util { -enum GTestParamIndex : uint8_t { kTaskGetter, kNameTest, kTestParams }; - -template -using FuncTestParam = std::tuple(InType)>, std::string, TestType>; - -template -using GTestFuncParam = ::testing::TestParamInfo>; - template -using PerfTestParam = FuncTestParam; +using PerfTestParam = std::tuple(InType)>, std::string, + ppc::core::PerfResults::TypeOfRunning>; template class BaseRunPerfTests : public ::testing::TestWithParam> { @@ -100,7 +93,7 @@ class BaseRunPerfTests : public ::testing::TestWithParam task_; }; -#define ADD_PERF_TASK(TaskType, InputTypeParam) \ +#define ADD_PERF_TASK(TaskType, InputTypeParam) \ std::make_tuple(ppc::core::TaskGetter, \ std::string(ppc::util::GetNamespace()) + std::string("_") + \ ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), PPC_STUDENT_SETTINGS), \ @@ -110,73 +103,4 @@ class BaseRunPerfTests : public ::testing::TestWithParam -concept HasPrintTestParam = requires(TestType value) { - { T::PrintTestParam(value) } -> std::same_as; -}; - -template -class BaseRunFuncTests : public ::testing::TestWithParam> { - public: - virtual bool CheckTestOutputData(OutType& output_data) = 0; - virtual InType GetTestInputData() = 0; - - template - static void RequireStaticInterface() { - static_assert(HasPrintTestParam, - "Derived class must implement: static std::string PrintTestParam(TestType)"); - } - - template - static std::string PrintFuncTestName(const GTestFuncParam& info) { - RequireStaticInterface(); - TestType test_param = std::get(info.param); - return std::get(info.param) + "_" + Derived::PrintTestParam(test_param); - } - - protected: - void ExecuteTest(FuncTestParam test_param) { - ASSERT_FALSE(std::get(test_param).find("unknown") != std::string::npos); - if (std::get(test_param).find("disabled") != std::string::npos) { - GTEST_SKIP(); - } - - task_ = std::get(test_param)(GetTestInputData()); - ASSERT_TRUE(task_->Validation()); - ASSERT_TRUE(task_->PreProcessing()); - ASSERT_TRUE(task_->Run()); - ASSERT_TRUE(task_->PostProcessing()); - ASSERT_TRUE(CheckTestOutputData(task_->GetOutput())); - } - - private: - ppc::core::TaskPtr task_; -}; - -template -auto ExpandToValuesImpl(const Tuple& t, std::index_sequence /*unused*/) { - return ::testing::Values(std::get(t)...); -} - -template -auto ExpandToValues(const Tuple& t) { - constexpr std::size_t kN = std::tuple_size_v; - return ExpandToValuesImpl(t, std::make_index_sequence{}); -} - -#define INIT_TASK_GENERATOR(InTypeParam, SizesParam) \ - template \ - auto GenTaskTuplesImpl(std::index_sequence) { \ - return std::make_tuple( \ - std::make_tuple(ppc::core::TaskGetter, \ - std::string(ppc::util::GetNamespace()) + std::string("_") + \ - ppc::core::GetStringTaskType(Task::GetStaticTypeOfTask(), PPC_STUDENT_SETTINGS), \ - SizesParam[Is])...); \ - } \ - \ - template \ - auto TaskListGenerator() { \ - return GenTaskTuplesImpl(std::make_index_sequence{}); \ - } - } // namespace ppc::util diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index 515a07bbf..76cd6d19c 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -13,6 +13,8 @@ namespace ppc::util { +enum GTestParamIndex : uint8_t { kTaskGetter, kNameTest, kTestParams }; + std::string GetAbsolutePath(const std::string &relative_path); int GetNumThreads(); diff --git a/tasks/example/common/include/common.hpp b/tasks/example/common/include/common.hpp index ab671f7ab..4f2d9d1bb 100644 --- a/tasks/example/common/include/common.hpp +++ b/tasks/example/common/include/common.hpp @@ -4,7 +4,6 @@ #include #include "core/task/include/task.hpp" -#include "core/util/include/test_util.hpp" #include "core/util/include/util.hpp" namespace nesterov_a_test_task { @@ -12,9 +11,6 @@ namespace nesterov_a_test_task { using InType = std::vector; using OutType = std::vector; using TestType = std::tuple; - using BaseTask = ppc::core::Task; -using BasePerfTests = ppc::util::BaseRunPerfTests; -using BaseFuncTests = ppc::util::BaseRunFuncTests; } // namespace nesterov_a_test_task diff --git a/tasks/example/tests/functional/main.cpp b/tasks/example/tests/functional/main.cpp index a50d026b7..3ae36c2e0 100644 --- a/tasks/example/tests/functional/main.cpp +++ b/tasks/example/tests/functional/main.cpp @@ -7,7 +7,7 @@ #include #include -#include "core/util/include/test_util.hpp" +#include "core/util/include/func_test_util.hpp" #include "core/util/include/util.hpp" #include "example/all/include/ops_all.hpp" #include "example/mpi/include/ops_mpi.hpp" @@ -18,9 +18,7 @@ namespace nesterov_a_test_task { -class NesterovARunFuncTests : public BaseFuncTests { - InType input_data_; - +class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests { public: static std::string PrintTestParam(TestType test_param) { return std::to_string(std::get<0>(test_param)) + "_" + std::get<1>(test_param); @@ -57,6 +55,9 @@ class NesterovARunFuncTests : public BaseFuncTests { bool CheckTestOutputData(OutType &output_data) final { return input_data_ == output_data; } InType GetTestInputData() final { return input_data_; } + + private: + InType input_data_; }; namespace { diff --git a/tasks/example/tests/performance/main.cpp b/tasks/example/tests/performance/main.cpp index c99611b74..306e5eed8 100644 --- a/tasks/example/tests/performance/main.cpp +++ b/tasks/example/tests/performance/main.cpp @@ -7,7 +7,7 @@ #include #include "core/perf/include/perf.hpp" -#include "core/util/include/test_util.hpp" +#include "core/util/include/perf_test_util.hpp" #include "core/util/include/util.hpp" #include "example/all/include/ops_all.hpp" #include "example/mpi/include/ops_mpi.hpp" @@ -18,7 +18,7 @@ namespace nesterov_a_test_task { -class ExampleRunPerfTest : public BasePerfTests { +class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { static constexpr std::vector::size_type kCount = 400; InType input_data_; From e01b19d4e59b393f1aad3224db2306d8205e9a73 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 3 Jun 2025 17:41:12 +0200 Subject: [PATCH 043/141] Set C++ standard as required in CMake configuration Enabled `CMAKE_CXX_STANDARD_REQUIRED` to enforce the specified C++ standard. This ensures compatibility and prevents fallback to earlier standards during the build process. --- cmake/configure.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/configure.cmake b/cmake/configure.cmake index 836e81a1d..e346f58a1 100644 --- a/cmake/configure.cmake +++ b/cmake/configure.cmake @@ -27,6 +27,7 @@ if ( MSVC AND (CMAKE_C_COMPILER_ID STREQUAL "Clang") AND (CMAKE_CXX_COMPILER_ID else () set( CMAKE_CXX_STANDARD 23 ) endif () +set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_COMPILE_WARNING_AS_ERROR ON) From 15796637429aedd7c09eccfb5fdefd0e9dbee85a Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 3 Jun 2025 17:52:44 +0200 Subject: [PATCH 044/141] Remove unused JSON include and adjust const qualifier. Removed redundant include of `nlohmann/json.hpp` in multiple files and migrated its usage into `util.hpp` while adding required safeguards for compatibility. Also replaced `constexpr` with `const` for `kTestParam` to align with its usage. --- modules/core/task/include/task.hpp | 3 +-- modules/core/util/include/func_test_util.hpp | 1 - modules/core/util/include/perf_test_util.hpp | 1 - modules/core/util/include/util.hpp | 12 ++++++++++++ tasks/example/tests/functional/main.cpp | 4 ++-- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/modules/core/task/include/task.hpp b/modules/core/task/include/task.hpp index 88ec04620..02c7ea6db 100644 --- a/modules/core/task/include/task.hpp +++ b/modules/core/task/include/task.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -14,8 +15,6 @@ #include #include -#include "nlohmann/json.hpp" - using namespace std::chrono; namespace ppc::core { diff --git a/modules/core/util/include/func_test_util.hpp b/modules/core/util/include/func_test_util.hpp index bd6a5cf93..ba2924740 100644 --- a/modules/core/util/include/func_test_util.hpp +++ b/modules/core/util/include/func_test_util.hpp @@ -11,7 +11,6 @@ #include "core/perf/include/perf.hpp" #include "core/util/include/util.hpp" -#include "nlohmann/json.hpp" namespace ppc::util { diff --git a/modules/core/util/include/perf_test_util.hpp b/modules/core/util/include/perf_test_util.hpp index b4bb29c48..0eec5ba70 100644 --- a/modules/core/util/include/perf_test_util.hpp +++ b/modules/core/util/include/perf_test_util.hpp @@ -11,7 +11,6 @@ #include "core/perf/include/perf.hpp" #include "core/util/include/util.hpp" -#include "nlohmann/json.hpp" namespace ppc::util { diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index 76cd6d19c..f6719907f 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -1,7 +1,19 @@ #pragma once +#include #include #include +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4459) // переменная 'last' перекрывает глобальную +#endif + +#include + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + /* NOLINTBEGIN */ #define INSTANTIATE_TEST_SUITE_P_NOLINT(prefix, test_case_name, generator, custom_test_name) \ INSTANTIATE_TEST_SUITE_P(prefix, test_case_name, generator, custom_test_name) diff --git a/tasks/example/tests/functional/main.cpp b/tasks/example/tests/functional/main.cpp index 3ae36c2e0..4db602d54 100644 --- a/tasks/example/tests/functional/main.cpp +++ b/tasks/example/tests/functional/main.cpp @@ -64,8 +64,8 @@ namespace { TEST_P(NesterovARunFuncTests, MatmulFromPic) { ExecuteTest(GetParam()); } -constexpr std::array kTestParam = {std::make_tuple(5, "5"), std::make_tuple(10, "10"), - std::make_tuple(15, "15")}; +const std::array kTestParam = {std::make_tuple(5, "5"), std::make_tuple(10, "10"), + std::make_tuple(15, "15")}; INIT_TASK_GENERATOR(InType, kTestParam) From 2e36d523079a4481ad99cb9b4ce4f0c2e073777d Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 3 Jun 2025 17:59:04 +0200 Subject: [PATCH 045/141] Fix incorrect usage of `constexpr` and redundant `const` casts Replaced `constexpr` with `const` for `kCount` in the performance test to align with proper usage. Removed the unnecessary `const` cast in the functional test for cleaner and more accurate type handling. --- tasks/example/tests/functional/main.cpp | 2 +- tasks/example/tests/performance/main.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/example/tests/functional/main.cpp b/tasks/example/tests/functional/main.cpp index 4db602d54..e9d0de975 100644 --- a/tasks/example/tests/functional/main.cpp +++ b/tasks/example/tests/functional/main.cpp @@ -44,7 +44,7 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests(GetParam()); - const auto k_count = static_cast::size_type>(((width + height) / std::get<0>(params)) * + const auto k_count = static_cast::size_type>(((width + height) / std::get<0>(params)) * std::stoi(std::get<1>(params))); input_data_ = InType(k_count * k_count, 0); for (std::vector::size_type i = 0; i < k_count; i++) { diff --git a/tasks/example/tests/performance/main.cpp b/tasks/example/tests/performance/main.cpp index 306e5eed8..47e31babc 100644 --- a/tasks/example/tests/performance/main.cpp +++ b/tasks/example/tests/performance/main.cpp @@ -19,7 +19,7 @@ namespace nesterov_a_test_task { class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { - static constexpr std::vector::size_type kCount = 400; + const std::vector::size_type kCount = 400; InType input_data_; void SetUp() override { From 151a1ced6e3b2846e999389e67d156db4b5a5bff Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 3 Jun 2025 18:01:35 +0200 Subject: [PATCH 046/141] Set C++ standard to C++20 for Clang builds Updated the CMake configuration to use C++20 when building with Clang on MSVC. Also included the `` header in tests and adjusted formatting for improved readability. --- cmake/configure.cmake | 2 +- tasks/example/tests/functional/main.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake/configure.cmake b/cmake/configure.cmake index e346f58a1..32a41802c 100644 --- a/cmake/configure.cmake +++ b/cmake/configure.cmake @@ -23,7 +23,7 @@ set( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" ) set( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" ) if ( MSVC AND (CMAKE_C_COMPILER_ID STREQUAL "Clang") AND (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")) - set( CMAKE_CXX_STANDARD 17 ) + set( CMAKE_CXX_STANDARD 20 ) else () set( CMAKE_CXX_STANDARD 23 ) endif () diff --git a/tasks/example/tests/functional/main.cpp b/tasks/example/tests/functional/main.cpp index e9d0de975..2836f2060 100644 --- a/tasks/example/tests/functional/main.cpp +++ b/tasks/example/tests/functional/main.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -45,7 +46,7 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests(GetParam()); const auto k_count = static_cast::size_type>(((width + height) / std::get<0>(params)) * - std::stoi(std::get<1>(params))); + std::stoi(std::get<1>(params))); input_data_ = InType(k_count * k_count, 0); for (std::vector::size_type i = 0; i < k_count; i++) { input_data_[(i * k_count) + i] = 1; From 38c32e9c460beaab0f096cf361e1d955274baa1b Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 3 Jun 2025 20:55:08 +0200 Subject: [PATCH 047/141] Update test parameters in functional test Updated the test parameter values from (5, 10, 15) to (3, 5, 7). This change ensures the tests cover a different range of input scenarios for improved validation. --- tasks/example/tests/functional/main.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tasks/example/tests/functional/main.cpp b/tasks/example/tests/functional/main.cpp index 2836f2060..2f836e75f 100644 --- a/tasks/example/tests/functional/main.cpp +++ b/tasks/example/tests/functional/main.cpp @@ -65,8 +65,7 @@ namespace { TEST_P(NesterovARunFuncTests, MatmulFromPic) { ExecuteTest(GetParam()); } -const std::array kTestParam = {std::make_tuple(5, "5"), std::make_tuple(10, "10"), - std::make_tuple(15, "15")}; +const std::array kTestParam = {std::make_tuple(3, "3"), std::make_tuple(5, "5"), std::make_tuple(7, "7")}; INIT_TASK_GENERATOR(InType, kTestParam) From 76dd44ae27ec97ce084a96d66c0a55bbf351115f Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 4 Jun 2025 00:01:06 +0200 Subject: [PATCH 048/141] Refactor tasks to simplify matrix operations and input handling Removed unnecessary matrix multiplication logic, replacing it with a streamlined computation approach. Standardized input/output types and ensured consistent initialization across tasks. Cleaned up unused private variables and redundant functions for better maintainability. --- tasks/example/all/include/ops_all.hpp | 6 --- tasks/example/all/src/ops_all.cpp | 64 ++++++++++++------------ tasks/example/common/include/common.hpp | 4 +- tasks/example/mpi/include/ops_mpi.hpp | 8 --- tasks/example/mpi/src/ops_mpi.cpp | 64 +++++++++++------------- tasks/example/omp/include/ops_omp.hpp | 3 -- tasks/example/omp/src/ops_omp.cpp | 46 +++++++++-------- tasks/example/seq/include/ops_seq.hpp | 3 -- tasks/example/seq/src/ops_seq.cpp | 39 +++++++++------ tasks/example/stl/include/ops_stl.hpp | 3 -- tasks/example/stl/src/ops_stl.cpp | 48 +++++++++--------- tasks/example/tbb/include/ops_tbb.hpp | 3 -- tasks/example/tbb/src/ops_tbb.cpp | 50 +++++++++--------- tasks/example/tests/functional/main.cpp | 10 ++-- tasks/example/tests/performance/main.cpp | 9 +--- 15 files changed, 170 insertions(+), 190 deletions(-) diff --git a/tasks/example/all/include/ops_all.hpp b/tasks/example/all/include/ops_all.hpp index 218e863c6..6bacdcade 100644 --- a/tasks/example/all/include/ops_all.hpp +++ b/tasks/example/all/include/ops_all.hpp @@ -6,9 +6,6 @@ namespace nesterov_a_test_task { -void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_vec); -void MatMulTBB(const std::vector &in_vec, int rc_size, std::vector &out_vec); - class NesterovATestTaskALL : public BaseTask { public: static constexpr ppc::core::TypeOfTask GetStaticTypeOfTask() { return ppc::core::TypeOfTask::kALL; } @@ -17,9 +14,6 @@ class NesterovATestTaskALL : public BaseTask { bool PreProcessingImpl() override; bool RunImpl() override; bool PostProcessingImpl() override; - - private: - int rc_size_{}; }; } // namespace nesterov_a_test_task diff --git a/tasks/example/all/src/ops_all.cpp b/tasks/example/all/src/ops_all.cpp index 221fa4221..4188ed118 100644 --- a/tasks/example/all/src/ops_all.cpp +++ b/tasks/example/all/src/ops_all.cpp @@ -13,63 +13,65 @@ namespace nesterov_a_test_task { -void MatMul(const InType &in_vec, int rc_size, OutType &out_vec) { - for (int i = 0; i < rc_size; ++i) { - for (int j = 0; j < rc_size; ++j) { - out_vec[(i * rc_size) + j] = 0; - for (int k = 0; k < rc_size; ++k) { - out_vec[(i * rc_size) + j] += in_vec[(i * rc_size) + k] * in_vec[(k * rc_size) + j]; - } - } - } -} - -void MatMulTBB(const InType &in_vec, int rc_size, OutType &out_vec) { - tbb::parallel_for(0, ppc::util::GetNumThreads(), [&](int i) { MatMul(in_vec, rc_size - i, out_vec); }); - MatMul(in_vec, rc_size, out_vec); -} - NesterovATestTaskALL::NesterovATestTaskALL(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; + GetOutput() = 0; } -bool NesterovATestTaskALL::ValidationImpl() { - auto sqrt_size = static_cast(std::sqrt(GetInput().size())); - return sqrt_size * sqrt_size == static_cast(GetInput().size()); -} +bool NesterovATestTaskALL::ValidationImpl() { return (GetInput() > 0) && (GetOutput() == 0); } bool NesterovATestTaskALL::PreProcessingImpl() { - // Init value for input and output - rc_size_ = static_cast(std::sqrt(GetInput().size())); - GetOutput() = OutType(GetInput().size(), 0); - return true; + GetOutput() = 2 * GetInput(); + return GetOutput() > 0; } bool NesterovATestTaskALL::RunImpl() { + for (InType i = 0; i < GetInput(); i++) { + for (InType j = 0; j < GetInput(); j++) { + for (InType k = 0; k < GetInput(); k++) { + std::vector tmp(i + j + k, 1); + GetOutput() += std::accumulate(tmp.begin(), tmp.end(), 0); + GetOutput() -= i + j + k; + } + } + } + + const int num_threads = ppc::util::GetNumThreads(); + GetOutput() *= num_threads; + int rank = -1; MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { + std::atomic counter(0); #pragma omp parallel default(none) { -#pragma omp critical - MatMul(GetInput(), rc_size_, GetOutput()); + counter++; } + GetOutput() /= counter; } else { - MatMulTBB(GetInput(), rc_size_, GetOutput()); + GetOutput() /= num_threads; } - const int num_threads = ppc::util::GetNumThreads(); + GetOutput() *= num_threads; std::vector threads(num_threads); + std::atomic counter(0); for (int i = 0; i < num_threads; i++) { - threads[i] = std::thread(MatMul, std::cref(GetInput()), rc_size_, std::ref(GetOutput())); + threads[i] = std::thread([&]() { counter++; }); threads[i].join(); } + GetOutput() /= counter; + + tbb::parallel_for(0, ppc::util::GetNumThreads(), [&](int i) { counter--; }); + GetOutput() += counter; MPI_Barrier(MPI_COMM_WORLD); - return true; + return GetOutput() > 0; } -bool NesterovATestTaskALL::PostProcessingImpl() { return true; } +bool NesterovATestTaskALL::PostProcessingImpl() { + GetOutput() -= GetInput(); + return GetOutput() > 0; +} } // namespace nesterov_a_test_task diff --git a/tasks/example/common/include/common.hpp b/tasks/example/common/include/common.hpp index 4f2d9d1bb..5530796a8 100644 --- a/tasks/example/common/include/common.hpp +++ b/tasks/example/common/include/common.hpp @@ -8,8 +8,8 @@ namespace nesterov_a_test_task { -using InType = std::vector; -using OutType = std::vector; +using InType = int; +using OutType = int; using TestType = std::tuple; using BaseTask = ppc::core::Task; diff --git a/tasks/example/mpi/include/ops_mpi.hpp b/tasks/example/mpi/include/ops_mpi.hpp index aa424b82f..ac4053fd6 100644 --- a/tasks/example/mpi/include/ops_mpi.hpp +++ b/tasks/example/mpi/include/ops_mpi.hpp @@ -7,9 +7,6 @@ namespace nesterov_a_test_task { -void MultiplyRowMajor(const std::vector &in, std::vector &out, int rc_size); -void MultiplyColumnMajor(const std::vector &in, std::vector &out, int rc_size); - class NesterovATestTaskMPI : public BaseTask { public: static constexpr ppc::core::TypeOfTask GetStaticTypeOfTask() { return ppc::core::TypeOfTask::kMPI; } @@ -18,11 +15,6 @@ class NesterovATestTaskMPI : public BaseTask { bool PreProcessingImpl() override; bool RunImpl() override; bool PostProcessingImpl() override; - - private: - int rc_size_{}; - - void MultiplyMatrixBasedOnRank(); }; } // namespace nesterov_a_test_task diff --git a/tasks/example/mpi/src/ops_mpi.cpp b/tasks/example/mpi/src/ops_mpi.cpp index cae5081f3..4147022da 100644 --- a/tasks/example/mpi/src/ops_mpi.cpp +++ b/tasks/example/mpi/src/ops_mpi.cpp @@ -5,62 +5,56 @@ #include #include #include -namespace nesterov_a_test_task { - -void MultiplyRowMajor(const InType &in, OutType &out, int rc_size) { - for (int i = 0; i < rc_size; ++i) { - for (int j = 0; j < rc_size; ++j) { - for (int k = 0; k < rc_size; ++k) { - out[(i * rc_size) + j] += in[(i * rc_size) + k] * in[(k * rc_size) + j]; - } - } - } -} -void MultiplyColumnMajor(const InType &in, OutType &out, int rc_size) { - for (int j = 0; j < rc_size; ++j) { - for (int k = 0; k < rc_size; ++k) { - for (int i = 0; i < rc_size; ++i) { - out[(i * rc_size) + j] += in[(i * rc_size) + k] * in[(k * rc_size) + j]; - } - } - } -} +namespace nesterov_a_test_task { NesterovATestTaskMPI::NesterovATestTaskMPI(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; + GetOutput() = 0; } -bool NesterovATestTaskMPI::ValidationImpl() { - auto sqrt_size = static_cast(std::sqrt(GetInput().size())); - return sqrt_size * sqrt_size == static_cast(GetInput().size()); -} +bool NesterovATestTaskMPI::ValidationImpl() { return (GetInput() > 0) && (GetOutput() == 0); } bool NesterovATestTaskMPI::PreProcessingImpl() { - // Init value for input and output - rc_size_ = static_cast(std::sqrt(GetInput().size())); - GetOutput() = OutType(GetInput().size(), 0); - return true; + GetOutput() = 2 * GetInput(); + return GetOutput() > 0; } bool NesterovATestTaskMPI::RunImpl() { - MultiplyMatrixBasedOnRank(); - return true; -} + for (InType i = 0; i < GetInput(); i++) { + for (InType j = 0; j < GetInput(); j++) { + for (InType k = 0; k < GetInput(); k++) { + std::vector tmp(i + j + k, 1); + GetOutput() += std::accumulate(tmp.begin(), tmp.end(), 0); + GetOutput() -= i + j + k; + } + } + } -bool NesterovATestTaskMPI::PostProcessingImpl() { return true; } + const int num_threads = ppc::util::GetNumThreads(); + GetOutput() *= num_threads; -void NesterovATestTaskMPI::MultiplyMatrixBasedOnRank() { int rank = -1; MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { - MultiplyRowMajor(GetInput(), GetOutput(), rc_size_); + GetOutput() /= num_threads; } else { - MultiplyColumnMajor(GetInput(), GetOutput(), rc_size_); + int counter = 0; + for (int i = 0; i < num_threads; i++) { + counter++; + } + GetOutput() /= counter; } + MPI_Barrier(MPI_COMM_WORLD); + return GetOutput() > 0; +} + +bool NesterovATestTaskMPI::PostProcessingImpl() { + GetOutput() -= GetInput(); + return GetOutput() > 0; } } // namespace nesterov_a_test_task diff --git a/tasks/example/omp/include/ops_omp.hpp b/tasks/example/omp/include/ops_omp.hpp index c9bc80699..581dbda75 100644 --- a/tasks/example/omp/include/ops_omp.hpp +++ b/tasks/example/omp/include/ops_omp.hpp @@ -16,9 +16,6 @@ class NesterovATestTaskOMP : public BaseTask { bool PreProcessingImpl() override; bool RunImpl() override; bool PostProcessingImpl() override; - - private: - int rc_size_{}; }; } // namespace nesterov_a_test_task diff --git a/tasks/example/omp/src/ops_omp.cpp b/tasks/example/omp/src/ops_omp.cpp index a1871cfee..2b8a75240 100644 --- a/tasks/example/omp/src/ops_omp.cpp +++ b/tasks/example/omp/src/ops_omp.cpp @@ -9,38 +9,42 @@ namespace nesterov_a_test_task { NesterovATestTaskOMP::NesterovATestTaskOMP(const InType& in) { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; + GetOutput() = 0; } -bool NesterovATestTaskOMP::ValidationImpl() { - auto sqrt_size = static_cast(std::sqrt(GetInput().size())); - return sqrt_size * sqrt_size == static_cast(GetInput().size()); -} +bool NesterovATestTaskOMP::ValidationImpl() { return (GetInput() > 0) && (GetOutput() == 0); } bool NesterovATestTaskOMP::PreProcessingImpl() { - rc_size_ = static_cast(std::sqrt(GetInput().size())); - GetOutput() = OutType(GetInput().size(), 0); - return true; + GetOutput() = 2 * GetInput(); + return GetOutput() > 0; } bool NesterovATestTaskOMP::RunImpl() { -#pragma omp parallel default(none) - { -#pragma omp critical - { - // Multiply matrices - for (int i = 0; i < rc_size_; ++i) { - for (int j = 0; j < rc_size_; ++j) { - GetOutput()[(i * rc_size_) + j] = 0; - for (int k = 0; k < rc_size_; ++k) { - GetOutput()[(i * rc_size_) + j] += GetInput()[(i * rc_size_) + k] * GetInput()[(k * rc_size_) + j]; - } - } + for (InType i = 0; i < GetInput(); i++) { + for (InType j = 0; j < GetInput(); j++) { + for (InType k = 0; k < GetInput(); k++) { + std::vector tmp(i + j + k, 1); + GetOutput() += std::accumulate(tmp.begin(), tmp.end(), 0); + GetOutput() -= i + j + k; } } } - return true; + + const int num_threads = ppc::util::GetNumThreads(); + GetOutput() *= num_threads; + + std::atomic counter(0); +#pragma omp parallel default(none) + { + counter++; + } + GetOutput() /= counter; + return GetOutput() > 0; } -bool NesterovATestTaskOMP::PostProcessingImpl() { return true; } +bool NesterovATestTaskOMP::PostProcessingImpl() { + GetOutput() -= GetInput(); + return GetOutput() > 0; +} } // namespace nesterov_a_test_task diff --git a/tasks/example/seq/include/ops_seq.hpp b/tasks/example/seq/include/ops_seq.hpp index 5dfa2869f..b72ff9aaa 100644 --- a/tasks/example/seq/include/ops_seq.hpp +++ b/tasks/example/seq/include/ops_seq.hpp @@ -16,9 +16,6 @@ class NesterovATestTaskSEQ : public BaseTask { bool PreProcessingImpl() override; bool RunImpl() override; bool PostProcessingImpl() override; - - private: - int rc_size_{}; }; } // namespace nesterov_a_test_task diff --git a/tasks/example/seq/src/ops_seq.cpp b/tasks/example/seq/src/ops_seq.cpp index 3b9d401d8..0ed459fef 100644 --- a/tasks/example/seq/src/ops_seq.cpp +++ b/tasks/example/seq/src/ops_seq.cpp @@ -9,31 +9,42 @@ namespace nesterov_a_test_task { NesterovATestTaskSEQ::NesterovATestTaskSEQ(const InType& in) { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; + GetOutput() = 0; } -bool NesterovATestTaskSEQ::ValidationImpl() { - auto sqrt_size = static_cast(std::sqrt(GetInput().size())); - return sqrt_size * sqrt_size == static_cast(GetInput().size()); -} +bool NesterovATestTaskSEQ::ValidationImpl() { return (GetInput() > 0) && (GetOutput() == 0); } bool NesterovATestTaskSEQ::PreProcessingImpl() { - rc_size_ = static_cast(std::sqrt(GetInput().size())); - GetOutput() = OutType(GetInput().size(), 0); - return true; + GetOutput() = 2 * GetInput(); + return GetOutput() > 0; } bool NesterovATestTaskSEQ::RunImpl() { - // Multiply matrices - for (int i = 0; i < rc_size_; ++i) { - for (int j = 0; j < rc_size_; ++j) { - for (int k = 0; k < rc_size_; ++k) { - GetOutput()[(i * rc_size_) + j] += GetInput()[(i * rc_size_) + k] * GetInput()[(k * rc_size_) + j]; + for (InType i = 0; i < GetInput(); i++) { + for (InType j = 0; j < GetInput(); j++) { + for (InType k = 0; k < GetInput(); k++) { + std::vector tmp(i + j + k, 1); + GetOutput() += std::accumulate(tmp.begin(), tmp.end(), 0); + GetOutput() -= i + j + k; } } } - return true; + + const int num_threads = ppc::util::GetNumThreads(); + GetOutput() *= num_threads; + + int counter = 0; + for (int i = 0; i < num_threads; i++) { + counter++; + } + + GetOutput() /= counter; + return GetOutput() > 0; } -bool NesterovATestTaskSEQ::PostProcessingImpl() { return true; } +bool NesterovATestTaskSEQ::PostProcessingImpl() { + GetOutput() -= GetInput(); + return GetOutput() > 0; +} } // namespace nesterov_a_test_task diff --git a/tasks/example/stl/include/ops_stl.hpp b/tasks/example/stl/include/ops_stl.hpp index 4e100e9b5..a26afbffe 100644 --- a/tasks/example/stl/include/ops_stl.hpp +++ b/tasks/example/stl/include/ops_stl.hpp @@ -16,9 +16,6 @@ class NesterovATestTaskSTL : public BaseTask { bool PreProcessingImpl() override; bool RunImpl() override; bool PostProcessingImpl() override; - - private: - int rc_size_{}; }; } // namespace nesterov_a_test_task diff --git a/tasks/example/stl/src/ops_stl.cpp b/tasks/example/stl/src/ops_stl.cpp index 572d3e788..ecdf601bf 100644 --- a/tasks/example/stl/src/ops_stl.cpp +++ b/tasks/example/stl/src/ops_stl.cpp @@ -10,45 +10,47 @@ namespace nesterov_a_test_task { -namespace { -void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_vec) { - for (int i = 0; i < rc_size; ++i) { - for (int j = 0; j < rc_size; ++j) { - out_vec[(i * rc_size) + j] = 0; - for (int k = 0; k < rc_size; ++k) { - out_vec[(i * rc_size) + j] += in_vec[(i * rc_size) + k] * in_vec[(k * rc_size) + j]; - } - } - } -} -} // namespace - NesterovATestTaskSTL::NesterovATestTaskSTL(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; + GetOutput() = 0; } -bool NesterovATestTaskSTL::ValidationImpl() { - auto sqrt_size = static_cast(std::sqrt(GetInput().size())); - return sqrt_size * sqrt_size == static_cast(GetInput().size()); -} +bool NesterovATestTaskSTL::ValidationImpl() { return (GetInput() > 0) && (GetOutput() == 0); } bool NesterovATestTaskSTL::PreProcessingImpl() { - rc_size_ = static_cast(std::sqrt(GetInput().size())); - GetOutput() = OutType(GetInput().size(), 0); - return true; + GetOutput() = 2 * GetInput(); + return GetOutput() > 0; } bool NesterovATestTaskSTL::RunImpl() { + for (InType i = 0; i < GetInput(); i++) { + for (InType j = 0; j < GetInput(); j++) { + for (InType k = 0; k < GetInput(); k++) { + std::vector tmp(i + j + k, 1); + GetOutput() += std::accumulate(tmp.begin(), tmp.end(), 0); + GetOutput() -= i + j + k; + } + } + } + const int num_threads = ppc::util::GetNumThreads(); std::vector threads(num_threads); + GetOutput() *= num_threads; + + std::atomic counter(0); for (int i = 0; i < num_threads; i++) { - threads[i] = std::thread(MatMul, GetInput(), rc_size_, std::ref(GetOutput())); + threads[i] = std::thread([&]() { counter++; }); threads[i].join(); } - return true; + + GetOutput() /= counter; + return GetOutput() > 0; } -bool NesterovATestTaskSTL::PostProcessingImpl() { return true; } +bool NesterovATestTaskSTL::PostProcessingImpl() { + GetOutput() -= GetInput(); + return GetOutput() > 0; +} } // namespace nesterov_a_test_task diff --git a/tasks/example/tbb/include/ops_tbb.hpp b/tasks/example/tbb/include/ops_tbb.hpp index 43533ccd5..02da419ee 100644 --- a/tasks/example/tbb/include/ops_tbb.hpp +++ b/tasks/example/tbb/include/ops_tbb.hpp @@ -16,9 +16,6 @@ class NesterovATestTaskTBB : public BaseTask { bool PreProcessingImpl() override; bool RunImpl() override; bool PostProcessingImpl() override; - - private: - int rc_size_{}; }; } // namespace nesterov_a_test_task diff --git a/tasks/example/tbb/src/ops_tbb.cpp b/tasks/example/tbb/src/ops_tbb.cpp index e00410214..f47cd9a02 100644 --- a/tasks/example/tbb/src/ops_tbb.cpp +++ b/tasks/example/tbb/src/ops_tbb.cpp @@ -11,41 +11,43 @@ namespace nesterov_a_test_task { -namespace { -void MatMul(const std::vector &in_vec, int rc_size, std::vector &out_vec) { - for (int i = 0; i < rc_size; ++i) { - for (int j = 0; j < rc_size; ++j) { - out_vec[(i * rc_size) + j] = 0; - for (int k = 0; k < rc_size; ++k) { - out_vec[(i * rc_size) + j] += in_vec[(i * rc_size) + k] * in_vec[(k * rc_size) + j]; - } - } - } -} -} // namespace - NesterovATestTaskTBB::NesterovATestTaskTBB(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); GetInput() = in; + GetOutput() = 0; } -bool NesterovATestTaskTBB::ValidationImpl() { - auto sqrt_size = static_cast(std::sqrt(GetInput().size())); - return sqrt_size * sqrt_size == static_cast(GetInput().size()); -} +bool NesterovATestTaskTBB::ValidationImpl() { return (GetInput() > 0) && (GetOutput() == 0); } bool NesterovATestTaskTBB::PreProcessingImpl() { - rc_size_ = static_cast(std::sqrt(GetInput().size())); - GetOutput() = OutType(GetInput().size(), 0); - return true; + GetOutput() = 2 * GetInput(); + return GetOutput() > 0; } bool NesterovATestTaskTBB::RunImpl() { - tbb::parallel_for(0, ppc::util::GetNumThreads(), [&](int i) { MatMul(GetInput(), rc_size_ - i, GetOutput()); }); - MatMul(GetInput(), rc_size_, GetOutput()); - return true; + for (InType i = 0; i < GetInput(); i++) { + for (InType j = 0; j < GetInput(); j++) { + for (InType k = 0; k < GetInput(); k++) { + std::vector tmp(i + j + k, 1); + GetOutput() += std::accumulate(tmp.begin(), tmp.end(), 0); + GetOutput() -= i + j + k; + } + } + } + + const int num_threads = ppc::util::GetNumThreads(); + GetOutput() *= num_threads; + + std::atomic counter(0); + tbb::parallel_for(0, ppc::util::GetNumThreads(), [&](int i) { counter++; }); + + GetOutput() /= counter; + return GetOutput() > 0; } -bool NesterovATestTaskTBB::PostProcessingImpl() { return true; } +bool NesterovATestTaskTBB::PostProcessingImpl() { + GetOutput() -= GetInput(); + return GetOutput() > 0; +} } // namespace nesterov_a_test_task diff --git a/tasks/example/tests/functional/main.cpp b/tasks/example/tests/functional/main.cpp index 2f836e75f..8d05b0554 100644 --- a/tasks/example/tests/functional/main.cpp +++ b/tasks/example/tests/functional/main.cpp @@ -30,6 +30,7 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests img; // Read image { std::string abs_path = ppc::util::GetAbsolutePath("example/data/pic.jpg"); @@ -37,7 +38,7 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests(data, data + (static_cast(width * height * channels))); + img = std::vector(data, data + (static_cast(width * height * channels))); stbi_image_free(data); if (std::cmp_not_equal(width, height)) { throw std::runtime_error("width != height: "); @@ -45,12 +46,7 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests(GetParam()); - const auto k_count = static_cast::size_type>(((width + height) / std::get<0>(params)) * - std::stoi(std::get<1>(params))); - input_data_ = InType(k_count * k_count, 0); - for (std::vector::size_type i = 0; i < k_count; i++) { - input_data_[(i * k_count) + i] = 1; - } + input_data_ = width - height + std::min(std::accumulate(img.begin(), img.end(), 0), channels); } bool CheckTestOutputData(OutType &output_data) final { return input_data_ == output_data; } diff --git a/tasks/example/tests/performance/main.cpp b/tasks/example/tests/performance/main.cpp index 47e31babc..2a243cddb 100644 --- a/tasks/example/tests/performance/main.cpp +++ b/tasks/example/tests/performance/main.cpp @@ -19,15 +19,10 @@ namespace nesterov_a_test_task { class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { - const std::vector::size_type kCount = 400; + const std::vector::size_type kCount = 111; InType input_data_; - void SetUp() override { - input_data_.assign(kCount * kCount, 0U); - for (std::vector::size_type i = 0; i < kCount; ++i) { - input_data_[(i * kCount) + i] = 1; - } - } + void SetUp() override { input_data_ = kCount; } bool CheckTestOutputData(OutType& output_data) final { return input_data_ == output_data; } From dc6d8bae7e5b4638ea03740711dc5031f52798d6 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 4 Jun 2025 00:07:33 +0200 Subject: [PATCH 049/141] Add include and fix OpenMP shared directive Include the header where needed to ensure proper functionality. Update OpenMP parallel region directives to explicitly declare the shared variable `counter` to avoid potential issues. --- tasks/example/all/src/ops_all.cpp | 5 +++-- tasks/example/omp/src/ops_omp.cpp | 3 ++- tasks/example/stl/src/ops_stl.cpp | 1 + tasks/example/tbb/src/ops_tbb.cpp | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tasks/example/all/src/ops_all.cpp b/tasks/example/all/src/ops_all.cpp index 4188ed118..2bef01619 100644 --- a/tasks/example/all/src/ops_all.cpp +++ b/tasks/example/all/src/ops_all.cpp @@ -2,6 +2,7 @@ #include +#include #include #include #include @@ -44,7 +45,7 @@ bool NesterovATestTaskALL::RunImpl() { MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { std::atomic counter(0); -#pragma omp parallel default(none) +#pragma omp parallel default(none) shared(counter) { counter++; } @@ -62,7 +63,7 @@ bool NesterovATestTaskALL::RunImpl() { } GetOutput() /= counter; - tbb::parallel_for(0, ppc::util::GetNumThreads(), [&](int i) { counter--; }); + tbb::parallel_for(0, ppc::util::GetNumThreads(), [&](int /*i*/) { counter--; }); GetOutput() += counter; MPI_Barrier(MPI_COMM_WORLD); diff --git a/tasks/example/omp/src/ops_omp.cpp b/tasks/example/omp/src/ops_omp.cpp index 2b8a75240..3effe680c 100644 --- a/tasks/example/omp/src/ops_omp.cpp +++ b/tasks/example/omp/src/ops_omp.cpp @@ -1,5 +1,6 @@ #include "example/omp/include/ops_omp.hpp" +#include #include #include #include @@ -34,7 +35,7 @@ bool NesterovATestTaskOMP::RunImpl() { GetOutput() *= num_threads; std::atomic counter(0); -#pragma omp parallel default(none) +#pragma omp parallel default(none) shared(counter) { counter++; } diff --git a/tasks/example/stl/src/ops_stl.cpp b/tasks/example/stl/src/ops_stl.cpp index ecdf601bf..06eeb6cfb 100644 --- a/tasks/example/stl/src/ops_stl.cpp +++ b/tasks/example/stl/src/ops_stl.cpp @@ -1,5 +1,6 @@ #include "example/stl/include/ops_stl.hpp" +#include #include #include #include diff --git a/tasks/example/tbb/src/ops_tbb.cpp b/tasks/example/tbb/src/ops_tbb.cpp index f47cd9a02..330accfda 100644 --- a/tasks/example/tbb/src/ops_tbb.cpp +++ b/tasks/example/tbb/src/ops_tbb.cpp @@ -2,6 +2,7 @@ #include +#include #include #include #include @@ -39,7 +40,7 @@ bool NesterovATestTaskTBB::RunImpl() { GetOutput() *= num_threads; std::atomic counter(0); - tbb::parallel_for(0, ppc::util::GetNumThreads(), [&](int i) { counter++; }); + tbb::parallel_for(0, ppc::util::GetNumThreads(), [&](int /*i*/) { counter++; }); GetOutput() /= counter; return GetOutput() > 0; From ba1ba0291f25ab57c04e7eeb68b0499ae296edf0 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 4 Jun 2025 00:38:20 +0200 Subject: [PATCH 050/141] Refactor member variable naming and initialization. Renamed `kCount` to `kCount_` to align with naming conventions. Added default initialization for `input_data_` and updated `SetUp()` accordingly for consistency and clarity. --- tasks/example/tests/performance/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasks/example/tests/performance/main.cpp b/tasks/example/tests/performance/main.cpp index 2a243cddb..254fe0119 100644 --- a/tasks/example/tests/performance/main.cpp +++ b/tasks/example/tests/performance/main.cpp @@ -19,10 +19,10 @@ namespace nesterov_a_test_task { class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { - const std::vector::size_type kCount = 111; - InType input_data_; + const std::vector::size_type kCount_ = 111; + InType input_data_{}; - void SetUp() override { input_data_ = kCount; } + void SetUp() override { input_data_ = kCount_; } bool CheckTestOutputData(OutType& output_data) final { return input_data_ == output_data; } From b51ab41712ed045a70bea6ba77269848ac2f4692 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 4 Jun 2025 06:42:51 +0200 Subject: [PATCH 051/141] Add Intel oneAPI setup for OpenMP in GitHub Actions Integrated Intel oneAPI into the workflow to enable OpenMP support for the project. Updated CMake configuration to include necessary OpenMP flags and library paths. This ensures compatibility with Intel's OpenMP runtime for improved parallelization.Simplify Intel oneAPI setup in CI workflow Removed the explicit `rscohn2/setup-oneapi` action and streamlined the OpenMP configuration directly within the CMake command. This reduces external dependencies while maintaining compatibility with Intel's oneAPI tools. --- .github/workflows/main.yml | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index aaf5422e2..10c350249 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -810,25 +810,37 @@ jobs: windows_compile_environment: msvc - name: Setup ninja uses: seanmiddleditch/gha-setup-ninja@v6 - - name: Setup MSVC for Ninja again + - name: Setup MSVC for Ninja uses: ilammy/msvc-dev-cmd@v1 + - name: Install Intel OpenMP via NuGet + run: | + nuget install intelopenmp.redist.win -Version 2025.1.1.9 -OutputDirectory intel-openmp + shell: pwsh + - name: Set environment variables for Intel OpenMP + shell: pwsh + run: | + echo "LIB=${{ github.workspace }}\\intel-openmp\\intelopenmp.redist.win.2025.1.1.9\\redist\\intel64\\compiler" >> $env:GITHUB_ENV + echo "PATH=${{ github.workspace }}\\intel-openmp\\intelopenmp.redist.win.2025.1.1.9\\redist\\intel64\\compiler;$env:PATH" >> $env:GITHUB_ENV - name: CMake configure run: > - cmake -S . -B build -G Ninja -D CMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl - -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -D CMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=install + cmake -S . -B build -G Ninja + -D CMAKE_C_COMPILER=clang-cl + -D CMAKE_CXX_COMPILER=clang-cl + -D CMAKE_C_COMPILER_LAUNCHER=ccache + -D CMAKE_CXX_COMPILER_LAUNCHER=ccache + -D CMAKE_BUILD_TYPE=Release + -D CMAKE_INSTALL_PREFIX=install + -D CMAKE_CXX_FLAGS="/clang:-fopenmp=libiomp5 /link libiomp5md.lib" env: CC: clang-cl CXX: clang-cl - name: Build project - run: | - cmake --build build --config Release --parallel + run: cmake --build build --config Release --parallel env: CC: clang-cl CXX: clang-cl - name: Install project - run: | - cmake --install build + run: cmake --install build - name: Archive installed package run: Compress-Archive -Path install -DestinationPath windows-clang-install.zip shell: pwsh From dd19a318c310463dd63aa18522139c20e42bd986 Mon Sep 17 00:00:00 2001 From: Nesterov Alexander Date: Wed, 4 Jun 2025 10:54:07 +0200 Subject: [PATCH 052/141] Update main.yml --- .github/workflows/main.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 10c350249..7e79be6c7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -812,15 +812,14 @@ jobs: uses: seanmiddleditch/gha-setup-ninja@v6 - name: Setup MSVC for Ninja uses: ilammy/msvc-dev-cmd@v1 - - name: Install Intel OpenMP via NuGet + - name: Install Intel oneAPI Base Toolkit (includes OpenMP runtime) run: | - nuget install intelopenmp.redist.win -Version 2025.1.1.9 -OutputDirectory intel-openmp - shell: pwsh - - name: Set environment variables for Intel OpenMP - shell: pwsh + choco install intel-oneapi-runtime -y + choco install intel-oneapi-compiler-dpcpp-cpp -y + choco install intel-oneapi-runtime-openmp -y + - name: Check OpenMP runtime run: | - echo "LIB=${{ github.workspace }}\\intel-openmp\\intelopenmp.redist.win.2025.1.1.9\\redist\\intel64\\compiler" >> $env:GITHUB_ENV - echo "PATH=${{ github.workspace }}\\intel-openmp\\intelopenmp.redist.win.2025.1.1.9\\redist\\intel64\\compiler;$env:PATH" >> $env:GITHUB_ENV + dir "C:\Program Files (x86)\Intel\oneAPI\compiler\latest\windows\redist\intel64_win\compiler" - name: CMake configure run: > cmake -S . -B build -G Ninja @@ -830,7 +829,9 @@ jobs: -D CMAKE_CXX_COMPILER_LAUNCHER=ccache -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=install - -D CMAKE_CXX_FLAGS="/clang:-fopenmp=libiomp5 /link libiomp5md.lib" + -DCMAKE_INCLUDE_PATH="C:/Program Files (x86)/Intel/oneAPI/compiler/latest/windows/include" + -DCMAKE_LIBRARY_PATH="C:/Program Files (x86)/Intel/oneAPI/compiler/latest/windows/lib/intel64_win" + -DCMAKE_EXE_LINKER_FLAGS="/NODEFAULTLIB:vcomp.lib /DEFAULTLIB:libiomp5md.lib" env: CC: clang-cl CXX: clang-cl From 90796b58181c1d772559bcb96b9a49e417308aba Mon Sep 17 00:00:00 2001 From: Nesterov Alexander Date: Wed, 4 Jun 2025 11:04:19 +0200 Subject: [PATCH 053/141] Update main.yml --- .github/workflows/main.yml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7e79be6c7..0a60d33f0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -811,15 +811,11 @@ jobs: - name: Setup ninja uses: seanmiddleditch/gha-setup-ninja@v6 - name: Setup MSVC for Ninja - uses: ilammy/msvc-dev-cmd@v1 - - name: Install Intel oneAPI Base Toolkit (includes OpenMP runtime) - run: | - choco install intel-oneapi-runtime -y - choco install intel-oneapi-compiler-dpcpp-cpp -y - choco install intel-oneapi-runtime-openmp -y - - name: Check OpenMP runtime + uses: ilammy/msvc-dev-cmd@v1 + - name: Install Intel OpenMP via NuGet run: | - dir "C:\Program Files (x86)\Intel\oneAPI\compiler\latest\windows\redist\intel64_win\compiler" + nuget install intelopenmp.redist.win + shell: pwsh - name: CMake configure run: > cmake -S . -B build -G Ninja @@ -829,19 +825,22 @@ jobs: -D CMAKE_CXX_COMPILER_LAUNCHER=ccache -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=install - -DCMAKE_INCLUDE_PATH="C:/Program Files (x86)/Intel/oneAPI/compiler/latest/windows/include" - -DCMAKE_LIBRARY_PATH="C:/Program Files (x86)/Intel/oneAPI/compiler/latest/windows/lib/intel64_win" + -DCMAKE_INCLUDE_PATH="C:/Program Files (x86)/Intel/oneAPI/compiler/latest/windows/include" ^ + -DCMAKE_LIBRARY_PATH="C:/Program Files (x86)/Intel/oneAPI/compiler/latest/windows/lib/intel64_win" ^ -DCMAKE_EXE_LINKER_FLAGS="/NODEFAULTLIB:vcomp.lib /DEFAULTLIB:libiomp5md.lib" + shell: pwsh env: CC: clang-cl CXX: clang-cl - name: Build project run: cmake --build build --config Release --parallel + shell: pwsh env: CC: clang-cl CXX: clang-cl - name: Install project run: cmake --install build + shell: pwsh - name: Archive installed package run: Compress-Archive -Path install -DestinationPath windows-clang-install.zip shell: pwsh From e997ee83d527e352f37a7d57663aa141935b07d8 Mon Sep 17 00:00:00 2001 From: Nesterov Alexander Date: Wed, 4 Jun 2025 11:07:50 +0200 Subject: [PATCH 054/141] Update main.yml --- .github/workflows/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0a60d33f0..0e4955683 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -825,9 +825,9 @@ jobs: -D CMAKE_CXX_COMPILER_LAUNCHER=ccache -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=install - -DCMAKE_INCLUDE_PATH="C:/Program Files (x86)/Intel/oneAPI/compiler/latest/windows/include" ^ - -DCMAKE_LIBRARY_PATH="C:/Program Files (x86)/Intel/oneAPI/compiler/latest/windows/lib/intel64_win" ^ - -DCMAKE_EXE_LINKER_FLAGS="/NODEFAULTLIB:vcomp.lib /DEFAULTLIB:libiomp5md.lib" + -D CMAKE_INCLUDE_PATH="C:/Program Files (x86)/Intel/oneAPI/compiler/latest/windows/include" + -D CMAKE_LIBRARY_PATH="C:/Program Files (x86)/Intel/oneAPI/compiler/latest/windows/lib/intel64_win" + -D CMAKE_EXE_LINKER_FLAGS="/NODEFAULTLIB:vcomp.lib \"C:/Program Files (x86)/Intel/oneAPI/compiler/latest/windows/lib/intel64_win/libiomp5md.lib\"" shell: pwsh env: CC: clang-cl From a2e4f11c66bb3d92ef76d462877d952dc742fee1 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 4 Jun 2025 11:33:15 +0200 Subject: [PATCH 055/141] Refactor threading and parallelism logic in tasks. Commented out unused code in `run_tests.py` related to `threads` and `processes`. Consolidated threading structures in `ops_all.cpp` with improved scoping for clarity. Minor syntax adjustment in `main.cpp` --- scripts/run_tests.py | 4 +-- tasks/example/all/src/ops_all.cpp | 47 ++++++++++++++----------- tasks/example/tests/functional/main.cpp | 2 +- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/scripts/run_tests.py b/scripts/run_tests.py index a0639d213..b877229ec 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -111,8 +111,8 @@ def run_performance_list(self): ppc_runner = PPCRunner() ppc_runner.setup_env() - if args_dict["running_type"] in ["threads", "processes"]: - ppc_runner.run_core() + # if args_dict["running_type"] in ["threads", "processes"]: + # ppc_runner.run_core() if args_dict["running_type"] == "threads": ppc_runner.run_threads() diff --git a/tasks/example/all/src/ops_all.cpp b/tasks/example/all/src/ops_all.cpp index 2bef01619..eb5336639 100644 --- a/tasks/example/all/src/ops_all.cpp +++ b/tasks/example/all/src/ops_all.cpp @@ -39,33 +39,40 @@ bool NesterovATestTaskALL::RunImpl() { } const int num_threads = ppc::util::GetNumThreads(); - GetOutput() *= num_threads; + { + GetOutput() *= num_threads; - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - if (rank == 0) { - std::atomic counter(0); + int rank = -1; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + if (rank == 0) { + std::atomic counter(0); #pragma omp parallel default(none) shared(counter) - { - counter++; + { + counter++; + } + GetOutput() /= counter; + } else { + GetOutput() /= num_threads; } - GetOutput() /= counter; - } else { - GetOutput() /= num_threads; } - GetOutput() *= num_threads; - std::vector threads(num_threads); - std::atomic counter(0); - for (int i = 0; i < num_threads; i++) { - threads[i] = std::thread([&]() { counter++; }); - threads[i].join(); + { + GetOutput() *= num_threads; + std::vector threads(num_threads); + std::atomic counter(0); + for (int i = 0; i < num_threads; i++) { + threads[i] = std::thread([&]() { counter++; }); + threads[i].join(); + } + GetOutput() /= counter; } - GetOutput() /= counter; - - tbb::parallel_for(0, ppc::util::GetNumThreads(), [&](int /*i*/) { counter--; }); - GetOutput() += counter; + { + GetOutput() *= num_threads; + std::atomic counter(0); + tbb::parallel_for(0, ppc::util::GetNumThreads(), [&](int /*i*/) { counter++; }); + GetOutput() /= counter; + } MPI_Barrier(MPI_COMM_WORLD); return GetOutput() > 0; } diff --git a/tasks/example/tests/functional/main.cpp b/tasks/example/tests/functional/main.cpp index 8d05b0554..ed8fc820f 100644 --- a/tasks/example/tests/functional/main.cpp +++ b/tasks/example/tests/functional/main.cpp @@ -49,7 +49,7 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests Date: Wed, 4 Jun 2025 11:33:39 +0200 Subject: [PATCH 056/141] Enable core run for threads and processes in test runner Uncommented and restored the logic to invoke `run_core` when the running type is either "threads" or "processes". This ensures the test runner executes core functionality as intended for these cases. --- scripts/run_tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/run_tests.py b/scripts/run_tests.py index b877229ec..a0639d213 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -111,8 +111,8 @@ def run_performance_list(self): ppc_runner = PPCRunner() ppc_runner.setup_env() - # if args_dict["running_type"] in ["threads", "processes"]: - # ppc_runner.run_core() + if args_dict["running_type"] in ["threads", "processes"]: + ppc_runner.run_core() if args_dict["running_type"] == "threads": ppc_runner.run_threads() From a42c6be5f526f8320e602c586c76891b881b0043 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 4 Jun 2025 11:49:26 +0200 Subject: [PATCH 057/141] Add debug logs for task input and output in test utility Inserted debug statements to print `task_->GetInput()` and `task_->GetOutput()` during test execution. This will help in diagnosing issues by providing better visibility into the intermediate data. --- modules/core/util/include/func_test_util.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/core/util/include/func_test_util.hpp b/modules/core/util/include/func_test_util.hpp index ba2924740..2bfac3051 100644 --- a/modules/core/util/include/func_test_util.hpp +++ b/modules/core/util/include/func_test_util.hpp @@ -56,6 +56,8 @@ class BaseRunFuncTests : public ::testing::TestWithParamPreProcessing()); ASSERT_TRUE(task_->Run()); ASSERT_TRUE(task_->PostProcessing()); + std::cout << "task_->GetInput() = " << task_->GetInput() << std::endl; + std::cout << "task_->GetOutput() = " << task_->GetOutput() << std::endl; ASSERT_TRUE(CheckTestOutputData(task_->GetOutput())); } From ab2242f42ccae14c46a5241ec20f2d54b72f0a6f Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 4 Jun 2025 14:14:56 +0200 Subject: [PATCH 058/141] Add OMP thread control and refactor environment handling Introduced `omp_set_num_threads` for OpenMP thread control in functional and performance runners. Refactored `PPCRunner` to rely on a custom environment dictionary rather than `os.environ`, improving encapsulation and configurability. Enhanced error checks for required environment variables (`PPC_NUM_THREADS` and `PPC_NUM_PROC`). --- .github/workflows/main.yml | 52 +++++++++++++++++++++++++++++++++++ scripts/run_tests.py | 43 +++++++++++++++++------------ tasks/runners/functional.cpp | 3 ++ tasks/runners/performance.cpp | 3 ++ 4 files changed, 84 insertions(+), 17 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0e4955683..eac3092cf 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -134,18 +134,22 @@ jobs: - name: Run func tests (threads, num_threads=1) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 1 - name: Run func tests (threads, num_threads=2) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 2 - name: Run func tests (threads, num_threads=3) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 3 - name: Run func tests (threads, num_threads=4) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 4 ubuntu-gcc-test-extended: needs: @@ -172,18 +176,22 @@ jobs: - name: Run func tests (threads, num_threads=5) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 5 - name: Run func tests (threads, num_threads=7) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 7 - name: Run func tests (threads, num_threads=11) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 11 - name: Run func tests (threads, num_threads=13) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 13 ubuntu-clang-build: needs: @@ -283,18 +291,22 @@ jobs: - name: Run tests (threads, num_threads=1) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 1 - name: Run tests (threads, num_threads=2) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 2 - name: Run tests (threads, num_threads=3) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 3 - name: Run tests (threads, num_threads=4) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 4 ubuntu-clang-test-extended: needs: @@ -323,18 +335,22 @@ jobs: - name: Run tests (threads, num_threads=5) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 5 - name: Run tests (threads, num_threads=7) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 7 - name: Run tests (threads, num_threads=11) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 11 - name: Run tests (threads, num_threads=13) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 13 ubuntu-clang-sanitizer-build: needs: @@ -424,6 +440,7 @@ jobs: - name: Run tests (threads, num_threads=1) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 1 PPC_ASAN_RUN: 1 ASAN_OPTIONS: abort_on_error=1 @@ -431,6 +448,7 @@ jobs: - name: Run tests (threads, num_threads=2) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 2 PPC_ASAN_RUN: 1 ASAN_OPTIONS: abort_on_error=1 @@ -438,6 +456,7 @@ jobs: - name: Run tests (threads, num_threads=3) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 3 PPC_ASAN_RUN: 1 ASAN_OPTIONS: abort_on_error=1 @@ -445,6 +464,7 @@ jobs: - name: Run tests (threads, num_threads=4) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 4 PPC_ASAN_RUN: 1 ASAN_OPTIONS: abort_on_error=1 @@ -477,21 +497,25 @@ jobs: - name: Run tests (threads, num_threads=5) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 5 PPC_ASAN_RUN: 1 - name: Run tests (threads, num_threads=7) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 7 PPC_ASAN_RUN: 1 - name: Run tests (threads, num_threads=11) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 11 PPC_ASAN_RUN: 1 - name: Run tests (threads, num_threads=13) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 13 PPC_ASAN_RUN: 1 macos-clang-build: @@ -584,18 +608,22 @@ jobs: - name: Run tests (threads, num_threads=1) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 1 - name: Run tests (threads, num_threads=2) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 2 - name: Run tests (threads, num_threads=3) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 3 - name: Run tests (threads, num_threads=4) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 4 macos-clang-test-extended: needs: @@ -622,18 +650,22 @@ jobs: - name: Run tests (threads, num_threads=5) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 5 - name: Run tests (threads, num_threads=7) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 7 - name: Run tests (threads, num_threads=11) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 11 - name: Run tests (threads, num_threads=13) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 13 windows-msvc-build: needs: @@ -731,18 +763,22 @@ jobs: - name: Run tests (threads, num_threads=1) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 1 - name: Run tests (threads, num_threads=2) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 2 - name: Run tests (threads, num_threads=3) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 3 - name: Run tests (threads, num_threads=4) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 4 windows-msvc-test-extended: needs: @@ -771,18 +807,22 @@ jobs: - name: Run tests (threads, num_threads=5) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 5 - name: Run tests (threads, num_threads=7) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 7 - name: Run tests (threads, num_threads=11) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 11 - name: Run tests (threads, num_threads=13) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 13 windows-clang-build: needs: @@ -876,18 +916,22 @@ jobs: - name: Run tests (threads, num_threads=1) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 1 - name: Run tests (threads, num_threads=2) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 2 - name: Run tests (threads, num_threads=3) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 3 - name: Run tests (threads, num_threads=4) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 4 windows-clang-test-extended: needs: @@ -916,18 +960,22 @@ jobs: - name: Run tests (threads, num_threads=5) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 5 - name: Run tests (threads, num_threads=7) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 7 - name: Run tests (threads, num_threads=11) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 11 - name: Run tests (threads, num_threads=13) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 13 ubuntu-gcc-build-codecov: needs: @@ -967,18 +1015,22 @@ jobs: - name: Run tests (threads, num_threads=1) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 1 - name: Run tests (threads, num_threads=2) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 2 - name: Run tests (threads, num_threads=3) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 3 - name: Run tests (threads, num_threads=4) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 4 - name: Generate gcovr Coverage Data run: | diff --git a/scripts/run_tests.py b/scripts/run_tests.py index a0639d213..fdd48bc50 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -26,6 +26,9 @@ def init_cmd_args(): class PPCRunner: def __init__(self): + self.__ppc_num_threads = None + self.__ppc_num_proc = None + self.__ppc_env = None self.work_dir = None self.valgrind_cmd = "valgrind --error-exitcode=1 --leak-check=full --show-leak-kinds=all" @@ -40,15 +43,25 @@ def __get_project_path(): script_dir = script_path.parent # Directory containing the script return script_dir.parent - def setup_env(self): + def setup_env(self, ppc_env): + self.__ppc_env = ppc_env + + self.__ppc_num_threads = self.__ppc_env.get("PPC_NUM_THREADS") + if self.__ppc_num_threads is None: + raise EnvironmentError("Required environment variable 'PPC_NUM_THREADS' is not set.") + self.__ppc_env["OMP_NUM_THREADS"] = self.__ppc_num_threads + + self.__ppc_num_proc = self.__ppc_env.get("PPC_NUM_PROC") + if self.__ppc_num_proc is None: + raise EnvironmentError("Required environment variable 'PPC_NUM_PROC' is not set.") + if (Path(self.__get_project_path()) / "install").exists(): self.work_dir = Path(self.__get_project_path()) / "install" / "bin" else: self.work_dir = Path(self.__get_project_path()) / "build" / "bin" - @staticmethod - def __run_exec(command): - result = subprocess.run(command, shell=True, env=os.environ) + def __run_exec(self, command): + result = subprocess.run(command, shell=True, env=self.__ppc_env) if result.returncode != 0: raise Exception(f"Subprocess return {result.returncode}.") @@ -62,7 +75,7 @@ def __get_gtest_settings(repeats_count, type_task): return command def run_threads(self): - if platform.system() == "Linux" and not os.environ.get("PPC_ASAN_RUN"): + if platform.system() == "Linux" and not self.__ppc_env.get("PPC_ASAN_RUN"): for task_type in ["seq", "stl"]: self.__run_exec(f"{self.valgrind_cmd} {self.work_dir / 'ppc_func_tests'} " f"{self.__get_gtest_settings(1, '_' + task_type + '_')}") @@ -71,29 +84,26 @@ def run_threads(self): self.__run_exec(f"{self.work_dir / 'ppc_func_tests'} {self.__get_gtest_settings(3, '_' + task_type + '_')}") def run_core(self): - if platform.system() == "Linux" and not os.environ.get("PPC_ASAN_RUN"): + if platform.system() == "Linux" and not self.__ppc_env.get("PPC_ASAN_RUN"): self.__run_exec(f"{self.valgrind_cmd} {self.work_dir / 'core_func_tests'} " f"{self.__get_gtest_settings(1, '*')}") self.__run_exec(f"{self.work_dir / 'core_func_tests'} {self.__get_gtest_settings(1, '*')}") def run_processes(self, additional_mpi_args): - PPC_NUM_PROC = os.environ.get("PPC_NUM_PROC") - if PPC_NUM_PROC is None: + ppc_num_proc = self.__ppc_env.get("PPC_NUM_PROC") + if ppc_num_proc is None: raise EnvironmentError("Required environment variable 'PPC_NUM_PROC' is not set.") - mpi_running = f"{self.mpi_exec} {additional_mpi_args} -np {PPC_NUM_PROC}" - if not os.environ.get("PPC_ASAN_RUN"): + mpi_running = f"{self.mpi_exec} {additional_mpi_args} -np {ppc_num_proc}" + if not self.__ppc_env.get("PPC_ASAN_RUN"): for task_type in ["all", "mpi"]: self.__run_exec(f"{mpi_running} {self.work_dir / 'ppc_func_tests'} " f"{self.__get_gtest_settings(10, '_' + task_type)}") def run_performance(self): - if not os.environ.get("PPC_ASAN_RUN"): - PPC_NUM_PROC = os.environ.get("PPC_NUM_PROC") - if PPC_NUM_PROC is None: - raise EnvironmentError("Required environment variable 'PPC_NUM_PROC' is not set.") - mpi_running = f"{self.mpi_exec} -np {PPC_NUM_PROC}" + if not self.__ppc_env.get("PPC_ASAN_RUN"): + mpi_running = f"{self.mpi_exec} -np {self.__ppc_num_proc}" for task_type in ["all", "mpi"]: self.__run_exec(f"{mpi_running} {self.work_dir / 'ppc_perf_tests'} " f"{self.__get_gtest_settings(1, '_' + task_type)}") @@ -107,9 +117,8 @@ def run_performance_list(self): if __name__ == "__main__": args_dict = init_cmd_args() - ppc_runner = PPCRunner() - ppc_runner.setup_env() + ppc_runner.setup_env(os.environ.copy()) if args_dict["running_type"] in ["threads", "processes"]: ppc_runner.run_core() diff --git a/tasks/runners/functional.cpp b/tasks/runners/functional.cpp index 0ba891220..bd280b15c 100644 --- a/tasks/runners/functional.cpp +++ b/tasks/runners/functional.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -75,6 +76,8 @@ int main(int argc, char** argv) { // Limit the number of threads in TBB tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetNumThreads()); + // Limit the number of threads in OMP + omp_set_num_threads(ppc::util::GetNumThreads()); ::testing::InitGoogleTest(&argc, argv); diff --git a/tasks/runners/performance.cpp b/tasks/runners/performance.cpp index 0ba891220..bd280b15c 100644 --- a/tasks/runners/performance.cpp +++ b/tasks/runners/performance.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -75,6 +76,8 @@ int main(int argc, char** argv) { // Limit the number of threads in TBB tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetNumThreads()); + // Limit the number of threads in OMP + omp_set_num_threads(ppc::util::GetNumThreads()); ::testing::InitGoogleTest(&argc, argv); From 93b19baa098cc0c7568ea8d2a26b883bd6cb4184 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 4 Jun 2025 14:43:01 +0200 Subject: [PATCH 059/141] **Replace `exit` with `std::terminate` and refine error handling** Replaced `exit(2)` with `std::terminate` in multiple runners for better error handling consistency. Simplified Task constructor by removing custom terminate handler and directly logging the error on destruction if the function order is incorrect. Removed redundant debug output in `func_test_util.hpp` for cleaner test logic. --- modules/core/task/include/task.hpp | 12 +++--------- modules/core/util/include/func_test_util.hpp | 2 -- tasks/runners/functional.cpp | 2 +- tasks/runners/performance.cpp | 2 +- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/modules/core/task/include/task.hpp b/modules/core/task/include/task.hpp index 02c7ea6db..edb1dd1ae 100644 --- a/modules/core/task/include/task.hpp +++ b/modules/core/task/include/task.hpp @@ -70,15 +70,7 @@ enum StateOfTesting : uint8_t { kFunc, kPerf }; template class Task { public: - explicit Task(StateOfTesting /*state_of_testing*/ = StateOfTesting::kFunc) { - auto custom_terminate = []() { - std::cerr << "ORDER OF FUNCTIONS IS NOT RIGHT! \n" - "Expected - \"Validation\", \"PreProcessing\", \"Run\", \"PostProcessing\" \n"; - std::abort(); - }; - std::set_terminate(custom_terminate); - functions_order_.clear(); - } + explicit Task(StateOfTesting /*state_of_testing*/ = StateOfTesting::kFunc) { functions_order_.clear(); } // validation of data and validation of task attributes before running virtual bool Validation() final { @@ -131,6 +123,8 @@ class Task { virtual ~Task() { if (!functions_order_.empty() || !was_worked_) { + std::cerr << "ORDER OF FUNCTIONS IS NOT RIGHT! \n Expected - \"Validation\", \"PreProcessing\", \"Run\", " + "\"PostProcessing\" \n"; std::terminate(); } else { functions_order_.clear(); diff --git a/modules/core/util/include/func_test_util.hpp b/modules/core/util/include/func_test_util.hpp index 2bfac3051..ba2924740 100644 --- a/modules/core/util/include/func_test_util.hpp +++ b/modules/core/util/include/func_test_util.hpp @@ -56,8 +56,6 @@ class BaseRunFuncTests : public ::testing::TestWithParamPreProcessing()); ASSERT_TRUE(task_->Run()); ASSERT_TRUE(task_->PostProcessing()); - std::cout << "task_->GetInput() = " << task_->GetInput() << std::endl; - std::cout << "task_->GetOutput() = " << task_->GetOutput() << std::endl; ASSERT_TRUE(CheckTestOutputData(task_->GetOutput())); } diff --git a/tasks/runners/functional.cpp b/tasks/runners/functional.cpp index bd280b15c..f114708f0 100644 --- a/tasks/runners/functional.cpp +++ b/tasks/runners/functional.cpp @@ -32,7 +32,7 @@ class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { "[ PROCESS %d ] [ FAILED ] %s.%s: MPI message queue has an unread message from process %d with tag %d\n", rank, "test_suite_name", "test_name", status.MPI_SOURCE, status.MPI_TAG); MPI_Finalize(); - exit(2); + std::terminate(); } MPI_Barrier(MPI_COMM_WORLD); diff --git a/tasks/runners/performance.cpp b/tasks/runners/performance.cpp index bd280b15c..f114708f0 100644 --- a/tasks/runners/performance.cpp +++ b/tasks/runners/performance.cpp @@ -32,7 +32,7 @@ class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { "[ PROCESS %d ] [ FAILED ] %s.%s: MPI message queue has an unread message from process %d with tag %d\n", rank, "test_suite_name", "test_name", status.MPI_SOURCE, status.MPI_TAG); MPI_Finalize(); - exit(2); + std::terminate(); } MPI_Barrier(MPI_COMM_WORLD); From 431496f686d9d7a325b7aa3c225a3b2ae08819a5 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 4 Jun 2025 17:20:27 +0200 Subject: [PATCH 060/141] Filter out death tests in run_tests.py Adjusted `run_tests.py` to exclude death tests from execution by modifying the gtest filter settings. Renamed death test cases in `task_tests.cpp` for consistency and improved clarity. Also removed an outdated comment in `util.hpp` for better maintainability. --- modules/core/task/func_tests/task_tests.cpp | 4 ++-- modules/core/util/include/util.hpp | 2 +- scripts/run_tests.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/core/task/func_tests/task_tests.cpp b/modules/core/task/func_tests/task_tests.cpp index 301244438..1adf72377 100644 --- a/modules/core/task/func_tests/task_tests.cpp +++ b/modules/core/task/func_tests/task_tests.cpp @@ -128,7 +128,7 @@ TEST(task_tests, check_float) { EXPECT_NEAR(test_task.GetOutput(), in.size(), 1e-3); } -DEATH_TEST(task_tests, check_wrong_order) { +DEATH_TEST(task_tests, check_wrong_order_death_test) { auto destroy_function = [] { // Create data std::vector in(20, 1); @@ -143,7 +143,7 @@ DEATH_TEST(task_tests, check_wrong_order) { EXPECT_DEATH_IF_SUPPORTED(destroy_function(), ".*ORDER OF FUNCTIONS IS NOT RIGHT.*"); } -DEATH_TEST(task_tests, check_empty_order) { +DEATH_TEST(task_tests, check_empty_order_death_test) { auto destroy_function = [] { // Create data std::vector in(20, 1); diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index f6719907f..d40e9a2d5 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -5,7 +5,7 @@ #ifdef _MSC_VER #pragma warning(push) -#pragma warning(disable : 4459) // переменная 'last' перекрывает глобальную +#pragma warning(disable : 4459) #endif #include diff --git a/scripts/run_tests.py b/scripts/run_tests.py index fdd48bc50..db3ead07c 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -86,7 +86,7 @@ def run_threads(self): def run_core(self): if platform.system() == "Linux" and not self.__ppc_env.get("PPC_ASAN_RUN"): self.__run_exec(f"{self.valgrind_cmd} {self.work_dir / 'core_func_tests'} " - f"{self.__get_gtest_settings(1, '*')}") + f"{self.__get_gtest_settings(1, '*')} --gtest_filter=*:-*_death_test") self.__run_exec(f"{self.work_dir / 'core_func_tests'} {self.__get_gtest_settings(1, '*')}") From c75efb60abdf5d560332b962aed8088a8c1dfd25 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 4 Jun 2025 17:35:39 +0200 Subject: [PATCH 061/141] Add Valgrind suppression file and integrate into test script Created a `valgrind.supp` file to suppress specific known issues during memory checks. Updated the test script to utilize this suppression file in the Valgrind command, improving test reliability and reducing false positives. --- scripts/run_tests.py | 5 ++++- valgrind.supp | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 valgrind.supp diff --git a/scripts/run_tests.py b/scripts/run_tests.py index db3ead07c..3e2182cdc 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -30,7 +30,10 @@ def __init__(self): self.__ppc_num_proc = None self.__ppc_env = None self.work_dir = None - self.valgrind_cmd = "valgrind --error-exitcode=1 --leak-check=full --show-leak-kinds=all" + + suppression_file = Path(self.__get_project_path()) / "valgrind.supp" + self.valgrind_cmd = (f"valgrind --suppressions={suppression_file} " + f"--error-exitcode=1 --leak-check=full --show-leak-kinds=all") if platform.system() == "Windows": self.mpi_exec = "mpiexec" diff --git a/valgrind.supp b/valgrind.supp new file mode 100644 index 000000000..d69e0c308 --- /dev/null +++ b/valgrind.supp @@ -0,0 +1,16 @@ +{ + hwloc_still_reachable + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + obj:*/lib*/**/hwloc*.so* +} + +{ + ignore-rdmacm-leak + Memcheck:Leak + match-leak-kinds: reachable + fun:calloc + ... + fun:rdma_create_event_channel +} From 38371666f1d1de01363000291c1b96a9eb23c3e4 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Thu, 5 Jun 2025 00:01:48 +0200 Subject: [PATCH 062/141] Refactor for modern C++ features and cleanup. Replaced legacy I/O functions (`fprintf`, `printf`) with modern `` utilities for improved readability and safety. Updated function signatures to use `const` references where appropriate and removed redundant `else` clauses. Simplified the valgrind command by removing unused suppression file, and deleted the obsolete `valgrind.supp` file. --- modules/core/task/include/task.hpp | 7 +++---- scripts/run_tests.py | 4 +--- tasks/runners/functional.cpp | 11 +++++------ tasks/runners/performance.cpp | 15 +++++++-------- valgrind.supp | 16 ---------------- 5 files changed, 16 insertions(+), 37 deletions(-) delete mode 100644 valgrind.supp diff --git a/modules/core/task/include/task.hpp b/modules/core/task/include/task.hpp index edb1dd1ae..3ec22fcac 100644 --- a/modules/core/task/include/task.hpp +++ b/modules/core/task/include/task.hpp @@ -25,12 +25,11 @@ enum StatusOfTask : uint8_t { kEnabled, kDisabled }; inline std::string GetStringTaskStatus(StatusOfTask status_of_task) { if (status_of_task == kDisabled) { return "disabled"; - } else { - return "enabled"; } + return "enabled"; } -inline std::string GetStringTaskType(TypeOfTask type_of_task, std::string settings_file_path) { +inline std::string GetStringTaskType(TypeOfTask type_of_task, const std::string &settings_file_path) { std::ifstream file(settings_file_path); if (!file.is_open()) { throw std::runtime_error("Failed to open file settings.json"); @@ -38,7 +37,7 @@ inline std::string GetStringTaskType(TypeOfTask type_of_task, std::string settin nlohmann::json list_settings; file >> list_settings; - auto to_type_str = [&](std::string type) -> std::string { + auto to_type_str = [&](const std::string &type) -> std::string { return type + "_" + std::string(list_settings["tasks"][type]); }; diff --git a/scripts/run_tests.py b/scripts/run_tests.py index 3e2182cdc..4b6fee1d0 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -31,9 +31,7 @@ def __init__(self): self.__ppc_env = None self.work_dir = None - suppression_file = Path(self.__get_project_path()) / "valgrind.supp" - self.valgrind_cmd = (f"valgrind --suppressions={suppression_file} " - f"--error-exitcode=1 --leak-check=full --show-leak-kinds=all") + self.valgrind_cmd = "valgrind --error-exitcode=1 --leak-check=full --show-leak-kinds=all" if platform.system() == "Windows": self.mpi_exec = "mpiexec" diff --git a/tasks/runners/functional.cpp b/tasks/runners/functional.cpp index f114708f0..9e479788f 100644 --- a/tasks/runners/functional.cpp +++ b/tasks/runners/functional.cpp @@ -3,8 +3,8 @@ #include #include -#include #include +#include #include #include @@ -27,12 +27,11 @@ class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status); if (flag != 0) { - fprintf( + std::println( stderr, - "[ PROCESS %d ] [ FAILED ] %s.%s: MPI message queue has an unread message from process %d with tag %d\n", + "[ PROCESS {} ] [ FAILED ] {}.{}: MPI message queue has an unread message from process {} with tag {}", rank, "test_suite_name", "test_name", status.MPI_SOURCE, status.MPI_TAG); - MPI_Finalize(); - std::terminate(); + exit(EXIT_FAILURE); // NOLINT } MPI_Barrier(MPI_COMM_WORLD); @@ -65,7 +64,7 @@ class WorkerTestFailurePrinter : public ::testing::EmptyTestEventListener { static void PrintProcessRank() { int rank = -1; MPI_Comm_rank(MPI_COMM_WORLD, &rank); - printf(" [ PROCESS %d ] ", rank); + std::print(" [ PROCESS {} ] ", rank); } std::shared_ptr<::testing::TestEventListener> base_; diff --git a/tasks/runners/performance.cpp b/tasks/runners/performance.cpp index f114708f0..765544056 100644 --- a/tasks/runners/performance.cpp +++ b/tasks/runners/performance.cpp @@ -3,8 +3,8 @@ #include #include -#include #include +#include #include #include @@ -27,12 +27,11 @@ class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status); if (flag != 0) { - fprintf( - stderr, - "[ PROCESS %d ] [ FAILED ] %s.%s: MPI message queue has an unread message from process %d with tag %d\n", - rank, "test_suite_name", "test_name", status.MPI_SOURCE, status.MPI_TAG); - MPI_Finalize(); - std::terminate(); + std::println(stderr, + "[ PROCESS {} ] [ FAILED ] MPI message queue has an unread message from process {} with tag {}", + rank, status.MPI_SOURCE, status.MPI_TAG); + + exit(EXIT_FAILURE); // NOLINT } MPI_Barrier(MPI_COMM_WORLD); @@ -65,7 +64,7 @@ class WorkerTestFailurePrinter : public ::testing::EmptyTestEventListener { static void PrintProcessRank() { int rank = -1; MPI_Comm_rank(MPI_COMM_WORLD, &rank); - printf(" [ PROCESS %d ] ", rank); + std::print(" [ PROCESS {} ] ", rank); } std::shared_ptr<::testing::TestEventListener> base_; diff --git a/valgrind.supp b/valgrind.supp deleted file mode 100644 index d69e0c308..000000000 --- a/valgrind.supp +++ /dev/null @@ -1,16 +0,0 @@ -{ - hwloc_still_reachable - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc - obj:*/lib*/**/hwloc*.so* -} - -{ - ignore-rdmacm-leak - Memcheck:Leak - match-leak-kinds: reachable - fun:calloc - ... - fun:rdma_create_event_channel -} From dc93e46d55f843c79d734fcae524e888f534a7be Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Thu, 5 Jun 2025 00:14:09 +0200 Subject: [PATCH 063/141] Use Valgrind suppression files and replace `exit` with `MPI_Abort` Added a Valgrind suppression file to handle internal MPI-related leaks, ensuring cleaner Valgrind output during tests. Replaced `exit` calls with `MPI_Abort` to properly terminate MPI programs on failure. Updated test script to utilize the new suppression file in Valgrind commands. --- scripts/run_tests.py | 4 +++- tasks/runners/functional.cpp | 2 +- tasks/runners/performance.cpp | 2 +- valgrind.supp | 15 +++++++++++++++ 4 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 valgrind.supp diff --git a/scripts/run_tests.py b/scripts/run_tests.py index 4b6fee1d0..3e2182cdc 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -31,7 +31,9 @@ def __init__(self): self.__ppc_env = None self.work_dir = None - self.valgrind_cmd = "valgrind --error-exitcode=1 --leak-check=full --show-leak-kinds=all" + suppression_file = Path(self.__get_project_path()) / "valgrind.supp" + self.valgrind_cmd = (f"valgrind --suppressions={suppression_file} " + f"--error-exitcode=1 --leak-check=full --show-leak-kinds=all") if platform.system() == "Windows": self.mpi_exec = "mpiexec" diff --git a/tasks/runners/functional.cpp b/tasks/runners/functional.cpp index 9e479788f..e0751206b 100644 --- a/tasks/runners/functional.cpp +++ b/tasks/runners/functional.cpp @@ -31,7 +31,7 @@ class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { stderr, "[ PROCESS {} ] [ FAILED ] {}.{}: MPI message queue has an unread message from process {} with tag {}", rank, "test_suite_name", "test_name", status.MPI_SOURCE, status.MPI_TAG); - exit(EXIT_FAILURE); // NOLINT + MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); } MPI_Barrier(MPI_COMM_WORLD); diff --git a/tasks/runners/performance.cpp b/tasks/runners/performance.cpp index 765544056..65262e5ab 100644 --- a/tasks/runners/performance.cpp +++ b/tasks/runners/performance.cpp @@ -31,7 +31,7 @@ class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { "[ PROCESS {} ] [ FAILED ] MPI message queue has an unread message from process {} with tag {}", rank, status.MPI_SOURCE, status.MPI_TAG); - exit(EXIT_FAILURE); // NOLINT + MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); } MPI_Barrier(MPI_COMM_WORLD); diff --git a/valgrind.supp b/valgrind.supp new file mode 100644 index 000000000..28656437a --- /dev/null +++ b/valgrind.supp @@ -0,0 +1,15 @@ +{ + suppress mpi init internal leaks + Memcheck:Leak + ... + fun:MPI_Init + ... +} + +{ + suppress mpi finalize internal leaks + Memcheck:Leak + ... + fun:MPI_Finalize + ... +} \ No newline at end of file From 198cea963ef23cc6e36e9f37a9bc3f38b5f9d662 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Thu, 5 Jun 2025 00:16:56 +0200 Subject: [PATCH 064/141] Set C++ standard to 23 unconditionally Removed conditional logic for setting the C++ standard based on compiler and platform. The code now consistently enforces C++23 as the standard across all configurations for clarity and uniformity. --- cmake/configure.cmake | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/cmake/configure.cmake b/cmake/configure.cmake index 32a41802c..95e55c46d 100644 --- a/cmake/configure.cmake +++ b/cmake/configure.cmake @@ -22,11 +22,8 @@ set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/arch" ) set( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" ) set( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" ) -if ( MSVC AND (CMAKE_C_COMPILER_ID STREQUAL "Clang") AND (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")) - set( CMAKE_CXX_STANDARD 20 ) -else () - set( CMAKE_CXX_STANDARD 23 ) -endif () +set( CMAKE_CXX_STANDARD 23 ) + set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_COMPILE_WARNING_AS_ERROR ON) From bb8a044d445eb13ffcad107ffa656796d3c15e54 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Thu, 5 Jun 2025 15:15:01 +0200 Subject: [PATCH 065/141] Refactor runners directory and add ASAN-specific handling Moved runner files from 'tasks/runners' to 'tasks/common/runners' for better organization. Added conditional handling for AddressSanitizer (ASAN) runs by defining `USE_ASAN` based on environment configuration. Adjusted MPI initialization and threading controls accordingly for improved flexibility. --- cmake/configure.cmake | 4 ++++ tasks/CMakeLists.txt | 6 +++--- tasks/{ => common}/runners/functional.cpp | 10 ++++++++++ tasks/{ => common}/runners/performance.cpp | 10 ++++++++++ 4 files changed, 27 insertions(+), 3 deletions(-) rename tasks/{ => common}/runners/functional.cpp (89%) rename tasks/{ => common}/runners/performance.cpp (88%) diff --git a/cmake/configure.cmake b/cmake/configure.cmake index 95e55c46d..3eb48d370 100644 --- a/cmake/configure.cmake +++ b/cmake/configure.cmake @@ -6,6 +6,10 @@ if (APPLE) set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG TRUE) endif(APPLE) +if(DEFINED ENV{PPC_ASAN_RUN} AND "$ENV{PPC_ASAN_RUN}" STREQUAL "1") + add_compile_definitions(USE_ASAN) +endif() + if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif(NOT CMAKE_BUILD_TYPE) diff --git a/tasks/CMakeLists.txt b/tasks/CMakeLists.txt index 6c60c582b..4ed5ec6a7 100644 --- a/tasks/CMakeLists.txt +++ b/tasks/CMakeLists.txt @@ -7,19 +7,19 @@ set(exec_perf_tests "ppc_perf_tests") # Init func tests executable files set(list_of_exec_tests "") if (USE_FUNC_TESTS) - add_executable(${exec_func_tests} "${CMAKE_CURRENT_SOURCE_DIR}/runners/functional.cpp") + add_executable(${exec_func_tests} "${CMAKE_CURRENT_SOURCE_DIR}/common/runners/functional.cpp") list(APPEND list_of_exec_tests ${exec_func_tests}) endif (USE_FUNC_TESTS) # Init perf tests executable files if (USE_PERF_TESTS) - add_executable(${exec_perf_tests} "${CMAKE_CURRENT_SOURCE_DIR}/runners/performance.cpp") + add_executable(${exec_perf_tests} "${CMAKE_CURRENT_SOURCE_DIR}/common/runners/performance.cpp") list(APPEND list_of_exec_tests ${exec_perf_tests}) endif (USE_PERF_TESTS) SUBDIRLIST(subdirs ${CMAKE_CURRENT_LIST_DIR}) foreach(subd ${subdirs}) - if (subd STREQUAL "runners") + if (subd STREQUAL "common") continue() endif () add_subdirectory(${subd}) diff --git a/tasks/runners/functional.cpp b/tasks/common/runners/functional.cpp similarity index 89% rename from tasks/runners/functional.cpp rename to tasks/common/runners/functional.cpp index e0751206b..00a793389 100644 --- a/tasks/runners/functional.cpp +++ b/tasks/common/runners/functional.cpp @@ -71,6 +71,7 @@ class WorkerTestFailurePrinter : public ::testing::EmptyTestEventListener { }; int main(int argc, char** argv) { +#ifndef USE_ASAN MPI_Init(&argc, &argv); // Limit the number of threads in TBB @@ -92,4 +93,13 @@ int main(int argc, char** argv) { MPI_Finalize(); return status; +#else + // Limit the number of threads in TBB + tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetNumThreads()); + // Limit the number of threads in OMP + omp_set_num_threads(ppc::util::GetNumThreads()); + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +#endif } diff --git a/tasks/runners/performance.cpp b/tasks/common/runners/performance.cpp similarity index 88% rename from tasks/runners/performance.cpp rename to tasks/common/runners/performance.cpp index 65262e5ab..9ec561205 100644 --- a/tasks/runners/performance.cpp +++ b/tasks/common/runners/performance.cpp @@ -71,6 +71,7 @@ class WorkerTestFailurePrinter : public ::testing::EmptyTestEventListener { }; int main(int argc, char** argv) { +#ifndef USE_ASAN MPI_Init(&argc, &argv); // Limit the number of threads in TBB @@ -92,4 +93,13 @@ int main(int argc, char** argv) { MPI_Finalize(); return status; +#else + // Limit the number of threads in TBB + tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetNumThreads()); + // Limit the number of threads in OMP + omp_set_num_threads(ppc::util::GetNumThreads()); + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +#endif } From 5d9109d709b25fca403362a186b3c3bd7e80bccf Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Fri, 6 Jun 2025 00:19:10 +0200 Subject: [PATCH 066/141] Add PPC_ASAN_RUN logic and refactor task/test macros Introduce `PPC_ASAN_RUN` to handle ASAN-specific configurations, replacing `USE_ASAN`. Refactor task initialization and testing macros for improved readability and flexibility. Adjust test and build scripts to incorporate new environment variables and settings management. --- .github/workflows/main.yml | 1 + modules/core/util/include/func_test_util.hpp | 34 ++++++++------ modules/core/util/include/perf_test_util.hpp | 48 ++++++++++++++++---- scripts/run_tests.py | 4 +- tasks/CMakeLists.txt | 8 ++++ tasks/common/runners/functional.cpp | 2 +- tasks/common/runners/performance.cpp | 2 +- tasks/example/CMakeLists.txt | 13 +++--- tasks/example/info.json | 3 +- tasks/example/tests/functional/main.cpp | 8 ++-- tasks/example/tests/performance/main.cpp | 15 +++--- 11 files changed, 95 insertions(+), 43 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index eac3092cf..1db23eb43 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -387,6 +387,7 @@ jobs: env: CC: clang-20 CXX: clang++-20 + PPC_ASAN_RUN: 1 - name: Build project run: | cmake --build build --parallel diff --git a/modules/core/util/include/func_test_util.hpp b/modules/core/util/include/func_test_util.hpp index ba2924740..3870d4458 100644 --- a/modules/core/util/include/func_test_util.hpp +++ b/modules/core/util/include/func_test_util.hpp @@ -74,19 +74,27 @@ auto ExpandToValues(const Tuple& t) { return ExpandToValuesImpl(t, std::make_index_sequence{}); } -#define INIT_TASK_GENERATOR(InTypeParam, SizesParam) \ - template \ - auto GenTaskTuplesImpl(std::index_sequence) { \ - return std::make_tuple( \ - std::make_tuple(ppc::core::TaskGetter, \ - std::string(ppc::util::GetNamespace()) + std::string("_") + \ - ppc::core::GetStringTaskType(Task::GetStaticTypeOfTask(), PPC_STUDENT_SETTINGS), \ - SizesParam[Is])...); \ - } \ - \ - template \ - auto TaskListGenerator() { \ - return GenTaskTuplesImpl(std::make_index_sequence{}); \ +#define INIT_TASK_GENERATOR(InTypeParam, SizesParam, SettingsPath) \ + template \ + auto GenTaskTuplesImpl(std::index_sequence) { \ + return std::make_tuple( \ + std::make_tuple(ppc::core::TaskGetter, \ + std::string(ppc::util::GetNamespace()) + std::string("_") + \ + ppc::core::GetStringTaskType(Task::GetStaticTypeOfTask(), SettingsPath), \ + SizesParam[Is])...); \ + } \ + \ + template \ + auto TaskListGenerator() { \ + return GenTaskTuplesImpl(std::make_index_sequence{}); \ } +#define ADD_FUNC_TASK_THREADS(TASK) TaskListGenerator() + +#ifndef PPC_ASAN_RUN +#define ADD_FUNC_TASK_PROCESS(TASK) TaskListGenerator() +#else +#define ADD_FUNC_TASK_PROCESS(TASK) std::tuple<>() +#endif + } // namespace ppc::util diff --git a/modules/core/util/include/perf_test_util.hpp b/modules/core/util/include/perf_test_util.hpp index 0eec5ba70..87424e520 100644 --- a/modules/core/util/include/perf_test_util.hpp +++ b/modules/core/util/include/perf_test_util.hpp @@ -79,11 +79,16 @@ class BaseRunPerfTests : public ::testing::TestWithParamGetOutput(); ASSERT_TRUE(CheckTestOutputData(output_data)); } @@ -92,14 +97,39 @@ class BaseRunPerfTests : public ::testing::TestWithParam task_; }; -#define ADD_PERF_TASK(TaskType, InputTypeParam) \ - std::make_tuple(ppc::core::TaskGetter, \ - std::string(ppc::util::GetNamespace()) + std::string("_") + \ - ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), PPC_STUDENT_SETTINGS), \ - ppc::core::PerfResults::TypeOfRunning::kPipeline), \ - std::make_tuple(ppc::core::TaskGetter, \ - std::string(ppc::util::GetNamespace()) + std::string("_") + \ - ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), PPC_STUDENT_SETTINGS), \ - ppc::core::PerfResults::TypeOfRunning::kTaskRun) +#define ADD_PERF_TASK_THREADS(TaskType, InputTypeParam, SettingsPath) \ + std::tuple(std::make_tuple(ppc::core::TaskGetter, \ + std::string(ppc::util::GetNamespace()) + "_" + \ + ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), SettingsPath), \ + ppc::core::PerfResults::TypeOfRunning::kPipeline), \ + std::make_tuple(ppc::core::TaskGetter, \ + std::string(ppc::util::GetNamespace()) + "_" + \ + ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), SettingsPath), \ + ppc::core::PerfResults::TypeOfRunning::kTaskRun)) + +template +auto TupleToGTestValuesImpl(Tuple&& tup, std::index_sequence) { + return ::testing::Values(std::get(std::forward(tup))...); +} + +template +auto TupleToGTestValues(Tuple&& tup) { + constexpr size_t size = std::tuple_size>::value; + return TupleToGTestValuesImpl(std::forward(tup), std::make_index_sequence{}); +} + +#ifndef PPC_ASAN_RUN +#define ADD_PERF_TASK_PROCESS(TaskType, InputTypeParam, SettingsPath) \ + std::tuple(std::make_tuple(ppc::core::TaskGetter, \ + std::string(ppc::util::GetNamespace()) + "_" + \ + ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), SettingsPath), \ + ppc::core::PerfResults::TypeOfRunning::kPipeline), \ + std::make_tuple(ppc::core::TaskGetter, \ + std::string(ppc::util::GetNamespace()) + "_" + \ + ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), SettingsPath), \ + ppc::core::PerfResults::TypeOfRunning::kTaskRun)) +#else +#define ADD_PERF_TASK_PROCESS(TaskType, InputTypeParam, SettingsPath) std::make_tuple() +#endif } // namespace ppc::util diff --git a/scripts/run_tests.py b/scripts/run_tests.py index 3e2182cdc..6220ae53a 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -123,8 +123,8 @@ def run_performance_list(self): ppc_runner = PPCRunner() ppc_runner.setup_env(os.environ.copy()) - if args_dict["running_type"] in ["threads", "processes"]: - ppc_runner.run_core() + # if args_dict["running_type"] in ["threads", "processes"]: + # ppc_runner.run_core() if args_dict["running_type"] == "threads": ppc_runner.run_threads() diff --git a/tasks/CMakeLists.txt b/tasks/CMakeLists.txt index 4ed5ec6a7..7b723b847 100644 --- a/tasks/CMakeLists.txt +++ b/tasks/CMakeLists.txt @@ -17,11 +17,19 @@ if (USE_PERF_TESTS) list(APPEND list_of_exec_tests ${exec_perf_tests}) endif (USE_PERF_TESTS) +if((DEFINED ENV{PPC_ASAN_RUN}) AND ("$ENV{PPC_ASAN_RUN}" STREQUAL "1")) + add_compile_definitions(PPC_ASAN_RUN) +endif() + SUBDIRLIST(subdirs ${CMAKE_CURRENT_LIST_DIR}) foreach(subd ${subdirs}) if (subd STREQUAL "common") continue() endif () + + set(SETTINGS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${subd}/settings.json") + add_compile_definitions(PPC_SETTINGS_${subd}=\"${SETTINGS_PATH}\") + add_subdirectory(${subd}) endforeach() diff --git a/tasks/common/runners/functional.cpp b/tasks/common/runners/functional.cpp index 00a793389..8a86afdf6 100644 --- a/tasks/common/runners/functional.cpp +++ b/tasks/common/runners/functional.cpp @@ -71,7 +71,7 @@ class WorkerTestFailurePrinter : public ::testing::EmptyTestEventListener { }; int main(int argc, char** argv) { -#ifndef USE_ASAN +#ifndef PPC_ASAN_RUN MPI_Init(&argc, &argv); // Limit the number of threads in TBB diff --git a/tasks/common/runners/performance.cpp b/tasks/common/runners/performance.cpp index 9ec561205..83b2afc87 100644 --- a/tasks/common/runners/performance.cpp +++ b/tasks/common/runners/performance.cpp @@ -71,7 +71,7 @@ class WorkerTestFailurePrinter : public ::testing::EmptyTestEventListener { }; int main(int argc, char** argv) { -#ifndef USE_ASAN +#ifndef PPC_ASAN_RUN MPI_Init(&argc, &argv); // Limit the number of threads in TBB diff --git a/tasks/example/CMakeLists.txt b/tasks/example/CMakeLists.txt index 57951303d..4674353d1 100644 --- a/tasks/example/CMakeLists.txt +++ b/tasks/example/CMakeLists.txt @@ -1,10 +1,6 @@ get_filename_component(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) project(CURRENT_DIR_NAME) -add_library("${CURRENT_DIR_NAME}_common" INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/common/include/common.hpp") -get_filename_component(SETTINGS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/settings.json" ABSOLUTE) -target_compile_definitions("${CURRENT_DIR_NAME}_common" INTERFACE PPC_STUDENT_SETTINGS=\"${SETTINGS_PATH}\") - set(exec_func_tests "ppc_func_tests") set(exec_perf_tests "ppc_perf_tests") set(test_base_dir "${CMAKE_CURRENT_SOURCE_DIR}/tests") @@ -28,8 +24,13 @@ endif (USE_PERF_TESTS) get_filename_component(TASK_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) message(STATUS "-- ${TASK_NAME}") +set(technologies "omp" "seq" "stl" "tbb") +if((NOT DEFINED ENV{PPC_ASAN_RUN}) OR ("$ENV{PPC_ASAN_RUN}" STREQUAL "0")) + list(APPEND technologies "all" "mpi") +endif() + # Create lib -foreach (dir_type "all" "mpi" "omp" "seq" "stl" "tbb") +foreach (dir_type ${technologies}) # Check directory existing set(base_dir "${CMAKE_CURRENT_SOURCE_DIR}/${dir_type}") if (NOT EXISTS "${base_dir}") @@ -51,7 +52,7 @@ foreach (dir_type "all" "mpi" "omp" "seq" "stl" "tbb") add_library(${name_lib} STATIC ${lib_source_files}) endif() set_target_properties(${name_lib} PROPERTIES LINKER_LANGUAGE CXX) - target_link_libraries(${name_lib} PUBLIC core_module_lib "${CURRENT_DIR_NAME}_common") + target_link_libraries(${name_lib} PUBLIC core_module_lib) # Link core library foreach (exec_func ${list_of_exec_tests}) diff --git a/tasks/example/info.json b/tasks/example/info.json index 9d0020dbc..a6abcae41 100644 --- a/tasks/example/info.json +++ b/tasks/example/info.json @@ -3,6 +3,7 @@ "first_name": "Нестеров", "last_name": "Александр", "middle_name": "Юрьевич", - "group_number": "АБВ-123" + "group_number": "АБВ-123", + "tasks_type": "threads" } } \ No newline at end of file diff --git a/tasks/example/tests/functional/main.cpp b/tasks/example/tests/functional/main.cpp index ed8fc820f..35f2002e9 100644 --- a/tasks/example/tests/functional/main.cpp +++ b/tasks/example/tests/functional/main.cpp @@ -63,12 +63,12 @@ TEST_P(NesterovARunFuncTests, MatmulFromPic) { ExecuteTest(GetParam()); } const std::array kTestParam = {std::make_tuple(3, "3"), std::make_tuple(5, "5"), std::make_tuple(7, "7")}; -INIT_TASK_GENERATOR(InType, kTestParam) +INIT_TASK_GENERATOR(InType, kTestParam, PPC_SETTINGS_example) const auto kTestTasksList = - std::tuple_cat(TaskListGenerator(), TaskListGenerator(), - TaskListGenerator(), TaskListGenerator(), - TaskListGenerator(), TaskListGenerator()); + std::tuple_cat(ADD_FUNC_TASK_PROCESS(NesterovATestTaskALL), ADD_FUNC_TASK_PROCESS(NesterovATestTaskMPI), + ADD_FUNC_TASK_THREADS(NesterovATestTaskOMP), ADD_FUNC_TASK_THREADS(NesterovATestTaskSEQ), + ADD_FUNC_TASK_THREADS(NesterovATestTaskSTL), ADD_FUNC_TASK_THREADS(NesterovATestTaskTBB)); INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTests, ppc::util::ExpandToValues(kTestTasksList), NesterovARunFuncTests::PrintFuncTestName); diff --git a/tasks/example/tests/performance/main.cpp b/tasks/example/tests/performance/main.cpp index 254fe0119..72570e0bd 100644 --- a/tasks/example/tests/performance/main.cpp +++ b/tasks/example/tests/performance/main.cpp @@ -29,13 +29,16 @@ class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { InType GetTestInputData() final { return input_data_; } }; +const auto all_perf_tasks = std::tuple_cat(ADD_PERF_TASK_PROCESS(NesterovATestTaskALL, InType, PPC_SETTINGS_example), + ADD_PERF_TASK_PROCESS(NesterovATestTaskMPI, InType, PPC_SETTINGS_example), + ADD_PERF_TASK_THREADS(NesterovATestTaskOMP, InType, PPC_SETTINGS_example), + ADD_PERF_TASK_THREADS(NesterovATestTaskSEQ, InType, PPC_SETTINGS_example), + ADD_PERF_TASK_THREADS(NesterovATestTaskSTL, InType, PPC_SETTINGS_example), + ADD_PERF_TASK_THREADS(NesterovATestTaskTBB, InType, PPC_SETTINGS_example)); + TEST_P(ExampleRunPerfTest, RunPerfModes) { ExecuteTest(GetParam()); } -INSTANTIATE_TEST_SUITE_P_NOLINT( - RunModeTests, ExampleRunPerfTest, - ::testing::Values(ADD_PERF_TASK(NesterovATestTaskALL, InType), ADD_PERF_TASK(NesterovATestTaskMPI, InType), - ADD_PERF_TASK(NesterovATestTaskOMP, InType), ADD_PERF_TASK(NesterovATestTaskSEQ, InType), - ADD_PERF_TASK(NesterovATestTaskSTL, InType), ADD_PERF_TASK(NesterovATestTaskTBB, InType)), - ExampleRunPerfTest::CustomPerfTestName); +INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, ExampleRunPerfTest, ppc::util::TupleToGTestValues(all_perf_tasks), + ExampleRunPerfTest::CustomPerfTestName); } // namespace nesterov_a_test_task From ba8011a4a3430a8c867a291c6e4ae77d3e5df750 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Fri, 6 Jun 2025 23:46:48 +0200 Subject: [PATCH 067/141] Add libenvpp integration and improve thread/environment handling Integrated libenvpp library to enhance environment variable parsing and validation. Refactored thread control logic with libenvpp and adjusted related tests and CMake configurations to support the new library. Removed outdated util test files and added necessary dependencies in build scripts. --- .gitmodules | 3 + 3rdparty/libenvpp | 1 + CMakeLists.txt | 1 + cmake/libenvpp.cmake | 14 ++++ modules/core/CMakeLists.txt | 7 ++ modules/core/util/func_tests/util_tests.cpp | 36 ---------- modules/core/util/include/util.hpp | 5 ++ modules/core/util/src/util.cpp | 76 ++++++++++++++++----- scripts/run_tests.py | 6 +- tasks/CMakeLists.txt | 19 +++++- tasks/common/runners/functional.cpp | 8 ++- tasks/common/tests/util.cpp | 22 ++++++ 12 files changed, 140 insertions(+), 58 deletions(-) create mode 160000 3rdparty/libenvpp create mode 100644 cmake/libenvpp.cmake delete mode 100644 modules/core/util/func_tests/util_tests.cpp create mode 100644 tasks/common/tests/util.cpp diff --git a/.gitmodules b/.gitmodules index f17182474..6ef00628f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "3rdparty/json"] path = 3rdparty/json url = https://github.com/nlohmann/json +[submodule "3rdparty/libenvpp"] + path = 3rdparty/libenvpp + url = https://github.com/ph3at/libenvpp diff --git a/3rdparty/libenvpp b/3rdparty/libenvpp new file mode 160000 index 000000000..86db27f6d --- /dev/null +++ b/3rdparty/libenvpp @@ -0,0 +1 @@ +Subproject commit 86db27f6df18a6e6a6ed143833bca0fd20977bf4 diff --git a/CMakeLists.txt b/CMakeLists.txt index ea4f23bba..82bc88efe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ include(cmake/configure.cmake) include(cmake/modes.cmake) include(cmake/sanitizers.cmake) include(cmake/json.cmake) +include(cmake/libenvpp.cmake) ################# Parallel programming technologies ################# diff --git a/cmake/libenvpp.cmake b/cmake/libenvpp.cmake new file mode 100644 index 000000000..5338bd09f --- /dev/null +++ b/cmake/libenvpp.cmake @@ -0,0 +1,14 @@ +include_directories(${CMAKE_SOURCE_DIR}/3rdparty/libenvpp/include) +include_directories(${CMAKE_SOURCE_DIR}/3rdparty/libenvpp/external/fmt/include) + +include(ExternalProject) +ExternalProject_Add(ppc_libenvpp + SOURCE_DIR "${CMAKE_SOURCE_DIR}/3rdparty/libenvpp" + PREFIX "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp" + BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" + INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/install" + CONFIGURE_COMMAND "${CMAKE_COMMAND}" -S "${CMAKE_SOURCE_DIR}/3rdparty/libenvpp/" -B "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build/" + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -G${CMAKE_GENERATOR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} + BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --config ${CMAKE_BUILD_TYPE} --parallel + INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/install") diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index 63659971e..bcc3c4ef5 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -23,10 +23,17 @@ project(${exec_func_lib}) add_library(${exec_func_lib} STATIC ${LIB_SOURCE_FILES}) set_target_properties(${exec_func_lib} PROPERTIES LINKER_LANGUAGE CXX) +add_dependencies(${exec_func_lib} ppc_libenvpp) +target_link_directories(${exec_func_lib} PUBLIC "${CMAKE_BINARY_DIR}/ppc_libenvpp/install/lib") +target_link_directories(${exec_func_lib} PUBLIC "${CMAKE_BINARY_DIR}/ppc_libenvpp/build") +target_link_libraries(${exec_func_lib} PUBLIC fmt envpp) + add_executable(${exec_func_tests} ${FUNC_TESTS_SOURCE_FILES}) + add_dependencies(${exec_func_tests} ppc_googletest) target_link_directories(${exec_func_tests} PUBLIC ${CMAKE_BINARY_DIR}/ppc_googletest/install/lib) target_link_libraries(${exec_func_tests} PUBLIC gtest gtest_main) + if( MPI_COMPILE_FLAGS ) set_target_properties(${exec_func_tests} PROPERTIES COMPILE_FLAGS "${MPI_COMPILE_FLAGS}") endif( MPI_COMPILE_FLAGS ) diff --git a/modules/core/util/func_tests/util_tests.cpp b/modules/core/util/func_tests/util_tests.cpp deleted file mode 100644 index b55e7c2f2..000000000 --- a/modules/core/util/func_tests/util_tests.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include - -#include -#include -#include - -#include "core/util/include/util.hpp" - -TEST(util_tests, check_unset_env) { -#ifndef _WIN32 - int save_var = ppc::util::GetNumThreads(); - - unsetenv("PPC_NUM_THREADS"); // NOLINT(concurrency-mt-unsafe) - - EXPECT_EQ(ppc::util::GetNumThreads(), 1); - - setenv("PPC_NUM_THREADS", std::to_string(save_var).c_str(), 1); // NOLINT(concurrency-mt-unsafe) -#else - GTEST_SKIP(); -#endif -} - -TEST(util_tests, check_set_env) { -#ifndef _WIN32 - int save_var = ppc::util::GetNumThreads(); - - const int num_threads = static_cast(std::thread::hardware_concurrency()); - setenv("PPC_NUM_THREADS", std::to_string(num_threads).c_str(), 1); // NOLINT(concurrency-mt-unsafe) - - EXPECT_EQ(ppc::util::GetNumThreads(), num_threads); - - setenv("PPC_NUM_THREADS", std::to_string(save_var).c_str(), 1); // NOLINT(concurrency-mt-unsafe) -#else - GTEST_SKIP(); -#endif -} diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index d40e9a2d5..8b18b21b9 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -61,4 +61,9 @@ static_assert(false, "Unsupported compiler"); return kFunc.substr(start, end - start); } +#include +#include + +bool IsUnderMpirun(); + } // namespace ppc::util diff --git a/modules/core/util/src/util.cpp b/modules/core/util/src/util.cpp index c5d94be91..d5d129752 100644 --- a/modules/core/util/src/util.cpp +++ b/modules/core/util/src/util.cpp @@ -1,33 +1,77 @@ #include "core/util/include/util.hpp" #include -#ifdef _WIN32 #include #include #include #include -#endif - +#include +#include #include +#include #include +#include +#include + +//namespace { +// +//struct MpiEnvVar { +// std::string_view name; +// const char* description; +//}; +// +//} // namespace -std::string ppc::util::GetAbsolutePath(const std::string &relative_path) { +std::string ppc::util::GetAbsolutePath(const std::string& relative_path) { const std::filesystem::path path = std::string(PPC_PATH_TO_PROJECT) + "/tasks/" + relative_path; return path.string(); } int ppc::util::GetNumThreads() { -#ifdef _WIN32 - size_t len; - char omp_env[100]; - errno_t err = getenv_s(&len, omp_env, sizeof(omp_env), "PPC_NUM_THREADS"); - if (err != 0 || len == 0) { - omp_env[0] = '\0'; + env::prefix pre("PPC"); + + const auto num_threads_id = pre.register_variable("NUM_THREADS"); + + auto validated = std::move(pre).parse_and_validate(); + + if (!validated.ok()) { + std::cerr << validated.warning_message() << "\n"; +// throw validated.error_message(); } - int num_threads = std::atoi(omp_env); -#else - const char *omp_env = std::getenv("PPC_NUM_THREADS"); // NOLINT(concurrency-mt-unsafe) - int num_threads = (omp_env != nullptr) ? std::atoi(omp_env) : 1; -#endif - return num_threads; + + const auto num_threads = validated.get(num_threads_id); + return num_threads ? static_cast(*num_threads) : 1; } + +//const std::array kMpiEnvVars = {{{.name = "OMPI_COMM_WORLD_SIZE", .description = "OpenMPI"}, +// {.name = "OMPI_UNIVERSE_SIZE", .description = "OpenMPI"}, +// {.name = "PMI_SIZE", .description = "MPICH/Intel MPI"}, +// {.name = "PMI_RANK", .description = "MPICH/Intel MPI"}, +// {.name = "PMI_FD", .description = "MPICH/Intel MPI"}, +// {.name = "HYDRA_CONTROL_FD", .description = "Hydra"}, +// {.name = "PMIX_RANK", .description = "Cray PMI/PMIx"}, +// {.name = "PMIX_NAMESPACE", .description = "Cray PMI/PMIx"}, +// {.name = "SLURM_PROCID", .description = "SLURM"}, +// {.name = "MPI_LOCALRANKID", .description = "IBM Spectrum MPI"}, +// {.name = "MSMPI_RANK", .description = "Microsoft MPI"}, +// {.name = "MSMPI_NODE_ID", .description = "Microsoft MPI"}, +// {.name = "MSMPI_LOCALRANK", .description = "Microsoft MPI"}}}; + +//bool ppc::util::IsUnderMpirun() { +// auto pre = env::prefix(""); +// const auto parsed_and_validated_pre = pre.parse_and_validate(); +// return std::ranges::any_of(kMpiEnvVars, [&](const auto& env_var) { +// const auto mpi_env_id = pre.register_variable(env_var.name); +// +// if (!parsed_and_validated_pre.ok()) { +// std::cerr << parsed_and_validated_pre.warning_message(); +// throw parsed_and_validated_pre.error_message(); +// } +// +// if (parsed_and_validated_pre.get(mpi_env_id)) { +// return true; +// } else { +// return false; +// } +// }); +//} diff --git a/scripts/run_tests.py b/scripts/run_tests.py index 6220ae53a..69be41f9a 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -87,6 +87,8 @@ def run_threads(self): self.__run_exec(f"{self.work_dir / 'ppc_func_tests'} {self.__get_gtest_settings(3, '_' + task_type + '_')}") def run_core(self): + self.__run_exec(f"{self.work_dir / 'ppc_func_tests'} {self.__get_gtest_settings(1, '_common')}") + if platform.system() == "Linux" and not self.__ppc_env.get("PPC_ASAN_RUN"): self.__run_exec(f"{self.valgrind_cmd} {self.work_dir / 'core_func_tests'} " f"{self.__get_gtest_settings(1, '*')} --gtest_filter=*:-*_death_test") @@ -123,8 +125,8 @@ def run_performance_list(self): ppc_runner = PPCRunner() ppc_runner.setup_env(os.environ.copy()) - # if args_dict["running_type"] in ["threads", "processes"]: - # ppc_runner.run_core() + if args_dict["running_type"] in ["threads", "processes"]: + ppc_runner.run_core() if args_dict["running_type"] == "threads": ppc_runner.run_threads() diff --git a/tasks/CMakeLists.txt b/tasks/CMakeLists.txt index 7b723b847..672876b5e 100644 --- a/tasks/CMakeLists.txt +++ b/tasks/CMakeLists.txt @@ -7,7 +7,8 @@ set(exec_perf_tests "ppc_perf_tests") # Init func tests executable files set(list_of_exec_tests "") if (USE_FUNC_TESTS) - add_executable(${exec_func_tests} "${CMAKE_CURRENT_SOURCE_DIR}/common/runners/functional.cpp") + add_executable(${exec_func_tests} "${CMAKE_CURRENT_SOURCE_DIR}/common/runners/functional.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/common/tests/util.cpp") list(APPEND list_of_exec_tests ${exec_func_tests}) endif (USE_FUNC_TESTS) @@ -38,7 +39,10 @@ add_library(stb_image INTERFACE) foreach (exec_func ${list_of_exec_tests}) target_link_libraries(${exec_func} PUBLIC Threads::Threads) - target_link_libraries(${exec_func} PUBLIC ${OpenMP_libomp_LIBRARY}) + + find_package(OpenMP REQUIRED) + target_link_libraries(${exec_func} PUBLIC ${OpenMP_libomp_LIBRARY} OpenMP::OpenMP_CXX) + if( MPI_COMPILE_FLAGS ) set_target_properties(${exec_func} PROPERTIES COMPILE_FLAGS "${MPI_COMPILE_FLAGS}") endif( MPI_COMPILE_FLAGS ) @@ -51,7 +55,11 @@ foreach (exec_func ${list_of_exec_tests}) add_dependencies(${exec_func} ppc_onetbb) target_link_directories(${exec_func} PUBLIC ${CMAKE_BINARY_DIR}/ppc_onetbb/install/lib) if(NOT MSVC) - target_link_libraries(${exec_func} PUBLIC tbb) + if(CMAKE_BUILD_TYPE STREQUAL "Debug") + target_link_libraries(${exec_func} PUBLIC tbb_debug) + else() + target_link_libraries(${exec_func} PUBLIC tbb) + endif() endif() target_link_directories(stb_image INTERFACE ${CMAKE_SOURCE_DIR}/3rdparty/stb) @@ -64,6 +72,11 @@ foreach (exec_func ${list_of_exec_tests}) add_dependencies(${exec_func} ppc_json) target_link_directories(${exec_func} INTERFACE "${CMAKE_BINARY_DIR}/ppc_json/install/include") + add_dependencies(${exec_func} ppc_libenvpp) + target_link_directories(${exec_func} PUBLIC "${CMAKE_BINARY_DIR}/ppc_libenvpp/install/lib") + target_link_directories(${exec_func} PUBLIC "${CMAKE_BINARY_DIR}/ppc_libenvpp/build") + target_link_libraries(${exec_func} PUBLIC fmt envpp) + enable_testing() add_test(NAME ${exec_func} COMMAND ${exec_func}) diff --git a/tasks/common/runners/functional.cpp b/tasks/common/runners/functional.cpp index 8a86afdf6..fc681106c 100644 --- a/tasks/common/runners/functional.cpp +++ b/tasks/common/runners/functional.cpp @@ -77,7 +77,13 @@ int main(int argc, char** argv) { // Limit the number of threads in TBB tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetNumThreads()); // Limit the number of threads in OMP - omp_set_num_threads(ppc::util::GetNumThreads()); + omp_set_num_threads(3); + + +#pragma omp parallel + { + std::cout << "Thread: " << omp_get_thread_num() << "\n"; + } ::testing::InitGoogleTest(&argc, argv); diff --git a/tasks/common/tests/util.cpp b/tasks/common/tests/util.cpp new file mode 100644 index 000000000..6b63dd612 --- /dev/null +++ b/tasks/common/tests/util.cpp @@ -0,0 +1,22 @@ +#include + +#include +#include +#include +#include "omp.h" + +#include "core/task/func_tests/test_task.hpp" +#include "core/util/include/util.hpp" + +TEST(ppc_func_tests_common, threads_control_check_openmp) { + int ppc_num_threads = ppc::util::GetNumThreads(); + + int omp_num_threads = -1; +#pragma omp parallel + { + omp_num_threads = omp_get_num_threads(); + }; + + // Check Result + ASSERT_EQ(ppc_num_threads, omp_num_threads); +} \ No newline at end of file From 0da828b5f8eb099189ccf7b9aae8bb217e65abf1 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sat, 7 Jun 2025 01:56:28 +0200 Subject: [PATCH 068/141] Remove PPC_ASAN_RUN logic and simplify build/test configurations Eliminated `PPC_ASAN_RUN` handling across the codebase and adjusted macros, CMake configurations, and test files accordingly. Simplified thread environment handling, replaced `std::println` with `fmt` library calls, and refactored redundant code in utils and runners. --- cmake/configure.cmake | 4 -- cmake/json.cmake | 2 +- cmake/libenvpp.cmake | 6 +- modules/core/task/include/task.hpp | 4 +- modules/core/util/include/func_test_util.hpp | 11 ++- modules/core/util/include/perf_test_util.hpp | 6 +- modules/core/util/include/util.hpp | 6 +- modules/core/util/src/util.cpp | 74 ++++---------------- tasks/CMakeLists.txt | 4 -- tasks/common/runners/functional.cpp | 48 ++++++------- tasks/common/runners/performance.cpp | 16 +---- tasks/common/tests/util.cpp | 13 ++-- tasks/example/CMakeLists.txt | 5 +- tasks/example/all/src/ops_all.cpp | 5 +- tasks/example/omp/src/ops_omp.cpp | 5 +- tasks/example/tests/functional/main.cpp | 4 +- tasks/example/tests/performance/main.cpp | 16 ++--- 17 files changed, 79 insertions(+), 150 deletions(-) diff --git a/cmake/configure.cmake b/cmake/configure.cmake index 3eb48d370..95e55c46d 100644 --- a/cmake/configure.cmake +++ b/cmake/configure.cmake @@ -6,10 +6,6 @@ if (APPLE) set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG TRUE) endif(APPLE) -if(DEFINED ENV{PPC_ASAN_RUN} AND "$ENV{PPC_ASAN_RUN}" STREQUAL "1") - add_compile_definitions(USE_ASAN) -endif() - if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif(NOT CMAKE_BUILD_TYPE) diff --git a/cmake/json.cmake b/cmake/json.cmake index 446699658..3fd9b0d42 100644 --- a/cmake/json.cmake +++ b/cmake/json.cmake @@ -6,7 +6,7 @@ ExternalProject_Add(ppc_json BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/build" INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/install" CONFIGURE_COMMAND "${CMAKE_COMMAND}" -S "${CMAKE_SOURCE_DIR}/3rdparty/json/" -B "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/build/" - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -G${CMAKE_GENERATOR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -G${CMAKE_GENERATOR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/build" --config ${CMAKE_BUILD_TYPE} --parallel INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/install") diff --git a/cmake/libenvpp.cmake b/cmake/libenvpp.cmake index 5338bd09f..61565c312 100644 --- a/cmake/libenvpp.cmake +++ b/cmake/libenvpp.cmake @@ -1,5 +1,5 @@ include_directories(${CMAKE_SOURCE_DIR}/3rdparty/libenvpp/include) -include_directories(${CMAKE_SOURCE_DIR}/3rdparty/libenvpp/external/fmt/include) +include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/3rdparty/libenvpp/external/fmt/include) include(ExternalProject) ExternalProject_Add(ppc_libenvpp @@ -8,7 +8,7 @@ ExternalProject_Add(ppc_libenvpp BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/install" CONFIGURE_COMMAND "${CMAKE_COMMAND}" -S "${CMAKE_SOURCE_DIR}/3rdparty/libenvpp/" -B "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build/" - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -G${CMAKE_GENERATOR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -G${CMAKE_GENERATOR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} -DCMAKE_CXX_FLAGS=-Wno-error=switch-enum BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --config ${CMAKE_BUILD_TYPE} --parallel INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/install") diff --git a/modules/core/task/include/task.hpp b/modules/core/task/include/task.hpp index 3ec22fcac..87caed22b 100644 --- a/modules/core/task/include/task.hpp +++ b/modules/core/task/include/task.hpp @@ -108,10 +108,10 @@ class Task { void SetTypeOfTask(TypeOfTask type_of_task) { type_of_task_ = type_of_task; } // get a dynamic type of task - TypeOfTask GetDynamicTypeOfTask() { return type_of_task_; } + [[nodiscard]] TypeOfTask GetDynamicTypeOfTask() const { return type_of_task_; } // get a dynamic type of task - StatusOfTask GetStatusOfTask() { return status_of_task_; } + [[nodiscard]] StatusOfTask GetStatusOfTask() const { return status_of_task_; } // get a static type of task static constexpr TypeOfTask GetStaticTypeOfTask() { return TypeOfTask::kUnknown; } diff --git a/modules/core/util/include/func_test_util.hpp b/modules/core/util/include/func_test_util.hpp index 3870d4458..4863995c1 100644 --- a/modules/core/util/include/func_test_util.hpp +++ b/modules/core/util/include/func_test_util.hpp @@ -51,6 +51,15 @@ class BaseRunFuncTests : public ::testing::TestWithParam(test_param).find(substring) != std::string::npos; + }; + + if (!ppc::util::IsUnderMpirun() && (which_task("_all") || which_task("_mpi"))) { + std::cerr << "kALL and kMPI tasks are not under mpirun" << '\n'; + GTEST_SKIP(); + } + task_ = std::get(test_param)(GetTestInputData()); ASSERT_TRUE(task_->Validation()); ASSERT_TRUE(task_->PreProcessing()); @@ -91,7 +100,7 @@ auto ExpandToValues(const Tuple& t) { #define ADD_FUNC_TASK_THREADS(TASK) TaskListGenerator() -#ifndef PPC_ASAN_RUN +#if 1 #define ADD_FUNC_TASK_PROCESS(TASK) TaskListGenerator() #else #define ADD_FUNC_TASK_PROCESS(TASK) std::tuple<>() diff --git a/modules/core/util/include/perf_test_util.hpp b/modules/core/util/include/perf_test_util.hpp index 87424e520..216acd271 100644 --- a/modules/core/util/include/perf_test_util.hpp +++ b/modules/core/util/include/perf_test_util.hpp @@ -79,15 +79,11 @@ class BaseRunPerfTests : public ::testing::TestWithParamGetOutput(); ASSERT_TRUE(CheckTestOutputData(output_data)); @@ -118,7 +114,7 @@ auto TupleToGTestValues(Tuple&& tup) { return TupleToGTestValuesImpl(std::forward(tup), std::make_index_sequence{}); } -#ifndef PPC_ASAN_RUN +#if 1 #define ADD_PERF_TASK_PROCESS(TaskType, InputTypeParam, SettingsPath) \ std::tuple(std::make_tuple(ppc::core::TaskGetter, \ std::string(ppc::util::GetNamespace()) + "_" + \ diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index 8b18b21b9..96a7bd6e0 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -1,4 +1,7 @@ #pragma once +#include +#include + #include #include #include @@ -61,9 +64,6 @@ static_assert(false, "Unsupported compiler"); return kFunc.substr(start, end - start); } -#include -#include - bool IsUnderMpirun(); } // namespace ppc::util diff --git a/modules/core/util/src/util.cpp b/modules/core/util/src/util.cpp index d5d129752..d715aadf0 100644 --- a/modules/core/util/src/util.cpp +++ b/modules/core/util/src/util.cpp @@ -1,26 +1,10 @@ #include "core/util/include/util.hpp" -#include -#include -#include -#include -#include #include #include #include -#include -#include -#include #include - -//namespace { -// -//struct MpiEnvVar { -// std::string_view name; -// const char* description; -//}; -// -//} // namespace +#include std::string ppc::util::GetAbsolutePath(const std::string& relative_path) { const std::filesystem::path path = std::string(PPC_PATH_TO_PROJECT) + "/tasks/" + relative_path; @@ -28,50 +12,20 @@ std::string ppc::util::GetAbsolutePath(const std::string& relative_path) { } int ppc::util::GetNumThreads() { - env::prefix pre("PPC"); - - const auto num_threads_id = pre.register_variable("NUM_THREADS"); - - auto validated = std::move(pre).parse_and_validate(); - - if (!validated.ok()) { - std::cerr << validated.warning_message() << "\n"; -// throw validated.error_message(); + const auto num_threads = env::get("PPC_NUM_THREADS"); + if (num_threads.has_value()) { + return num_threads.value(); } - - const auto num_threads = validated.get(num_threads_id); - return num_threads ? static_cast(*num_threads) : 1; + return 1; } -//const std::array kMpiEnvVars = {{{.name = "OMPI_COMM_WORLD_SIZE", .description = "OpenMPI"}, -// {.name = "OMPI_UNIVERSE_SIZE", .description = "OpenMPI"}, -// {.name = "PMI_SIZE", .description = "MPICH/Intel MPI"}, -// {.name = "PMI_RANK", .description = "MPICH/Intel MPI"}, -// {.name = "PMI_FD", .description = "MPICH/Intel MPI"}, -// {.name = "HYDRA_CONTROL_FD", .description = "Hydra"}, -// {.name = "PMIX_RANK", .description = "Cray PMI/PMIx"}, -// {.name = "PMIX_NAMESPACE", .description = "Cray PMI/PMIx"}, -// {.name = "SLURM_PROCID", .description = "SLURM"}, -// {.name = "MPI_LOCALRANKID", .description = "IBM Spectrum MPI"}, -// {.name = "MSMPI_RANK", .description = "Microsoft MPI"}, -// {.name = "MSMPI_NODE_ID", .description = "Microsoft MPI"}, -// {.name = "MSMPI_LOCALRANK", .description = "Microsoft MPI"}}}; +constexpr std::array kMpiEnvVars = { + "OMPI_COMM_WORLD_SIZE", "OMPI_UNIVERSE_SIZE", "PMI_SIZE", "PMI_RANK", "PMI_FD", + "HYDRA_CONTROL_FD", "PMIX_RANK", "SLURM_PROCID", "MSMPI_RANK", "MSMPI_LOCALRANK"}; -//bool ppc::util::IsUnderMpirun() { -// auto pre = env::prefix(""); -// const auto parsed_and_validated_pre = pre.parse_and_validate(); -// return std::ranges::any_of(kMpiEnvVars, [&](const auto& env_var) { -// const auto mpi_env_id = pre.register_variable(env_var.name); -// -// if (!parsed_and_validated_pre.ok()) { -// std::cerr << parsed_and_validated_pre.warning_message(); -// throw parsed_and_validated_pre.error_message(); -// } -// -// if (parsed_and_validated_pre.get(mpi_env_id)) { -// return true; -// } else { -// return false; -// } -// }); -//} +bool ppc::util::IsUnderMpirun() { + return std::ranges::any_of(kMpiEnvVars, [&](const auto& env_var) { + const auto mpi_env = env::get(env_var); + return static_cast(mpi_env.has_value()); + }); +} diff --git a/tasks/CMakeLists.txt b/tasks/CMakeLists.txt index 672876b5e..4ec741e79 100644 --- a/tasks/CMakeLists.txt +++ b/tasks/CMakeLists.txt @@ -18,10 +18,6 @@ if (USE_PERF_TESTS) list(APPEND list_of_exec_tests ${exec_perf_tests}) endif (USE_PERF_TESTS) -if((DEFINED ENV{PPC_ASAN_RUN}) AND ("$ENV{PPC_ASAN_RUN}" STREQUAL "1")) - add_compile_definitions(PPC_ASAN_RUN) -endif() - SUBDIRLIST(subdirs ${CMAKE_CURRENT_LIST_DIR}) foreach(subd ${subdirs}) if (subd STREQUAL "common") diff --git a/tasks/common/runners/functional.cpp b/tasks/common/runners/functional.cpp index fc681106c..3ee62ed31 100644 --- a/tasks/common/runners/functional.cpp +++ b/tasks/common/runners/functional.cpp @@ -1,10 +1,10 @@ +#include #include #include #include #include #include -#include #include #include @@ -27,7 +27,7 @@ class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status); if (flag != 0) { - std::println( + fmt::println( stderr, "[ PROCESS {} ] [ FAILED ] {}.{}: MPI message queue has an unread message from process {} with tag {}", rank, "test_suite_name", "test_name", status.MPI_SOURCE, status.MPI_TAG); @@ -64,42 +64,37 @@ class WorkerTestFailurePrinter : public ::testing::EmptyTestEventListener { static void PrintProcessRank() { int rank = -1; MPI_Comm_rank(MPI_COMM_WORLD, &rank); - std::print(" [ PROCESS {} ] ", rank); + fmt::print(" [ PROCESS {} ] ", rank); } std::shared_ptr<::testing::TestEventListener> base_; }; int main(int argc, char** argv) { -#ifndef PPC_ASAN_RUN - MPI_Init(&argc, &argv); + if (ppc::util::IsUnderMpirun()) { + MPI_Init(&argc, &argv); - // Limit the number of threads in TBB - tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetNumThreads()); - // Limit the number of threads in OMP - omp_set_num_threads(3); + // Limit the number of threads in TBB + tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetNumThreads()); + // Limit the number of threads in OMP + omp_set_num_threads(ppc::util::GetNumThreads()); + ::testing::InitGoogleTest(&argc, argv); -#pragma omp parallel - { - std::cout << "Thread: " << omp_get_thread_num() << "\n"; - } - - ::testing::InitGoogleTest(&argc, argv); + auto& listeners = ::testing::UnitTest::GetInstance()->listeners(); + int rank = -1; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + if (rank != 0 && (argc < 2 || argv[1] != std::string("--print-workers"))) { + auto* listener = listeners.Release(listeners.default_result_printer()); + listeners.Append(new WorkerTestFailurePrinter(std::shared_ptr<::testing::TestEventListener>(listener))); + } + listeners.Append(new UnreadMessagesDetector()); + auto status = RUN_ALL_TESTS(); - auto& listeners = ::testing::UnitTest::GetInstance()->listeners(); - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - if (rank != 0 && (argc < 2 || argv[1] != std::string("--print-workers"))) { - auto* listener = listeners.Release(listeners.default_result_printer()); - listeners.Append(new WorkerTestFailurePrinter(std::shared_ptr<::testing::TestEventListener>(listener))); + MPI_Finalize(); + return status; } - listeners.Append(new UnreadMessagesDetector()); - auto status = RUN_ALL_TESTS(); - MPI_Finalize(); - return status; -#else // Limit the number of threads in TBB tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetNumThreads()); // Limit the number of threads in OMP @@ -107,5 +102,4 @@ int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); -#endif } diff --git a/tasks/common/runners/performance.cpp b/tasks/common/runners/performance.cpp index 83b2afc87..79b56e290 100644 --- a/tasks/common/runners/performance.cpp +++ b/tasks/common/runners/performance.cpp @@ -1,10 +1,10 @@ +#include #include #include #include #include #include -#include #include #include @@ -27,7 +27,7 @@ class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status); if (flag != 0) { - std::println(stderr, + fmt::println(stderr, "[ PROCESS {} ] [ FAILED ] MPI message queue has an unread message from process {} with tag {}", rank, status.MPI_SOURCE, status.MPI_TAG); @@ -64,14 +64,13 @@ class WorkerTestFailurePrinter : public ::testing::EmptyTestEventListener { static void PrintProcessRank() { int rank = -1; MPI_Comm_rank(MPI_COMM_WORLD, &rank); - std::print(" [ PROCESS {} ] ", rank); + fmt::print(" [ PROCESS {} ] ", rank); } std::shared_ptr<::testing::TestEventListener> base_; }; int main(int argc, char** argv) { -#ifndef PPC_ASAN_RUN MPI_Init(&argc, &argv); // Limit the number of threads in TBB @@ -93,13 +92,4 @@ int main(int argc, char** argv) { MPI_Finalize(); return status; -#else - // Limit the number of threads in TBB - tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetNumThreads()); - // Limit the number of threads in OMP - omp_set_num_threads(ppc::util::GetNumThreads()); - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -#endif } diff --git a/tasks/common/tests/util.cpp b/tasks/common/tests/util.cpp index 6b63dd612..8d714a48e 100644 --- a/tasks/common/tests/util.cpp +++ b/tasks/common/tests/util.cpp @@ -1,22 +1,21 @@ +#include "core/util/include/util.hpp" + #include #include #include #include -#include "omp.h" #include "core/task/func_tests/test_task.hpp" -#include "core/util/include/util.hpp" +#include "omp.h" TEST(ppc_func_tests_common, threads_control_check_openmp) { int ppc_num_threads = ppc::util::GetNumThreads(); int omp_num_threads = -1; -#pragma omp parallel - { - omp_num_threads = omp_get_num_threads(); - }; +#pragma omp parallel default(none) shared(omp_num_threads) + omp_num_threads = omp_get_num_threads(); // Check Result ASSERT_EQ(ppc_num_threads, omp_num_threads); -} \ No newline at end of file +} diff --git a/tasks/example/CMakeLists.txt b/tasks/example/CMakeLists.txt index 4674353d1..2c6bfd2ac 100644 --- a/tasks/example/CMakeLists.txt +++ b/tasks/example/CMakeLists.txt @@ -24,10 +24,7 @@ endif (USE_PERF_TESTS) get_filename_component(TASK_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) message(STATUS "-- ${TASK_NAME}") -set(technologies "omp" "seq" "stl" "tbb") -if((NOT DEFINED ENV{PPC_ASAN_RUN}) OR ("$ENV{PPC_ASAN_RUN}" STREQUAL "0")) - list(APPEND technologies "all" "mpi") -endif() +set(technologies "all" "mpi" "omp" "seq" "stl" "tbb") # Create lib foreach (dir_type ${technologies}) diff --git a/tasks/example/all/src/ops_all.cpp b/tasks/example/all/src/ops_all.cpp index eb5336639..67c3a50ac 100644 --- a/tasks/example/all/src/ops_all.cpp +++ b/tasks/example/all/src/ops_all.cpp @@ -47,9 +47,8 @@ bool NesterovATestTaskALL::RunImpl() { if (rank == 0) { std::atomic counter(0); #pragma omp parallel default(none) shared(counter) - { - counter++; - } + counter++; + GetOutput() /= counter; } else { GetOutput() /= num_threads; diff --git a/tasks/example/omp/src/ops_omp.cpp b/tasks/example/omp/src/ops_omp.cpp index 3effe680c..394fe6cb1 100644 --- a/tasks/example/omp/src/ops_omp.cpp +++ b/tasks/example/omp/src/ops_omp.cpp @@ -36,9 +36,8 @@ bool NesterovATestTaskOMP::RunImpl() { std::atomic counter(0); #pragma omp parallel default(none) shared(counter) - { - counter++; - } + counter++; + GetOutput() /= counter; return GetOutput() > 0; } diff --git a/tasks/example/tests/functional/main.cpp b/tasks/example/tests/functional/main.cpp index 35f2002e9..6cc6111f1 100644 --- a/tasks/example/tests/functional/main.cpp +++ b/tasks/example/tests/functional/main.cpp @@ -21,7 +21,7 @@ namespace nesterov_a_test_task { class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests { public: - static std::string PrintTestParam(TestType test_param) { + static std::string PrintTestParam(const TestType &test_param) { return std::to_string(std::get<0>(test_param)) + "_" + std::get<1>(test_param); } @@ -54,7 +54,7 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests { - const std::vector::size_type kCount_ = 111; + const int kCount_ = 111; InType input_data_{}; void SetUp() override { input_data_ = kCount_; } @@ -29,16 +29,16 @@ class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { InType GetTestInputData() final { return input_data_; } }; -const auto all_perf_tasks = std::tuple_cat(ADD_PERF_TASK_PROCESS(NesterovATestTaskALL, InType, PPC_SETTINGS_example), - ADD_PERF_TASK_PROCESS(NesterovATestTaskMPI, InType, PPC_SETTINGS_example), - ADD_PERF_TASK_THREADS(NesterovATestTaskOMP, InType, PPC_SETTINGS_example), - ADD_PERF_TASK_THREADS(NesterovATestTaskSEQ, InType, PPC_SETTINGS_example), - ADD_PERF_TASK_THREADS(NesterovATestTaskSTL, InType, PPC_SETTINGS_example), - ADD_PERF_TASK_THREADS(NesterovATestTaskTBB, InType, PPC_SETTINGS_example)); +const auto kAllPerfTasks = std::tuple_cat(ADD_PERF_TASK_PROCESS(NesterovATestTaskALL, InType, PPC_SETTINGS_example), + ADD_PERF_TASK_PROCESS(NesterovATestTaskMPI, InType, PPC_SETTINGS_example), + ADD_PERF_TASK_THREADS(NesterovATestTaskOMP, InType, PPC_SETTINGS_example), + ADD_PERF_TASK_THREADS(NesterovATestTaskSEQ, InType, PPC_SETTINGS_example), + ADD_PERF_TASK_THREADS(NesterovATestTaskSTL, InType, PPC_SETTINGS_example), + ADD_PERF_TASK_THREADS(NesterovATestTaskTBB, InType, PPC_SETTINGS_example)); TEST_P(ExampleRunPerfTest, RunPerfModes) { ExecuteTest(GetParam()); } -INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, ExampleRunPerfTest, ppc::util::TupleToGTestValues(all_perf_tasks), +INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, ExampleRunPerfTest, ppc::util::TupleToGTestValues(kAllPerfTasks), ExampleRunPerfTest::CustomPerfTestName); } // namespace nesterov_a_test_task From 8c6e9ff18308a38df5a6c55debb43f1a8909f784 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sat, 7 Jun 2025 02:14:28 +0200 Subject: [PATCH 069/141] Expand Valgrind suppression file for additional leaks Added new leak suppressions to `valgrind.supp`, covering libraries like `libucs` and `libomp`, as well as `dlopen`-related functions. Improves memory check output by reducing false positives. --- valgrind.supp | 82 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 73 insertions(+), 9 deletions(-) diff --git a/valgrind.supp b/valgrind.supp index 28656437a..768e41db8 100644 --- a/valgrind.supp +++ b/valgrind.supp @@ -1,15 +1,79 @@ { - suppress mpi init internal leaks + libucs_strdup_leak Memcheck:Leak - ... - fun:MPI_Init - ... + match-leak-kinds: reachable + fun:malloc + fun:strdup + fun:ucs_strdup + fun:ucs_config_sscanf_string } { - suppress mpi finalize internal leaks + libucs_array_leak Memcheck:Leak - ... - fun:MPI_Finalize - ... -} \ No newline at end of file + match-leak-kinds: reachable + fun:calloc + fun:ucs_calloc + fun:ucs_config_sscanf_array +} + +{ + libomp_set_num_threads_leak1 + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + obj:/usr/lib/llvm-20/lib/libomp.so.5 + fun:omp_set_num_threads +} + +{ + libomp_set_num_threads_leak2 + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + obj:/usr/lib/llvm-20/lib/libomp.so.5 + fun:omp_set_num_threads +} + +{ + libomp_internal_alloc1 + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + fun:___kmp_allocate + obj:/usr/lib/llvm-20/lib/libomp.so.5 +} + +{ + dlopen_strdup_leak + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + fun:strdup + fun:_dl_map_object +} + +{ + dlopen_dl_new_object + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + fun:_dl_new_object + fun:_dl_map_object_from_fd +} + +{ + dlopen_global_resize + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + fun:add_to_global_resize +} + +{ + dlopen_check_map_versions + Memcheck:Leak + match-leak-kinds: reachable + fun:calloc + fun:_dl_check_map_versions +} From 110cd96bb4b2dc32bc4cd17b68a7485d06330aeb Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sat, 7 Jun 2025 02:24:20 +0200 Subject: [PATCH 070/141] Remove Valgrind suppression file and simplify command Deleted `valgrind.supp` and updated the test script to remove its usage in the Valgrind command. Streamlined the memory check setup by eliminating the suppression file dependency. --- scripts/run_tests.py | 4 +-- valgrind.supp | 79 -------------------------------------------- 2 files changed, 1 insertion(+), 82 deletions(-) delete mode 100644 valgrind.supp diff --git a/scripts/run_tests.py b/scripts/run_tests.py index 69be41f9a..3befd48f9 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -31,9 +31,7 @@ def __init__(self): self.__ppc_env = None self.work_dir = None - suppression_file = Path(self.__get_project_path()) / "valgrind.supp" - self.valgrind_cmd = (f"valgrind --suppressions={suppression_file} " - f"--error-exitcode=1 --leak-check=full --show-leak-kinds=all") + self.valgrind_cmd = "valgrind --error-exitcode=1 --leak-check=full --show-leak-kinds=all" if platform.system() == "Windows": self.mpi_exec = "mpiexec" diff --git a/valgrind.supp b/valgrind.supp deleted file mode 100644 index 768e41db8..000000000 --- a/valgrind.supp +++ /dev/null @@ -1,79 +0,0 @@ -{ - libucs_strdup_leak - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc - fun:strdup - fun:ucs_strdup - fun:ucs_config_sscanf_string -} - -{ - libucs_array_leak - Memcheck:Leak - match-leak-kinds: reachable - fun:calloc - fun:ucs_calloc - fun:ucs_config_sscanf_array -} - -{ - libomp_set_num_threads_leak1 - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc - obj:/usr/lib/llvm-20/lib/libomp.so.5 - fun:omp_set_num_threads -} - -{ - libomp_set_num_threads_leak2 - Memcheck:Leak - match-leak-kinds: possible - fun:malloc - obj:/usr/lib/llvm-20/lib/libomp.so.5 - fun:omp_set_num_threads -} - -{ - libomp_internal_alloc1 - Memcheck:Leak - match-leak-kinds: possible - fun:malloc - fun:___kmp_allocate - obj:/usr/lib/llvm-20/lib/libomp.so.5 -} - -{ - dlopen_strdup_leak - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc - fun:strdup - fun:_dl_map_object -} - -{ - dlopen_dl_new_object - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc - fun:_dl_new_object - fun:_dl_map_object_from_fd -} - -{ - dlopen_global_resize - Memcheck:Leak - match-leak-kinds: reachable - fun:malloc - fun:add_to_global_resize -} - -{ - dlopen_check_map_versions - Memcheck:Leak - match-leak-kinds: reachable - fun:calloc - fun:_dl_check_map_versions -} From 92d7b85235daaeb0d5610a5443b051dab7cadc93 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 00:26:51 +0200 Subject: [PATCH 071/141] Refactor OpenMP thread handling and remove redundant `omp_set_num_threads` calls Updated `#pragma omp parallel` statements to explicitly define `num_threads` using `ppc::util::GetNumThreads()`. Removed redundant `omp_set_num_threads` calls in runners, streamlining thread configuration across the codebase. --- tasks/common/runners/functional.cpp | 4 ---- tasks/common/runners/performance.cpp | 2 -- tasks/common/tests/util.cpp | 2 +- tasks/example/all/src/ops_all.cpp | 2 +- tasks/example/omp/src/ops_omp.cpp | 2 +- 5 files changed, 3 insertions(+), 9 deletions(-) diff --git a/tasks/common/runners/functional.cpp b/tasks/common/runners/functional.cpp index 3ee62ed31..d4052d5d3 100644 --- a/tasks/common/runners/functional.cpp +++ b/tasks/common/runners/functional.cpp @@ -76,8 +76,6 @@ int main(int argc, char** argv) { // Limit the number of threads in TBB tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetNumThreads()); - // Limit the number of threads in OMP - omp_set_num_threads(ppc::util::GetNumThreads()); ::testing::InitGoogleTest(&argc, argv); @@ -97,8 +95,6 @@ int main(int argc, char** argv) { // Limit the number of threads in TBB tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetNumThreads()); - // Limit the number of threads in OMP - omp_set_num_threads(ppc::util::GetNumThreads()); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/tasks/common/runners/performance.cpp b/tasks/common/runners/performance.cpp index 79b56e290..a32b13c25 100644 --- a/tasks/common/runners/performance.cpp +++ b/tasks/common/runners/performance.cpp @@ -75,8 +75,6 @@ int main(int argc, char** argv) { // Limit the number of threads in TBB tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetNumThreads()); - // Limit the number of threads in OMP - omp_set_num_threads(ppc::util::GetNumThreads()); ::testing::InitGoogleTest(&argc, argv); diff --git a/tasks/common/tests/util.cpp b/tasks/common/tests/util.cpp index 8d714a48e..57122c23e 100644 --- a/tasks/common/tests/util.cpp +++ b/tasks/common/tests/util.cpp @@ -13,7 +13,7 @@ TEST(ppc_func_tests_common, threads_control_check_openmp) { int ppc_num_threads = ppc::util::GetNumThreads(); int omp_num_threads = -1; -#pragma omp parallel default(none) shared(omp_num_threads) +#pragma omp parallel default(none) shared(omp_num_threads) num_threads(ppc::util::GetNumThreads()) omp_num_threads = omp_get_num_threads(); // Check Result diff --git a/tasks/example/all/src/ops_all.cpp b/tasks/example/all/src/ops_all.cpp index 67c3a50ac..bb2e6f557 100644 --- a/tasks/example/all/src/ops_all.cpp +++ b/tasks/example/all/src/ops_all.cpp @@ -46,7 +46,7 @@ bool NesterovATestTaskALL::RunImpl() { MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { std::atomic counter(0); -#pragma omp parallel default(none) shared(counter) +#pragma omp parallel default(none) shared(counter) num_threads(ppc::util::GetNumThreads()) counter++; GetOutput() /= counter; diff --git a/tasks/example/omp/src/ops_omp.cpp b/tasks/example/omp/src/ops_omp.cpp index 394fe6cb1..3d9515b99 100644 --- a/tasks/example/omp/src/ops_omp.cpp +++ b/tasks/example/omp/src/ops_omp.cpp @@ -35,7 +35,7 @@ bool NesterovATestTaskOMP::RunImpl() { GetOutput() *= num_threads; std::atomic counter(0); -#pragma omp parallel default(none) shared(counter) +#pragma omp parallel default(none) shared(counter) num_threads(ppc::util::GetNumThreads()) counter++; GetOutput() /= counter; From 647bf7e842da5af84d3b97b0a773a568bc0cf59d Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 00:31:17 +0200 Subject: [PATCH 072/141] Remove redundant CMake flag `-DCMAKE_CXX_FLAGS=-Wno-error=switch-enum` .adjustments made to simplify libenvpp configuration in CMake. --- cmake/libenvpp.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/libenvpp.cmake b/cmake/libenvpp.cmake index 61565c312..8394879d5 100644 --- a/cmake/libenvpp.cmake +++ b/cmake/libenvpp.cmake @@ -9,6 +9,6 @@ ExternalProject_Add(ppc_libenvpp INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/install" CONFIGURE_COMMAND "${CMAKE_COMMAND}" -S "${CMAKE_SOURCE_DIR}/3rdparty/libenvpp/" -B "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build/" -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -G${CMAKE_GENERATOR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} -DCMAKE_CXX_FLAGS=-Wno-error=switch-enum + -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --config ${CMAKE_BUILD_TYPE} --parallel INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/install") From 76a13a409b08a4df4429e451665a146aab6216bb Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 02:06:37 +0200 Subject: [PATCH 073/141] Refactor example tasks to `example_threads` and streamline task/test macros Reorganized the directory structure by renaming `example` tasks to `example_threads`. Updated include paths, CMakeLists, and JSON settings accordingly. Simplified task and test macro structure by consolidating redundant definitions and improving generator logic. --- modules/core/util/include/func_test_util.hpp | 8 ++-- modules/core/util/include/perf_test_util.hpp | 26 +++++----- tasks/example/tests/performance/main.cpp | 44 ----------------- .../CMakeLists.txt | 0 .../all/include/ops_all.hpp | 2 +- .../all/src/ops_all.cpp | 2 +- .../common/include/common.hpp | 0 .../{example => example_threads}/data/pic.jpg | Bin tasks/{example => example_threads}/info.json | 0 .../mpi/include/ops_mpi.hpp | 2 +- .../mpi/src/ops_mpi.cpp | 2 +- .../omp/include/ops_omp.hpp | 2 +- .../omp/src/ops_omp.cpp | 2 +- .../seq/include/ops_seq.hpp | 2 +- .../seq/src/ops_seq.cpp | 2 +- .../settings.json | 0 .../stl/include/ops_stl.hpp | 2 +- .../stl/src/ops_stl.cpp | 2 +- .../tbb/include/ops_tbb.hpp | 2 +- .../tbb/src/ops_tbb.cpp | 2 +- .../tests/functional/main.cpp | 23 +++++---- .../tests/performance/main.cpp | 45 ++++++++++++++++++ 22 files changed, 83 insertions(+), 87 deletions(-) delete mode 100644 tasks/example/tests/performance/main.cpp rename tasks/{example => example_threads}/CMakeLists.txt (100%) rename tasks/{example => example_threads}/all/include/ops_all.hpp (89%) rename tasks/{example => example_threads}/all/src/ops_all.cpp (97%) rename tasks/{example => example_threads}/common/include/common.hpp (100%) rename tasks/{example => example_threads}/data/pic.jpg (100%) rename tasks/{example => example_threads}/info.json (100%) rename tasks/{example => example_threads}/mpi/include/ops_mpi.hpp (90%) rename tasks/{example => example_threads}/mpi/src/ops_mpi.cpp (96%) rename tasks/{example => example_threads}/omp/include/ops_omp.hpp (90%) rename tasks/{example => example_threads}/omp/src/ops_omp.cpp (95%) rename tasks/{example => example_threads}/seq/include/ops_seq.hpp (90%) rename tasks/{example => example_threads}/seq/src/ops_seq.cpp (95%) rename tasks/{example => example_threads}/settings.json (100%) rename tasks/{example => example_threads}/stl/include/ops_stl.hpp (90%) rename tasks/{example => example_threads}/stl/src/ops_stl.cpp (96%) rename tasks/{example => example_threads}/tbb/include/ops_tbb.hpp (90%) rename tasks/{example => example_threads}/tbb/src/ops_tbb.cpp (96%) rename tasks/{example => example_threads}/tests/functional/main.cpp (73%) create mode 100644 tasks/example_threads/tests/performance/main.cpp diff --git a/modules/core/util/include/func_test_util.hpp b/modules/core/util/include/func_test_util.hpp index 4863995c1..886e12040 100644 --- a/modules/core/util/include/func_test_util.hpp +++ b/modules/core/util/include/func_test_util.hpp @@ -83,7 +83,7 @@ auto ExpandToValues(const Tuple& t) { return ExpandToValuesImpl(t, std::make_index_sequence{}); } -#define INIT_TASK_GENERATOR(InTypeParam, SizesParam, SettingsPath) \ +#define INIT_FUNC_TASK_GENERATOR(InTypeParam, SizesParam, SettingsPath) \ template \ auto GenTaskTuplesImpl(std::index_sequence) { \ return std::make_tuple( \ @@ -98,12 +98,10 @@ auto ExpandToValues(const Tuple& t) { return GenTaskTuplesImpl(std::make_index_sequence{}); \ } -#define ADD_FUNC_TASK_THREADS(TASK) TaskListGenerator() - #if 1 -#define ADD_FUNC_TASK_PROCESS(TASK) TaskListGenerator() +#define ADD_FUNC_TASK(TASK) TaskListGenerator() #else -#define ADD_FUNC_TASK_PROCESS(TASK) std::tuple<>() +#define ADD_FUNC_TASK(TASK) std::tuple<>() #endif } // namespace ppc::util diff --git a/modules/core/util/include/perf_test_util.hpp b/modules/core/util/include/perf_test_util.hpp index 216acd271..67e897501 100644 --- a/modules/core/util/include/perf_test_util.hpp +++ b/modules/core/util/include/perf_test_util.hpp @@ -93,7 +93,8 @@ class BaseRunPerfTests : public ::testing::TestWithParam task_; }; -#define ADD_PERF_TASK_THREADS(TaskType, InputTypeParam, SettingsPath) \ +#if 1 +#define ADD_PERF_TASK(TaskType, InputTypeParam, SettingsPath) \ std::tuple(std::make_tuple(ppc::core::TaskGetter, \ std::string(ppc::util::GetNamespace()) + "_" + \ ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), SettingsPath), \ @@ -102,6 +103,9 @@ class BaseRunPerfTests : public ::testing::TestWithParam()) + "_" + \ ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), SettingsPath), \ ppc::core::PerfResults::TypeOfRunning::kTaskRun)) +#else +#define ADD_PERF_TASK(TaskType, InputTypeParam, SettingsPath) std::make_tuple() +#endif template auto TupleToGTestValuesImpl(Tuple&& tup, std::index_sequence) { @@ -114,18 +118,12 @@ auto TupleToGTestValues(Tuple&& tup) { return TupleToGTestValuesImpl(std::forward(tup), std::make_index_sequence{}); } -#if 1 -#define ADD_PERF_TASK_PROCESS(TaskType, InputTypeParam, SettingsPath) \ - std::tuple(std::make_tuple(ppc::core::TaskGetter, \ - std::string(ppc::util::GetNamespace()) + "_" + \ - ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), SettingsPath), \ - ppc::core::PerfResults::TypeOfRunning::kPipeline), \ - std::make_tuple(ppc::core::TaskGetter, \ - std::string(ppc::util::GetNamespace()) + "_" + \ - ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), SettingsPath), \ - ppc::core::PerfResults::TypeOfRunning::kTaskRun)) -#else -#define ADD_PERF_TASK_PROCESS(TaskType, InputTypeParam, SettingsPath) std::make_tuple() -#endif +#define INIT_PERF_TASK_GENERATOR(InType, EnvVarSettingsPath) \ + template \ + struct perf_tasks_type_list {}; \ + template \ + auto MakeTask(perf_tasks_type_list) { \ + return std::tuple_cat(ADD_PERF_TASK(Ts, InType, EnvVarSettingsPath)...); \ + } } // namespace ppc::util diff --git a/tasks/example/tests/performance/main.cpp b/tasks/example/tests/performance/main.cpp deleted file mode 100644 index 0385352ff..000000000 --- a/tasks/example/tests/performance/main.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include - -#include -#include -#include -#include - -#include "core/perf/include/perf.hpp" -#include "core/util/include/perf_test_util.hpp" -#include "core/util/include/util.hpp" -#include "example/all/include/ops_all.hpp" -#include "example/mpi/include/ops_mpi.hpp" -#include "example/omp/include/ops_omp.hpp" -#include "example/seq/include/ops_seq.hpp" -#include "example/stl/include/ops_stl.hpp" -#include "example/tbb/include/ops_tbb.hpp" - -namespace nesterov_a_test_task { - -class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { - const int kCount_ = 111; - InType input_data_{}; - - void SetUp() override { input_data_ = kCount_; } - - bool CheckTestOutputData(OutType& output_data) final { return input_data_ == output_data; } - - InType GetTestInputData() final { return input_data_; } -}; - -const auto kAllPerfTasks = std::tuple_cat(ADD_PERF_TASK_PROCESS(NesterovATestTaskALL, InType, PPC_SETTINGS_example), - ADD_PERF_TASK_PROCESS(NesterovATestTaskMPI, InType, PPC_SETTINGS_example), - ADD_PERF_TASK_THREADS(NesterovATestTaskOMP, InType, PPC_SETTINGS_example), - ADD_PERF_TASK_THREADS(NesterovATestTaskSEQ, InType, PPC_SETTINGS_example), - ADD_PERF_TASK_THREADS(NesterovATestTaskSTL, InType, PPC_SETTINGS_example), - ADD_PERF_TASK_THREADS(NesterovATestTaskTBB, InType, PPC_SETTINGS_example)); - -TEST_P(ExampleRunPerfTest, RunPerfModes) { ExecuteTest(GetParam()); } - -INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, ExampleRunPerfTest, ppc::util::TupleToGTestValues(kAllPerfTasks), - ExampleRunPerfTest::CustomPerfTestName); - -} // namespace nesterov_a_test_task diff --git a/tasks/example/CMakeLists.txt b/tasks/example_threads/CMakeLists.txt similarity index 100% rename from tasks/example/CMakeLists.txt rename to tasks/example_threads/CMakeLists.txt diff --git a/tasks/example/all/include/ops_all.hpp b/tasks/example_threads/all/include/ops_all.hpp similarity index 89% rename from tasks/example/all/include/ops_all.hpp rename to tasks/example_threads/all/include/ops_all.hpp index 6bacdcade..7012c2353 100644 --- a/tasks/example/all/include/ops_all.hpp +++ b/tasks/example_threads/all/include/ops_all.hpp @@ -2,7 +2,7 @@ #include -#include "example/common/include/common.hpp" +#include "example_threads/common/include/common.hpp" namespace nesterov_a_test_task { diff --git a/tasks/example/all/src/ops_all.cpp b/tasks/example_threads/all/src/ops_all.cpp similarity index 97% rename from tasks/example/all/src/ops_all.cpp rename to tasks/example_threads/all/src/ops_all.cpp index bb2e6f557..8e4cde071 100644 --- a/tasks/example/all/src/ops_all.cpp +++ b/tasks/example_threads/all/src/ops_all.cpp @@ -1,4 +1,4 @@ -#include "example/all/include/ops_all.hpp" +#include "example_threads/all/include/ops_all.hpp" #include diff --git a/tasks/example/common/include/common.hpp b/tasks/example_threads/common/include/common.hpp similarity index 100% rename from tasks/example/common/include/common.hpp rename to tasks/example_threads/common/include/common.hpp diff --git a/tasks/example/data/pic.jpg b/tasks/example_threads/data/pic.jpg similarity index 100% rename from tasks/example/data/pic.jpg rename to tasks/example_threads/data/pic.jpg diff --git a/tasks/example/info.json b/tasks/example_threads/info.json similarity index 100% rename from tasks/example/info.json rename to tasks/example_threads/info.json diff --git a/tasks/example/mpi/include/ops_mpi.hpp b/tasks/example_threads/mpi/include/ops_mpi.hpp similarity index 90% rename from tasks/example/mpi/include/ops_mpi.hpp rename to tasks/example_threads/mpi/include/ops_mpi.hpp index ac4053fd6..d8c37122a 100644 --- a/tasks/example/mpi/include/ops_mpi.hpp +++ b/tasks/example_threads/mpi/include/ops_mpi.hpp @@ -3,7 +3,7 @@ #include #include "core/task/include/task.hpp" -#include "example/common/include/common.hpp" +#include "example_threads/common/include/common.hpp" namespace nesterov_a_test_task { diff --git a/tasks/example/mpi/src/ops_mpi.cpp b/tasks/example_threads/mpi/src/ops_mpi.cpp similarity index 96% rename from tasks/example/mpi/src/ops_mpi.cpp rename to tasks/example_threads/mpi/src/ops_mpi.cpp index 4147022da..80ef31245 100644 --- a/tasks/example/mpi/src/ops_mpi.cpp +++ b/tasks/example_threads/mpi/src/ops_mpi.cpp @@ -1,4 +1,4 @@ -#include "example/mpi/include/ops_mpi.hpp" +#include "example_threads/mpi/include/ops_mpi.hpp" #include diff --git a/tasks/example/omp/include/ops_omp.hpp b/tasks/example_threads/omp/include/ops_omp.hpp similarity index 90% rename from tasks/example/omp/include/ops_omp.hpp rename to tasks/example_threads/omp/include/ops_omp.hpp index 581dbda75..7351d66b5 100644 --- a/tasks/example/omp/include/ops_omp.hpp +++ b/tasks/example_threads/omp/include/ops_omp.hpp @@ -4,7 +4,7 @@ #include #include "core/task/include/task.hpp" -#include "example/common/include/common.hpp" +#include "example_threads/common/include/common.hpp" namespace nesterov_a_test_task { diff --git a/tasks/example/omp/src/ops_omp.cpp b/tasks/example_threads/omp/src/ops_omp.cpp similarity index 95% rename from tasks/example/omp/src/ops_omp.cpp rename to tasks/example_threads/omp/src/ops_omp.cpp index 3d9515b99..d454105c3 100644 --- a/tasks/example/omp/src/ops_omp.cpp +++ b/tasks/example_threads/omp/src/ops_omp.cpp @@ -1,4 +1,4 @@ -#include "example/omp/include/ops_omp.hpp" +#include "example_threads/omp/include/ops_omp.hpp" #include #include diff --git a/tasks/example/seq/include/ops_seq.hpp b/tasks/example_threads/seq/include/ops_seq.hpp similarity index 90% rename from tasks/example/seq/include/ops_seq.hpp rename to tasks/example_threads/seq/include/ops_seq.hpp index b72ff9aaa..2ddee637f 100644 --- a/tasks/example/seq/include/ops_seq.hpp +++ b/tasks/example_threads/seq/include/ops_seq.hpp @@ -4,7 +4,7 @@ #include #include "core/task/include/task.hpp" -#include "example/common/include/common.hpp" +#include "example_threads/common/include/common.hpp" namespace nesterov_a_test_task { diff --git a/tasks/example/seq/src/ops_seq.cpp b/tasks/example_threads/seq/src/ops_seq.cpp similarity index 95% rename from tasks/example/seq/src/ops_seq.cpp rename to tasks/example_threads/seq/src/ops_seq.cpp index 0ed459fef..8ba19c4f9 100644 --- a/tasks/example/seq/src/ops_seq.cpp +++ b/tasks/example_threads/seq/src/ops_seq.cpp @@ -1,4 +1,4 @@ -#include "example/seq/include/ops_seq.hpp" +#include "example_threads/seq/include/ops_seq.hpp" #include #include diff --git a/tasks/example/settings.json b/tasks/example_threads/settings.json similarity index 100% rename from tasks/example/settings.json rename to tasks/example_threads/settings.json diff --git a/tasks/example/stl/include/ops_stl.hpp b/tasks/example_threads/stl/include/ops_stl.hpp similarity index 90% rename from tasks/example/stl/include/ops_stl.hpp rename to tasks/example_threads/stl/include/ops_stl.hpp index a26afbffe..f1c2970a4 100644 --- a/tasks/example/stl/include/ops_stl.hpp +++ b/tasks/example_threads/stl/include/ops_stl.hpp @@ -4,7 +4,7 @@ #include #include "core/task/include/task.hpp" -#include "example/common/include/common.hpp" +#include "example_threads/common/include/common.hpp" namespace nesterov_a_test_task { diff --git a/tasks/example/stl/src/ops_stl.cpp b/tasks/example_threads/stl/src/ops_stl.cpp similarity index 96% rename from tasks/example/stl/src/ops_stl.cpp rename to tasks/example_threads/stl/src/ops_stl.cpp index 06eeb6cfb..35c91ee01 100644 --- a/tasks/example/stl/src/ops_stl.cpp +++ b/tasks/example_threads/stl/src/ops_stl.cpp @@ -1,4 +1,4 @@ -#include "example/stl/include/ops_stl.hpp" +#include "example_threads/stl/include/ops_stl.hpp" #include #include diff --git a/tasks/example/tbb/include/ops_tbb.hpp b/tasks/example_threads/tbb/include/ops_tbb.hpp similarity index 90% rename from tasks/example/tbb/include/ops_tbb.hpp rename to tasks/example_threads/tbb/include/ops_tbb.hpp index 02da419ee..389f497f6 100644 --- a/tasks/example/tbb/include/ops_tbb.hpp +++ b/tasks/example_threads/tbb/include/ops_tbb.hpp @@ -4,7 +4,7 @@ #include #include "core/task/include/task.hpp" -#include "example/common/include/common.hpp" +#include "example_threads/common/include/common.hpp" namespace nesterov_a_test_task { diff --git a/tasks/example/tbb/src/ops_tbb.cpp b/tasks/example_threads/tbb/src/ops_tbb.cpp similarity index 96% rename from tasks/example/tbb/src/ops_tbb.cpp rename to tasks/example_threads/tbb/src/ops_tbb.cpp index 330accfda..cf39a1e74 100644 --- a/tasks/example/tbb/src/ops_tbb.cpp +++ b/tasks/example_threads/tbb/src/ops_tbb.cpp @@ -1,4 +1,4 @@ -#include "example/tbb/include/ops_tbb.hpp" +#include "example_threads/tbb/include/ops_tbb.hpp" #include diff --git a/tasks/example/tests/functional/main.cpp b/tasks/example_threads/tests/functional/main.cpp similarity index 73% rename from tasks/example/tests/functional/main.cpp rename to tasks/example_threads/tests/functional/main.cpp index 6cc6111f1..3576e1914 100644 --- a/tasks/example/tests/functional/main.cpp +++ b/tasks/example_threads/tests/functional/main.cpp @@ -10,12 +10,12 @@ #include "core/util/include/func_test_util.hpp" #include "core/util/include/util.hpp" -#include "example/all/include/ops_all.hpp" -#include "example/mpi/include/ops_mpi.hpp" -#include "example/omp/include/ops_omp.hpp" -#include "example/seq/include/ops_seq.hpp" -#include "example/stl/include/ops_stl.hpp" -#include "example/tbb/include/ops_tbb.hpp" +#include "example_threads/all/include/ops_all.hpp" +#include "example_threads/mpi/include/ops_mpi.hpp" +#include "example_threads/omp/include/ops_omp.hpp" +#include "example_threads/seq/include/ops_seq.hpp" +#include "example_threads/stl/include/ops_stl.hpp" +#include "example_threads/tbb/include/ops_tbb.hpp" namespace nesterov_a_test_task { @@ -33,7 +33,7 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests img; // Read image { - std::string abs_path = ppc::util::GetAbsolutePath("example/data/pic.jpg"); + std::string abs_path = ppc::util::GetAbsolutePath("example_threads/data/pic.jpg"); auto *data = stbi_load(abs_path.c_str(), &width, &height, &channels, 0); if (data == nullptr) { throw std::runtime_error("Failed to load image: " + std::string(stbi_failure_reason())); @@ -63,12 +63,11 @@ TEST_P(NesterovARunFuncTests, MatmulFromPic) { ExecuteTest(GetParam()); } const std::array kTestParam = {std::make_tuple(3, "3"), std::make_tuple(5, "5"), std::make_tuple(7, "7")}; -INIT_TASK_GENERATOR(InType, kTestParam, PPC_SETTINGS_example) +INIT_FUNC_TASK_GENERATOR(InType, kTestParam, PPC_SETTINGS_example_threads) -const auto kTestTasksList = - std::tuple_cat(ADD_FUNC_TASK_PROCESS(NesterovATestTaskALL), ADD_FUNC_TASK_PROCESS(NesterovATestTaskMPI), - ADD_FUNC_TASK_THREADS(NesterovATestTaskOMP), ADD_FUNC_TASK_THREADS(NesterovATestTaskSEQ), - ADD_FUNC_TASK_THREADS(NesterovATestTaskSTL), ADD_FUNC_TASK_THREADS(NesterovATestTaskTBB)); +const auto kTestTasksList = std::tuple_cat(ADD_FUNC_TASK(NesterovATestTaskALL), ADD_FUNC_TASK(NesterovATestTaskMPI), + ADD_FUNC_TASK(NesterovATestTaskOMP), ADD_FUNC_TASK(NesterovATestTaskSEQ), + ADD_FUNC_TASK(NesterovATestTaskSTL), ADD_FUNC_TASK(NesterovATestTaskTBB)); INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTests, ppc::util::ExpandToValues(kTestTasksList), NesterovARunFuncTests::PrintFuncTestName); diff --git a/tasks/example_threads/tests/performance/main.cpp b/tasks/example_threads/tests/performance/main.cpp new file mode 100644 index 000000000..385d9b924 --- /dev/null +++ b/tasks/example_threads/tests/performance/main.cpp @@ -0,0 +1,45 @@ +#include +#include + +#include +#include +#include +#include +#include + +#include "core/perf/include/perf.hpp" +#include "core/util/include/perf_test_util.hpp" +#include "core/util/include/util.hpp" +#include "example_threads/all/include/ops_all.hpp" +#include "example_threads/mpi/include/ops_mpi.hpp" +#include "example_threads/omp/include/ops_omp.hpp" +#include "example_threads/seq/include/ops_seq.hpp" +#include "example_threads/stl/include/ops_stl.hpp" +#include "example_threads/tbb/include/ops_tbb.hpp" + +namespace nesterov_a_test_task { + +class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { + const int kCount_ = 111; + InType input_data_{}; + + void SetUp() override { input_data_ = kCount_; } + + bool CheckTestOutputData(OutType& output_data) final { return input_data_ == output_data; } + + InType GetTestInputData() final { return input_data_; } +}; + +INIT_PERF_TASK_GENERATOR(InType, PPC_SETTINGS_example_threads) + +using PerfTasks = perf_tasks_type_list; + +const auto kAllPerfTasks = std::tuple_cat(MakeTask(PerfTasks{})); + +TEST_P(ExampleRunPerfTest, RunPerfModes) { ExecuteTest(GetParam()); } + +INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, ExampleRunPerfTest, ppc::util::TupleToGTestValues(kAllPerfTasks), + ExampleRunPerfTest::CustomPerfTestName); + +} // namespace nesterov_a_test_task From b7513af8b6360b98e74ce3c22d7025228809de41 Mon Sep 17 00:00:00 2001 From: anesterov Date: Sun, 8 Jun 2025 13:11:47 +0200 Subject: [PATCH 074/141] Fix inconsistent spacing and formatting in `util.hpp` and `util.cpp` --- cmake/configure.cmake | 4 ++ modules/core/CMakeLists.txt | 40 ++++++++++++---- .../core/util/func_tests}/util.cpp | 12 ++++- modules/core/util/include/util.hpp | 46 ++++++++++++------- scripts/run_tests.py | 2 - tasks/CMakeLists.txt | 41 +---------------- 6 files changed, 76 insertions(+), 69 deletions(-) rename {tasks/common/tests => modules/core/util/func_tests}/util.cpp (60%) diff --git a/cmake/configure.cmake b/cmake/configure.cmake index 95e55c46d..f71cdb98e 100644 --- a/cmake/configure.cmake +++ b/cmake/configure.cmake @@ -10,6 +10,10 @@ if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif(NOT CMAKE_BUILD_TYPE) +if (MSVC) + add_compile_options("/utf-8") +endif() + set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/arch" ) set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/lib" ) set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/bin" ) diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index bcc3c4ef5..c10c43b6f 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -26,22 +26,46 @@ set_target_properties(${exec_func_lib} PROPERTIES LINKER_LANGUAGE CXX) add_dependencies(${exec_func_lib} ppc_libenvpp) target_link_directories(${exec_func_lib} PUBLIC "${CMAKE_BINARY_DIR}/ppc_libenvpp/install/lib") target_link_directories(${exec_func_lib} PUBLIC "${CMAKE_BINARY_DIR}/ppc_libenvpp/build") -target_link_libraries(${exec_func_lib} PUBLIC fmt envpp) +if(MSVC) + target_link_libraries(${exec_func_lib} PUBLIC fmt libenvpp) +else() + target_link_libraries(${exec_func_lib} PUBLIC fmt envpp) +endif () -add_executable(${exec_func_tests} ${FUNC_TESTS_SOURCE_FILES}) +add_dependencies(${exec_func_lib} ppc_json) +target_link_directories(${exec_func_lib} INTERFACE "${CMAKE_BINARY_DIR}/ppc_json/install/include") + +add_dependencies(${exec_func_lib} ppc_googletest) +target_link_directories(${exec_func_lib} PUBLIC "${CMAKE_BINARY_DIR}/ppc_googletest/install/lib") +target_link_libraries(${exec_func_lib} PUBLIC gtest gtest_main) + +target_link_libraries(${exec_func_lib} PUBLIC Threads::Threads) + +find_package(OpenMP REQUIRED) +target_link_libraries(${exec_func_lib} PUBLIC ${OpenMP_libomp_LIBRARY} OpenMP::OpenMP_CXX) -add_dependencies(${exec_func_tests} ppc_googletest) -target_link_directories(${exec_func_tests} PUBLIC ${CMAKE_BINARY_DIR}/ppc_googletest/install/lib) -target_link_libraries(${exec_func_tests} PUBLIC gtest gtest_main) +add_dependencies(${exec_func_lib} ppc_onetbb) +target_link_directories(${exec_func_lib} PUBLIC ${CMAKE_BINARY_DIR}/ppc_onetbb/install/lib) +if(NOT MSVC) + if(CMAKE_BUILD_TYPE STREQUAL "Debug") + target_link_libraries(${exec_func_lib} PUBLIC tbb_debug) + else() + target_link_libraries(${exec_func_lib} PUBLIC tbb) + endif() +endif() if( MPI_COMPILE_FLAGS ) - set_target_properties(${exec_func_tests} PROPERTIES COMPILE_FLAGS "${MPI_COMPILE_FLAGS}") + set_target_properties(${exec_func_lib} PROPERTIES COMPILE_FLAGS "${MPI_COMPILE_FLAGS}") endif( MPI_COMPILE_FLAGS ) if( MPI_LINK_FLAGS ) - set_target_properties(${exec_func_tests} PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}") + set_target_properties(${exec_func_lib} PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}") endif( MPI_LINK_FLAGS ) -target_link_libraries(${exec_func_tests} PUBLIC ${MPI_LIBRARIES}) +target_link_libraries(${exec_func_lib} PUBLIC ${MPI_LIBRARIES}) + +target_link_directories(${exec_func_lib} INTERFACE ${CMAKE_SOURCE_DIR}/3rdparty/stb) + +add_executable(${exec_func_tests} ${FUNC_TESTS_SOURCE_FILES}) target_link_libraries(${exec_func_tests} PUBLIC ${exec_func_lib}) diff --git a/tasks/common/tests/util.cpp b/modules/core/util/func_tests/util.cpp similarity index 60% rename from tasks/common/tests/util.cpp rename to modules/core/util/func_tests/util.cpp index 57122c23e..53a7987be 100644 --- a/tasks/common/tests/util.cpp +++ b/modules/core/util/func_tests/util.cpp @@ -6,10 +6,18 @@ #include #include -#include "core/task/func_tests/test_task.hpp" #include "omp.h" -TEST(ppc_func_tests_common, threads_control_check_openmp) { +namespace my::nested { +struct Type {}; +} // namespace my::nested + +TEST(util_tests, extracts_correct_namespace) { + constexpr std::string_view kNs = ppc::util::GetNamespace(); + EXPECT_EQ(kNs, "my::nested"); +} + +TEST(util_tests, threads_control_check_openmp) { int ppc_num_threads = ppc::util::GetNumThreads(); int omp_num_threads = -1; diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index 96a7bd6e0..dd71460e7 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -33,35 +33,47 @@ enum GTestParamIndex : uint8_t { kTaskGetter, kNameTest, kTestParams }; std::string GetAbsolutePath(const std::string &relative_path); int GetNumThreads(); -#if (defined(__clang__) || defined(__GNUC__)) && !defined(_MSC_VER) template -consteval std::string_view GetNamespace() { +constexpr std::string_view GetNamespace() { +#if defined(__clang__) || defined(__GNUC__) constexpr std::string_view kFunc = __PRETTY_FUNCTION__; - // example: "consteval std::string_view get_namespace() [with T = my_namespace::MyClass]" constexpr std::string_view kKey = "T = "; + + auto start = kFunc.find(kKey); + if (start == std::string_view::npos) return {}; + start += kKey.size(); + + auto end = kFunc.rfind("::"); + if (end == std::string_view::npos || end <= start) return {}; + + return kFunc.substr(start, end - start); + #elif defined(_MSC_VER) -template -constexpr std::string_view GetNamespace() { constexpr std::string_view kFunc = __FUNCSIG__; - // example: "class std::basic_string_view > __cdecl get_namespace(void)" - constexpr std::string_view kKey = "get_namespace<"; -#else -static_assert(false, "Unsupported compiler"); -#endif + constexpr std::string_view kKey = "GetNamespace<"; auto start = kFunc.find(kKey); - if (start == std::string_view::npos) { - return {}; - } + if (start == std::string_view::npos) return {}; start += kKey.size(); - auto end = kFunc.find("::", start); - if (end == std::string_view::npos) { - return {}; + // Удалим class/struct/enum/union префиксы + constexpr std::string_view prefixes[] = {"class ", "struct ", "enum ", "union "}; + for (auto prefix : prefixes) { + if (kFunc.substr(start, prefix.size()) == prefix) { + start += prefix.size(); + break; + } } + auto end = kFunc.rfind("::"); + if (end == std::string_view::npos || end <= start) return {}; + return kFunc.substr(start, end - start); + +#else + static_assert([] { return false; }(), "Unsupported compiler"); + return {}; +#endif } bool IsUnderMpirun(); diff --git a/scripts/run_tests.py b/scripts/run_tests.py index 3befd48f9..4b6fee1d0 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -85,8 +85,6 @@ def run_threads(self): self.__run_exec(f"{self.work_dir / 'ppc_func_tests'} {self.__get_gtest_settings(3, '_' + task_type + '_')}") def run_core(self): - self.__run_exec(f"{self.work_dir / 'ppc_func_tests'} {self.__get_gtest_settings(1, '_common')}") - if platform.system() == "Linux" and not self.__ppc_env.get("PPC_ASAN_RUN"): self.__run_exec(f"{self.valgrind_cmd} {self.work_dir / 'core_func_tests'} " f"{self.__get_gtest_settings(1, '*')} --gtest_filter=*:-*_death_test") diff --git a/tasks/CMakeLists.txt b/tasks/CMakeLists.txt index 4ec741e79..a49ae9be7 100644 --- a/tasks/CMakeLists.txt +++ b/tasks/CMakeLists.txt @@ -8,7 +8,7 @@ set(exec_perf_tests "ppc_perf_tests") set(list_of_exec_tests "") if (USE_FUNC_TESTS) add_executable(${exec_func_tests} "${CMAKE_CURRENT_SOURCE_DIR}/common/runners/functional.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/common/tests/util.cpp") + "../modules/core/util/func_tests/util.cpp") list(APPEND list_of_exec_tests ${exec_func_tests}) endif (USE_FUNC_TESTS) @@ -34,45 +34,6 @@ endforeach() add_library(stb_image INTERFACE) foreach (exec_func ${list_of_exec_tests}) - target_link_libraries(${exec_func} PUBLIC Threads::Threads) - - find_package(OpenMP REQUIRED) - target_link_libraries(${exec_func} PUBLIC ${OpenMP_libomp_LIBRARY} OpenMP::OpenMP_CXX) - - if( MPI_COMPILE_FLAGS ) - set_target_properties(${exec_func} PROPERTIES COMPILE_FLAGS "${MPI_COMPILE_FLAGS}") - endif( MPI_COMPILE_FLAGS ) - - if( MPI_LINK_FLAGS ) - set_target_properties(${exec_func} PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}") - endif( MPI_LINK_FLAGS ) - target_link_libraries(${exec_func} PUBLIC ${MPI_LIBRARIES}) - - add_dependencies(${exec_func} ppc_onetbb) - target_link_directories(${exec_func} PUBLIC ${CMAKE_BINARY_DIR}/ppc_onetbb/install/lib) - if(NOT MSVC) - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - target_link_libraries(${exec_func} PUBLIC tbb_debug) - else() - target_link_libraries(${exec_func} PUBLIC tbb) - endif() - endif() - - target_link_directories(stb_image INTERFACE ${CMAKE_SOURCE_DIR}/3rdparty/stb) - target_link_libraries(${exec_func} PUBLIC stb_image) - - add_dependencies(${exec_func} ppc_googletest) - target_link_directories(${exec_func} PUBLIC "${CMAKE_BINARY_DIR}/ppc_googletest/install/lib") - target_link_libraries(${exec_func} PUBLIC gtest gtest_main) - - add_dependencies(${exec_func} ppc_json) - target_link_directories(${exec_func} INTERFACE "${CMAKE_BINARY_DIR}/ppc_json/install/include") - - add_dependencies(${exec_func} ppc_libenvpp) - target_link_directories(${exec_func} PUBLIC "${CMAKE_BINARY_DIR}/ppc_libenvpp/install/lib") - target_link_directories(${exec_func} PUBLIC "${CMAKE_BINARY_DIR}/ppc_libenvpp/build") - target_link_libraries(${exec_func} PUBLIC fmt envpp) - enable_testing() add_test(NAME ${exec_func} COMMAND ${exec_func}) From 68f93bb421a6a3830646492be1c16079a3a98411 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 13:28:55 +0200 Subject: [PATCH 075/141] Rename tests and update filters to disable Valgrind-specific cases Adjusted naming conventions for tests and death tests to append `_disabled_valgrind` where appropriate. Updated `gtest_filter` in the test runner script to exclude Valgrind-incompatible tests for improved compatibility and clarity. --- modules/core/task/func_tests/task_tests.cpp | 4 ++-- modules/core/util/func_tests/util.cpp | 2 +- modules/core/util/include/util.hpp | 1 - scripts/run_tests.py | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/modules/core/task/func_tests/task_tests.cpp b/modules/core/task/func_tests/task_tests.cpp index 1adf72377..ff09b10e6 100644 --- a/modules/core/task/func_tests/task_tests.cpp +++ b/modules/core/task/func_tests/task_tests.cpp @@ -128,7 +128,7 @@ TEST(task_tests, check_float) { EXPECT_NEAR(test_task.GetOutput(), in.size(), 1e-3); } -DEATH_TEST(task_tests, check_wrong_order_death_test) { +DEATH_TEST(task_tests, check_wrong_order_disabled_valgrind) { auto destroy_function = [] { // Create data std::vector in(20, 1); @@ -143,7 +143,7 @@ DEATH_TEST(task_tests, check_wrong_order_death_test) { EXPECT_DEATH_IF_SUPPORTED(destroy_function(), ".*ORDER OF FUNCTIONS IS NOT RIGHT.*"); } -DEATH_TEST(task_tests, check_empty_order_death_test) { +DEATH_TEST(task_tests, check_empty_order_disabled_valgrind) { auto destroy_function = [] { // Create data std::vector in(20, 1); diff --git a/modules/core/util/func_tests/util.cpp b/modules/core/util/func_tests/util.cpp index 53a7987be..db376daa6 100644 --- a/modules/core/util/func_tests/util.cpp +++ b/modules/core/util/func_tests/util.cpp @@ -17,7 +17,7 @@ TEST(util_tests, extracts_correct_namespace) { EXPECT_EQ(kNs, "my::nested"); } -TEST(util_tests, threads_control_check_openmp) { +TEST(util_tests, threads_control_check_openmp_disabled_valgrind) { int ppc_num_threads = ppc::util::GetNumThreads(); int omp_num_threads = -1; diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index dd71460e7..6179d6011 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -56,7 +56,6 @@ constexpr std::string_view GetNamespace() { if (start == std::string_view::npos) return {}; start += kKey.size(); - // Удалим class/struct/enum/union префиксы constexpr std::string_view prefixes[] = {"class ", "struct ", "enum ", "union "}; for (auto prefix : prefixes) { if (kFunc.substr(start, prefix.size()) == prefix) { diff --git a/scripts/run_tests.py b/scripts/run_tests.py index 4b6fee1d0..1119a6052 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -87,7 +87,7 @@ def run_threads(self): def run_core(self): if platform.system() == "Linux" and not self.__ppc_env.get("PPC_ASAN_RUN"): self.__run_exec(f"{self.valgrind_cmd} {self.work_dir / 'core_func_tests'} " - f"{self.__get_gtest_settings(1, '*')} --gtest_filter=*:-*_death_test") + f"{self.__get_gtest_settings(1, '*')} --gtest_filter=*:-*_disabled_valgrind") self.__run_exec(f"{self.work_dir / 'core_func_tests'} {self.__get_gtest_settings(1, '*')}") From 751a4750b07b828af5648a3e95161d494f857d8e Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 13:40:00 +0200 Subject: [PATCH 076/141] Refactor type extraction logic in `Demangle` for improved clarity and correctness Optimized namespace extraction by refining `kFunc` substring logic and replacing redundant conditions. Improved handling of compiler-specific type demangling to ensure consistent and accurate results. --- modules/core/util/include/util.hpp | 33 ++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index 6179d6011..a20b4b2cf 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -1,8 +1,7 @@ #pragma once -#include -#include #include +#include #include #include @@ -40,13 +39,24 @@ constexpr std::string_view GetNamespace() { constexpr std::string_view kKey = "T = "; auto start = kFunc.find(kKey); - if (start == std::string_view::npos) return {}; + if (start == std::string_view::npos) { + return {}; + } start += kKey.size(); - auto end = kFunc.rfind("::"); - if (end == std::string_view::npos || end <= start) return {}; + auto end = kFunc.find_first_of(";]> ,", start); + if (end == std::string_view::npos) { + return {}; + } + + auto full_type = kFunc.substr(start, end - start); - return kFunc.substr(start, end - start); + auto ns_end = full_type.rfind("::"); + if (ns_end == std::string_view::npos) { + return {}; + } + + return full_type.substr(0, ns_end); #elif defined(_MSC_VER) constexpr std::string_view kFunc = __FUNCSIG__; @@ -64,10 +74,15 @@ constexpr std::string_view GetNamespace() { } } - auto end = kFunc.rfind("::"); - if (end == std::string_view::npos || end <= start) return {}; + auto end = kFunc.find('>', start); + if (end == std::string_view::npos) return {}; + + auto full_type = kFunc.substr(start, end - start); + + auto ns_end = full_type.rfind("::"); + if (ns_end == std::string_view::npos) return {}; - return kFunc.substr(start, end - start); + return full_type.substr(0, ns_end); #else static_assert([] { return false; }(), "Unsupported compiler"); From d72991996df891c018900c04a957af6711c7485a Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 14:13:05 +0200 Subject: [PATCH 077/141] Switch Windows build configuration to use LLVM and GCC tooling Replaced MSVC with LLVM (v17.0) as the compiler and updated the build environment to use GCC for ccache. Simplified configuration by removing MSVC-specific setup steps and Intel OpenMP dependencies. Updated associated build and install scripts to reflect the new toolchain. --- .github/workflows/main.yml | 41 ++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1db23eb43..1d42f1314 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -837,54 +837,51 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive - - name: Add msbuild to PATH - uses: microsoft/setup-msbuild@v2 + + - name: Setup LLVM + uses: KyleMayes/install-llvm-action@v1 with: - vs-version: 'latest' + version: "17.0" + - name: Setup MPI uses: mpi4py/setup-mpi@v1 with: mpi: msmpi + - name: Setup ccache uses: Chocobo1/setup-ccache-action@v1 with: - windows_compile_environment: msvc + windows_compile_environment: gcc + - name: Setup ninja uses: seanmiddleditch/gha-setup-ninja@v6 - - name: Setup MSVC for Ninja - uses: ilammy/msvc-dev-cmd@v1 - - name: Install Intel OpenMP via NuGet - run: | - nuget install intelopenmp.redist.win - shell: pwsh + - name: CMake configure run: > cmake -S . -B build -G Ninja - -D CMAKE_C_COMPILER=clang-cl - -D CMAKE_CXX_COMPILER=clang-cl + -D CMAKE_C_COMPILER=clang + -D CMAKE_CXX_COMPILER=clang++ -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=install - -D CMAKE_INCLUDE_PATH="C:/Program Files (x86)/Intel/oneAPI/compiler/latest/windows/include" - -D CMAKE_LIBRARY_PATH="C:/Program Files (x86)/Intel/oneAPI/compiler/latest/windows/lib/intel64_win" - -D CMAKE_EXE_LINKER_FLAGS="/NODEFAULTLIB:vcomp.lib \"C:/Program Files (x86)/Intel/oneAPI/compiler/latest/windows/lib/intel64_win/libiomp5md.lib\"" - shell: pwsh env: - CC: clang-cl - CXX: clang-cl + CC: clang + CXX: clang++ + - name: Build project run: cmake --build build --config Release --parallel - shell: pwsh env: - CC: clang-cl - CXX: clang-cl + CC: clang + CXX: clang++ + - name: Install project run: cmake --install build - shell: pwsh + - name: Archive installed package run: Compress-Archive -Path install -DestinationPath windows-clang-install.zip shell: pwsh + - name: Upload installed package uses: actions/upload-artifact@v4 with: From 82896bef4fdaca9bf46b0b4f35f07daba5693a3e Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 14:19:59 +0200 Subject: [PATCH 078/141] Switch Windows MPI setup from MS-MPI to MPICH Replaced `mpi4py/setup-mpi` with a manual installation and configuration of MPICH (v4.2) for Windows builds. Updated CMake configuration to use `CMAKE_PREFIX_PATH` for MPICH integration. Simplified environment setup for consistent MPI tooling. --- .github/workflows/main.yml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1d42f1314..aa9fdc23b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -843,10 +843,16 @@ jobs: with: version: "17.0" - - name: Setup MPI - uses: mpi4py/setup-mpi@v1 - with: - mpi: msmpi + - name: Download MPICH (64-bit) + run: | + curl -LO https://www.mpich.org/static/downloads/4.2/mpich-4.2-windows-x86_64.zip + unzip mpich-4.2-windows-x86_64.zip -d mpich + echo "MPICH installed" + + - name: Setup environment for MPICH + run: | + echo "$GITHUB_WORKSPACE/mpich/bin" >> $GITHUB_PATH + echo "MPICH_ROOT=$GITHUB_WORKSPACE/mpich" >> $GITHUB_ENV - name: Setup ccache uses: Chocobo1/setup-ccache-action@v1 @@ -865,6 +871,7 @@ jobs: -D CMAKE_CXX_COMPILER_LAUNCHER=ccache -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=install + -D CMAKE_PREFIX_PATH="${{ env.MPICH_ROOT }}" env: CC: clang CXX: clang++ From e7220ec1294432b7e85a7ad63b885fc7e018e897 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 14:35:02 +0200 Subject: [PATCH 079/141] Switch to `mpi4py/setup-mpi` for MPI setup in Windows builds Replaced manual MPICH installation and configuration with `mpi4py/setup-mpi` GitHub action for streamlined MPI setup. Updated CMake configuration to require MPI and removed redundant MPICH-specific setup steps. --- .github/workflows/main.yml | 14 ++++---------- modules/core/CMakeLists.txt | 1 + 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index aa9fdc23b..160b23e09 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -843,16 +843,10 @@ jobs: with: version: "17.0" - - name: Download MPICH (64-bit) - run: | - curl -LO https://www.mpich.org/static/downloads/4.2/mpich-4.2-windows-x86_64.zip - unzip mpich-4.2-windows-x86_64.zip -d mpich - echo "MPICH installed" - - - name: Setup environment for MPICH - run: | - echo "$GITHUB_WORKSPACE/mpich/bin" >> $GITHUB_PATH - echo "MPICH_ROOT=$GITHUB_WORKSPACE/mpich" >> $GITHUB_ENV + - name: Setup MPI + uses: mpi4py/setup-mpi@v1 + with: + mpi: msmpi - name: Setup ccache uses: Chocobo1/setup-ccache-action@v1 diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index c10c43b6f..503f87d61 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -54,6 +54,7 @@ if(NOT MSVC) endif() endif() +find_package(MPI REQUIRED) if( MPI_COMPILE_FLAGS ) set_target_properties(${exec_func_lib} PROPERTIES COMPILE_FLAGS "${MPI_COMPILE_FLAGS}") endif( MPI_COMPILE_FLAGS ) From 8856a7150bec99b9f056c930b164f02a7db8467d Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 15:00:40 +0200 Subject: [PATCH 080/141] Switch Windows build configuration from GCC to MSVC and update CMake to use clang-cl Updated Windows build environment to use MSVC with ccache and clang-cl as the compiler. Adjusted CMake settings and environment variables to reflect the new toolchain. Simplified build configuration by removing GCC-specific setup. --- .github/workflows/main.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 160b23e09..2b13dfff5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -851,7 +851,7 @@ jobs: - name: Setup ccache uses: Chocobo1/setup-ccache-action@v1 with: - windows_compile_environment: gcc + windows_compile_environment: msvc - name: Setup ninja uses: seanmiddleditch/gha-setup-ninja@v6 @@ -859,22 +859,21 @@ jobs: - name: CMake configure run: > cmake -S . -B build -G Ninja - -D CMAKE_C_COMPILER=clang - -D CMAKE_CXX_COMPILER=clang++ + -D CMAKE_C_COMPILER=clang-cl + -D CMAKE_CXX_COMPILER=clang-cl -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=install - -D CMAKE_PREFIX_PATH="${{ env.MPICH_ROOT }}" env: - CC: clang - CXX: clang++ + CC: clang-cl + CXX: clang-cl - name: Build project run: cmake --build build --config Release --parallel env: - CC: clang - CXX: clang++ + CC: clang-cl + CXX: clang-cl - name: Install project run: cmake --install build From d42fd48bce8b6b76172fc7c3f7540f6f2a29108e Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 15:20:42 +0200 Subject: [PATCH 081/141] Update LLVM GitHub action to v2 and set version to 20.1.4 --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2b13dfff5..d0b13db1d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -839,9 +839,9 @@ jobs: submodules: recursive - name: Setup LLVM - uses: KyleMayes/install-llvm-action@v1 + uses: KyleMayes/install-llvm-action@v2 with: - version: "17.0" + version: "20.1.4" - name: Setup MPI uses: mpi4py/setup-mpi@v1 From 54f5e9a3ed2d8e5cacd05321eb456fe7887f1f3f Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 15:36:37 +0200 Subject: [PATCH 082/141] Update Windows build to include `CMAKE_PREFIX_PATH` for LLVM --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d0b13db1d..7fe0e1f56 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -865,6 +865,7 @@ jobs: -D CMAKE_CXX_COMPILER_LAUNCHER=ccache -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=install + -D CMAKE_PREFIX_PATH="C:/Program Files/LLVM" env: CC: clang-cl CXX: clang-cl From 11d57776f63c9eae7efaac618274773500fa44f0 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 16:00:00 +0200 Subject: [PATCH 083/141] Add `example_processes` task with MPI and SEQ modes Implemented new task structure under `example_processes` with support for MPI and SEQ modes. Added functional and performance tests, updated CMake files and settings, and integrated with the existing testing framework. --- 3rdparty/stb_image_wrapper.cpp | 2 + 3rdparty/stb_library.hpp | 1 - modules/core/CMakeLists.txt | 5 +- modules/core/util/include/util.hpp | 2 +- modules/core/util/src/util.cpp | 10 ++- tasks/CMakeLists.txt | 7 +- tasks/example_processes/CMakeLists.txt | 58 ++++++++++++++ .../common/include/common.hpp | 16 ++++ tasks/example_processes/data/pic.jpg | Bin 0 -> 15356 bytes tasks/example_processes/info.json | 8 ++ .../mpi/include/ops_mpi.hpp | 6 +- .../mpi/src/ops_mpi.cpp | 6 +- .../example_processes/seq/include/ops_seq.hpp | 21 +++++ tasks/example_processes/seq/src/ops_seq.cpp | 50 ++++++++++++ tasks/example_processes/settings.json | 11 +++ .../tests/functional/main.cpp | 72 ++++++++++++++++++ .../tests/performance/main.cpp | 40 ++++++++++ tasks/example_threads/all/include/ops_all.hpp | 4 +- tasks/example_threads/all/src/ops_all.cpp | 4 +- .../example_threads/common/include/common.hpp | 4 +- tasks/example_threads/info.json | 5 +- tasks/example_threads/omp/include/ops_omp.hpp | 4 +- tasks/example_threads/omp/src/ops_omp.cpp | 4 +- tasks/example_threads/seq/include/ops_seq.hpp | 4 +- tasks/example_threads/seq/src/ops_seq.cpp | 4 +- tasks/example_threads/settings.json | 5 +- tasks/example_threads/stl/include/ops_stl.hpp | 4 +- tasks/example_threads/stl/src/ops_stl.cpp | 4 +- tasks/example_threads/tbb/include/ops_tbb.hpp | 4 +- tasks/example_threads/tbb/src/ops_tbb.cpp | 4 +- .../example_threads/tests/functional/main.cpp | 21 +++-- .../tests/performance/main.cpp | 17 ++--- 32 files changed, 344 insertions(+), 63 deletions(-) create mode 100644 3rdparty/stb_image_wrapper.cpp create mode 100644 tasks/example_processes/CMakeLists.txt create mode 100644 tasks/example_processes/common/include/common.hpp create mode 100644 tasks/example_processes/data/pic.jpg create mode 100644 tasks/example_processes/info.json rename tasks/{example_threads => example_processes}/mpi/include/ops_mpi.hpp (74%) rename tasks/{example_threads => example_processes}/mpi/src/ops_mpi.cpp (89%) create mode 100644 tasks/example_processes/seq/include/ops_seq.hpp create mode 100644 tasks/example_processes/seq/src/ops_seq.cpp create mode 100644 tasks/example_processes/settings.json create mode 100644 tasks/example_processes/tests/functional/main.cpp create mode 100644 tasks/example_processes/tests/performance/main.cpp diff --git a/3rdparty/stb_image_wrapper.cpp b/3rdparty/stb_image_wrapper.cpp new file mode 100644 index 000000000..72063ea3a --- /dev/null +++ b/3rdparty/stb_image_wrapper.cpp @@ -0,0 +1,2 @@ +#define STB_IMAGE_IMPLEMENTATION +#include "stb_library.hpp" diff --git a/3rdparty/stb_library.hpp b/3rdparty/stb_library.hpp index 36039a3d8..56492de6f 100644 --- a/3rdparty/stb_library.hpp +++ b/3rdparty/stb_library.hpp @@ -5,7 +5,6 @@ #pragma clang diagnostic ignored "-Wcast-align" #endif -#define STB_IMAGE_IMPLEMENTATION #include #if defined(__clang__) diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index 503f87d61..119054344 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -64,7 +64,10 @@ if( MPI_LINK_FLAGS ) endif( MPI_LINK_FLAGS ) target_link_libraries(${exec_func_lib} PUBLIC ${MPI_LIBRARIES}) -target_link_directories(${exec_func_lib} INTERFACE ${CMAKE_SOURCE_DIR}/3rdparty/stb) + +add_library(stb_image STATIC ${CMAKE_SOURCE_DIR}/3rdparty/stb_image_wrapper.cpp) +target_include_directories(stb_image PUBLIC ${CMAKE_SOURCE_DIR}/3rdparty/stb) +target_link_libraries(${exec_func_lib} PUBLIC stb_image) add_executable(${exec_func_tests} ${FUNC_TESTS_SOURCE_FILES}) diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index a20b4b2cf..107b47328 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -29,7 +29,7 @@ namespace ppc::util { enum GTestParamIndex : uint8_t { kTaskGetter, kNameTest, kTestParams }; -std::string GetAbsolutePath(const std::string &relative_path); +std::string GetAbsoluteTaskPath(const std::string& id_path, const std::string& relative_path); int GetNumThreads(); template diff --git a/modules/core/util/src/util.cpp b/modules/core/util/src/util.cpp index d715aadf0..a7db755b1 100644 --- a/modules/core/util/src/util.cpp +++ b/modules/core/util/src/util.cpp @@ -6,11 +6,19 @@ #include #include -std::string ppc::util::GetAbsolutePath(const std::string& relative_path) { +namespace { + +static std::string GetAbsolutePath(const std::string& relative_path) { const std::filesystem::path path = std::string(PPC_PATH_TO_PROJECT) + "/tasks/" + relative_path; return path.string(); } +} // namespace + +std::string ppc::util::GetAbsoluteTaskPath(const std::string& id_path, const std::string& relative_path) { + return GetAbsolutePath(id_path + "/data/" + relative_path); +} + int ppc::util::GetNumThreads() { const auto num_threads = env::get("PPC_NUM_THREADS"); if (num_threads.has_value()) { diff --git a/tasks/CMakeLists.txt b/tasks/CMakeLists.txt index a49ae9be7..a424b52f1 100644 --- a/tasks/CMakeLists.txt +++ b/tasks/CMakeLists.txt @@ -7,8 +7,7 @@ set(exec_perf_tests "ppc_perf_tests") # Init func tests executable files set(list_of_exec_tests "") if (USE_FUNC_TESTS) - add_executable(${exec_func_tests} "${CMAKE_CURRENT_SOURCE_DIR}/common/runners/functional.cpp" - "../modules/core/util/func_tests/util.cpp") + add_executable(${exec_func_tests} "${CMAKE_CURRENT_SOURCE_DIR}/common/runners/functional.cpp") list(APPEND list_of_exec_tests ${exec_func_tests}) endif (USE_FUNC_TESTS) @@ -26,13 +25,11 @@ foreach(subd ${subdirs}) set(SETTINGS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${subd}/settings.json") add_compile_definitions(PPC_SETTINGS_${subd}=\"${SETTINGS_PATH}\") + add_compile_definitions(PPC_ID_${subd}=\"${subd}\") add_subdirectory(${subd}) endforeach() -# Link 3rdparty libraries -add_library(stb_image INTERFACE) - foreach (exec_func ${list_of_exec_tests}) enable_testing() add_test(NAME ${exec_func} COMMAND ${exec_func}) diff --git a/tasks/example_processes/CMakeLists.txt b/tasks/example_processes/CMakeLists.txt new file mode 100644 index 000000000..2c6bfd2ac --- /dev/null +++ b/tasks/example_processes/CMakeLists.txt @@ -0,0 +1,58 @@ +get_filename_component(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) +project(CURRENT_DIR_NAME) + +set(exec_func_tests "ppc_func_tests") +set(exec_perf_tests "ppc_perf_tests") +set(test_base_dir "${CMAKE_CURRENT_SOURCE_DIR}/tests") + +# Init func tests executable files +set(list_of_exec_tests "") +if (USE_FUNC_TESTS) + file(GLOB_RECURSE func_tests_source_files "${test_base_dir}/functional/*") + target_sources(${exec_func_tests} PRIVATE ${func_tests_source_files}) + list(APPEND list_of_exec_tests ${exec_func_tests}) +endif (USE_FUNC_TESTS) + +# Init perf tests executable files +if (USE_PERF_TESTS) + file(GLOB_RECURSE perf_tests_source_files "${test_base_dir}/performance/*") + target_sources(${exec_perf_tests} PRIVATE ${perf_tests_source_files}) + list(APPEND list_of_exec_tests ${exec_perf_tests}) +endif (USE_PERF_TESTS) + +# Print student task name +get_filename_component(TASK_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) +message(STATUS "-- ${TASK_NAME}") + +set(technologies "all" "mpi" "omp" "seq" "stl" "tbb") + +# Create lib +foreach (dir_type ${technologies}) + # Check directory existing + set(base_dir "${CMAKE_CURRENT_SOURCE_DIR}/${dir_type}") + if (NOT EXISTS "${base_dir}") + continue() + endif () + + # Print type of directories + message(STATUS "-- -- ${dir_type}") + + # Create task library + file(GLOB_RECURSE lib_source_files "${base_dir}/include/*" "${base_dir}/src/*") + file(GLOB source_files "${base_dir}/src/*") + + list(LENGTH source_files result_length) + set(name_lib "${TASK_NAME}_${dir_type}") + if(result_length EQUAL 0) + add_library(${name_lib} INTERFACE ${lib_source_files}) + else() + add_library(${name_lib} STATIC ${lib_source_files}) + endif() + set_target_properties(${name_lib} PROPERTIES LINKER_LANGUAGE CXX) + target_link_libraries(${name_lib} PUBLIC core_module_lib) + + # Link core library + foreach (exec_func ${list_of_exec_tests}) + target_link_libraries(${exec_func} PUBLIC ${name_lib}) + endforeach () +endforeach () diff --git a/tasks/example_processes/common/include/common.hpp b/tasks/example_processes/common/include/common.hpp new file mode 100644 index 000000000..339aed794 --- /dev/null +++ b/tasks/example_processes/common/include/common.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include +#include + +#include "core/task/include/task.hpp" +#include "core/util/include/util.hpp" + +namespace nesterov_a_test_task_processes { + +using InType = int; +using OutType = int; +using TestType = std::tuple; +using BaseTask = ppc::core::Task; + +} // namespace nesterov_a_test_task_processes diff --git a/tasks/example_processes/data/pic.jpg b/tasks/example_processes/data/pic.jpg new file mode 100644 index 0000000000000000000000000000000000000000..34458023494a39d66880a98aa5dcad18eb14b249 GIT binary patch literal 15356 zcmb7r1ymeM+h(J|Lh#^jgS!(nxH}|3!r<;sAOsKYPH>0dE6e&6od zf6v*P!%WfLQ`J@7_0Ic9Kg~R?0BAB2(h>j^6aYX$Ucl2D)Qq&4n7)#VqJ*^E>wk89 z2OtHO1put99qm;lMM<@^bx5DB{PT@p``&{cY=3?J4+YZh<mpyF;3wpd(jL+|a@S=2LIFre$`zZZ5<)UDE+G2tEq@V>V}Xyt;v7Y z4gRYRwzdCtd?@4?0V_+VUw!>5zs?xN$XZ<$@`(WXBLo}(6+jXY{WX5b|Bzyn1pqu3 z000yDpKS(708r--0JwAi*+%&V0ABb3K<&tXw*6;LY~S0z|J@uc}B7ywT50pPhd z0AT(A0Him+_d(wNhjSx^>>`Ammks1)0$2h@04X31SOZ{y2~uMNSO8Xl>uDYk17M(k zm0#~LkOB)2`>PgAVo71sMPU1NFQ79WC$- z0Uiz!76ux!R|O4nIS^rBkx>xfV4>h3hd=?)FmUkC&@nJ!u~@NjUXmf;vT=)OeDcew z8Y8Em`noY_Uo!DAF1^Q*^SP5kQd-wxrQ0dNSA z4iO=HHP8Vl7-(2nXlTUe$S5$7gP@>c(BUuuSa`B$n5-h?%2?P4IBZ-h_Kp=*FL5b2 zMBm$e^!*e)Hcrhc_F7dfDyFidlaiL5TODi^o0UDfMrE*``7{UoY6==11|1Lr5SWE7 z$Aqi}Jt})ogXX0k>MxE4Ncus+5yA){#z7(OyeXs56>}TSH!UPkRd@`O)C&{{JxaZU z3dWq3W;mr(;ooeu)rI48wv;6---WI|e`ktH3MX~p!O-Jqs1~P7Du-|)?vnnfWirkq zuT!)eXP&2P%7V6bNT>UAR7v9-9GfNUT6naiu^sHoj5{-uI^vdD@Xc!%{{T>6;JR;T z^j;`v*-$g){&*Ef-QYewdTJ(m*~XkMUlwtsK|2hxS~#IuPyl4LqqfP=%$ygw_UiQc zKS7h}-j(sJdB&`MoTB8y`*}^$BTQvCa9?wAF>@$7VkekE2za z;EYQl*-~;cz?RzQ6w3M%sJ9|g1_RQ#y@IW5*{M#5NQqP_2EFW|$h;O7+Eh;8tls6j zRBK4ZOON4)9&M8K;zV<`(fUFFBp@5_T8aBalZI^xpNIM)8q9LZlNaXHYB3PXAF0^`<4(kgxJ*8aN~9k5zUxXXSPA zY6b(w)}kNKg3=#Y+ZT$F~iWgw2P|?BJ(Xx*NT=ZdxE^l>#b&d5egtiwlOi- zS2CLJ(zcNVsL1cTd}KaGItNjkFbi`r9%BriEl<%f3-wppmBvUFITgvmeKeAWrXLJY zmT;snllkZR1Q-1u*GI~<6kBQ932wY_KvW|ZJG$}WuJOm8g4^Xqu;9Grc|e^SxM6}A?Yk` zIX0_Gh(E*u%jttk$rNHyV|hw5qKyx`DzhZ^d7b)fg)-!;TC&EY9$9=pHqw4F*omK99fTb zK0=SyYR6mM7XsEy=hZ}&#;il1dD^SuC8SHW7I3DJ5kY`|4p+-E-|^yDn}xUsUh3q%LRVW;`k6fxz@O2+FXIuJ#m@ zT9}$EYR*MrpT$0K{N>#PbJJL~^b^238v0m*Sad94t9ja@yiqic+_3&qTychxy~ab~ zc4D4BlGK!1VDATVmTf3nx&SrWXNC!)0`8Qd+H%L}T&zd{*4h~W;J5Lqvz5nqi71lC z=R7$2;`PMj$u{b17`w_aqTJ(iLFRrr(v&{WL_*%?%4aVS|i6|A1IPccJ`s zbPYl!Y`-umdXJ_4D`)ojT5qnSx+1UJ8-dCkj)%dIxC1Dz(#HA*X$qD4C6PtgIOdnt zXR4CCc|)Kq+kGBk7$t-?9jm`r7i6fqv%5hhEq)BAAL7D3kDwEi+!-_+Qhd;qOiS4G zW6%eRuI|7TG0O9}8GVlBdVci2>}vUX^Rub5(&lD&rd8quec#e)>W|nT-1s7d0^R9z zwGZ{5kNHW4sP0q-m=kj^3X{xAxH;p(Wp?NiqooHq&OEYV<#8dmPJydzK5rEG)refOr( zW6+CaofzxqxT5cRhu=_lSC|lN*-!Pc$r9YoEh`+GWJO_}QgV_lj)}>0keUUeR-g!M zv<;8maPp&#qCh9TqPP0!@_C>nX&(Ph?gV$Dnmfms{jjJgZ>ffD#iGEX5kLh!kT@tNi4N}25OvU3x(lq^q&@q87} zle8LkPsu5Pa@~zH)YG!M`@}q^&n=y1N!3n?VNI*4`_8nxAU_SR*}Is^FdO(jr^0bL zcfmz47>~jS{6gEj_VW|K;nnvjVw$?X?t)snK!?k9lHF%9sk?S%*pRQNkmVRGcQlG? z_X!gNmoFSw0;U8OF?qO+TWd;>-K(%g*RXVjD~2kW?P$~wOuM>8@BeCyU>hV%Gc0a1 z{vl=6afmuIX*k(|fl<*{l7Z^AeNw#++*l$Txj5c#@I&Uz_Ln%p%)RaKx8Lnu;T4-S zN^D8*Wby})s;nj0I@JttTPpN=?>g^Z%f2d>c^P|?zxP!pV^C} zF`0M5ov1_xxWb(6NZSA2NOaSM=W`tmdr)@O{v@3QxW}J#tjnfSc}>R>RZcTak__gg zC?hdlX3^B)zt5XJYhKT+nVx^)@&q^*Jk!}MV<4{_NUiF7)7a3#D(AW?R8sFZ41Pmx zr8YEkfO8Q?xl^QIgcT?XLPeW`4|+!`iZvHen#Q2M0QZ$rj;5RRd6zSdSx@j(BhSyv z^pK1f_Mau}ES?v9VLa;xsl+nqvp~5kuT`VHlfytoUpsg^a*%PcwQ5^@ZKS;&^DzD% zQP4F3FMMV^(>VP5>De@cp?f-9jP-?iHt&l$^;cTzDfW=eMS^tFG$WsdT&MbVxyr&8cMO8(9`#HyS)ZX^63;m!7Gx z09!P3V$(2Ra(wMsk-Xr+uRVoQuH_q7zfX4bZWAp6TD~1ti`T9#&<5+Or&xAr#IbEg zgzUWI$hCVE^AdryO>2*t>Iu*g(!{rzvw?pCVh12`vG{Uk7Hjz0rRUArhfF+G*d3R2 zn&KP1>eFPQ!_9lKvwX~1qGL_wQ$H_)`ZJDN1rJXnNuE87mpMkMt{-Shc$um@_=>!; zuDUb_?cyA1T8m8j@ovRenbfou{9i}reSRc4^==7#0xC_e%g>&Gl~tyn_qJO0y2}3i z2O+24Y4_yK2=s4TGtS+EN6u)Ra3lN$x2td7L09#>c(XIH%Pd+;VAN{D<~@pqR~0Wf znZ`8dp13^ppG=O9!8a~UXy2rBVc?y(_!Z5d+nViqD2eK=YV3&Uw%)4!kx>*#)PUFg znw@<)Zw7hfAvWcXV`1Rj6md@>&~44VEpA^CBsoD`>sd8W3p+SsD-f7YgMKY^A(YFl zdcNdz1b?_WixF33l34x;o#^&3f?d{dyRJvgAv}}JT|&DzaLv6ldS8y-Jb#Ya^R;I$ z@&n>=QPOF^hbSJ|ND+ygx~x$zJMZv$aP{EGGO^ZNs{ESG#P+CnpWFT2|2{@~3LRnm4_iGoa88nO5jpz;Ki$f0yIkAXVL zJT0SGe}b#8A_NTaxf(AdDm6;aJ#u?fHGxkq#(Zfm zBF!aE*o#NzUZggr_)2UtfEjeVzxPqyI)CRrh2Z(T*BO#do|R%pQ23%tcdUp+?hbr+ z%bIq&$8FaJ?;-QU6YwB(_kR3h@CoR60*;@6>ovn!?2RXY|5`kmS)BN4RiLetl7Dq+ z6Eci*qvNjisAZmXn!fE-aSJt(4# z@{^4wGfmA9b#P*7bETD}Kq^vjbg*c`q{Fz40^kSqF^tR45+Y31EeBV!4}M+VtO{A( zE8H&8?!Dba`EBW}HEdxe^-12@g@eoFG>JdC^aXi~iT8#MPci37*bQenLh_<#-+g5$ zBz>(QMw`utE@2v8!6Au`v9|mC>v@~x>sdx(Q;{ctSOHOY*}=DTP8|1@Y0bscX1@B;}ivRTs=vn1FQS%pgad& zV{8>s7;DPSZvs=Jmr8FLXR?sg>6-n~Ns}<=AR#x(d`#9TfOz?DuAwUi&m1YQbEw$3&zG^Gwn|js+AUNu=3E0+V2yk#m@p z8E$GvKQA9KW*qHA0T5#+z9Z^tz#}=Ke)}hw!4rQ!c5m>GrPx{QY+0|S_eWLeVtDM8N z_m(1u>JV$-U);mkLehWi^#p_~SfSmCjS9KBYZNwQniQ#;yeTEa9HX%lTpu`Dj|tG3 z^V`n#QX)BzupHLmD{|t>D(1 zwnz+Z+qE7}1n!VtjAcYx^-AH@nbq^Z%<$ltk(c0)L|B27Hw~O44!-MmnYI6JoM-Mu z;ohR(2DyiR+;`#*JppiiQhgda!(?ui#jt~Al41mJJ$ev$f(u>El*YAFYcs?sIEoo) z2jVBIg6RC?V~EiT7o?(=Sn6y;EB$Lc=%|hIzAj_e4oo^?D@qE)8|J4h;*vt(pFCvs zX~0j`VRq@e&A&2x%~aDkTI^h6RjH@kH`$Eef**&L9^nG|;djz*8(32C{O>GD%nagg z?YJ$Rxa8&^#z4jEGR)*Yk4rMP;^wppcSoS)q>M?o+jf!kNoD0(57hdZ&>_p!eYTY% zX<>3^ec_b9TplgY#;&;VoyG4*uTN|PchT$>vbKwc6z0+Q`ID&ah#zT^@;~rp=~53( zs1mGdXh}&VWtzn?V99ETgZaCxrt=5}0{m@Tv*SwRcH|XXk}a!5e^2ALx1h=53v(mU zr6IlV={iB%JhQnxsLzdq5G(*fS+=8eCU2t`nMW^?^j(Vu&K^~NWg79{>(9)FjH+nH z5VwMs49{V0XsTVlF{L|y(#awnjrWO zv0wQ7RtSY<Tgaz$cC_g*vDyqCtjhFYR%<+_Y2giI<3R!w6DHOU>(kLB7w7GML~lOPnslo8oj#s(#AFrn#z6fD5%c5p zfn<-erIC!EdHOa8SF{#wG>Zf`$1fwW{O|N056LdQXuj6qX7_<6&c3 zLh&mGP*gjgcHk$Knq!s9m8$il>C@XeM;254_)_ZY`$Z4jEl8RE1k5umuniU6_77Ik z%dYj$3c_MxP^62Y3LNd63IF(*m&(`clZY>1DTqFX?i^w=Q`c6-KH@Er+5*rin%$5D zwC$1<2Y62t6?vy@J^>;lb8C*Ew4cYJbz2XjY@SqSG#r@D{nA|rb=LBd??z`eB0mUhjVh7%KWCL=Kk)&5zNbAo~L2rf5nKgLUZWaa_ z{HYl>yL9~SDcA)Y!DB}J^DdAzgWZ_W`Cu(TcKi)zQ}s z&~Z!Azi36@89Q;GNWf$rIHN&+0t{VROWOKI&%;+Bw7!bX!MFqS=odP$lvN-kzA^PN&&3nP zTWL<^CFQ9v<7o8J=a)qhp5mGXTu~Fk`#tCQF+m6?Sa0|N`U&{*p_XQ9y~sP&=n0S? znKe*hj7eX{Qy%8?^PlrPaDW6e&t*+r8_kf#8%Quy(4Fl>kmGUtJ~LBRQL3-X`>rmt z=p*B)12rZXnf(3pcceT%*!6ClA?~p~)49Tm>jYg_9lQM&&Ad}673yRrbo=!BOj4v; z+W{-VT!~AtS7ARN=@_b#|IK#QZ$E@T&?F6$E}~=3dA6T@3&iD#kXd_{>0VKX-nXSY zh=}RUL_S%(l9YHjjp*`6I$&5e{kv=$nO4(P%PYe*DyB0fGCX-^jnny~5LRF@F69Rw zv=^Ghp*31txF{iTg~9CBI=g?D5h}W5TP2rkNuQYvz;=zEgN0V%D^OTByT|R0R0tzx zeGJ+~^bj{ai8z;(lAWVxHoG|vh}ab>_9-vpm-Xfz{P4-UrYAJ|_(d;VAk`$U>Z>`) z!`^adtw&`pT<2WRxymW(q`W$P9F6|C@iA7yQ%asrj~L)N0=`*h0T0rZmRD9p_$#CL z>IZgLlZiKck5MH&i@(<+HHa+s5NTEH4dpzoW_-Q}$8K&Yw=heWZ0xDte1{UN?5{|d zX(1w!ESm+Bn*<67&kjW+5+(a+r(`i}jB7!jQ?wiWk(dhiSn&Rbx(XJ!V2S%rdy-a&lS`FrD2^xW ztt)*yd{pLjpagnCWqdG!#C_lfET>EDW(VO=oobd^5bqXFd%)rg?^t>VwIzZpOz`+y zZ5gcV3U{tz1BV!>7w}p9zD1)+(1)>RjnP2!NuBmIJscGuT53zy?36 zcrDzV*m@-MS5y}FCZ)_ts*g7Pwd*Kw#ncRt1^;HV@-HXNL{HPAH$w~}`ss7SmJW@5 zG7A-cgpobWNy{PNzV9p%Lx8V`lI7P}u0!|Q2H)h`$eU1hzUIYXOj}uOMm_bAcA?`END>8x?kVwHKD zM&_F$teS)1t-R>dAV{hzPb5hQjo&T?UFz;HF_5<%jUmt<`^xFvR7&>;Dh*u*)r>a- z&@xJ$7Nk;`h^C3ru;PJJ;r+o2Wj<7jKPM0$Oly4u(QdhDXBe%g`5b0(6#BUd>KqY^RLg~CgMavK zt)n>E#!y}8C^hFBHW(ykpN8y$U7EDN(3-1OQ%HF`N2@}^mFNDLXJCp;ai`(I~HYG_7_XH9d~+ z?H&FAR`LIkmte`Tz$`vdrcup3lx|7pfpfqm$!~F!DAeU!;Io}MuJYa1d9|6kgn=yq zo&CX9GSj9klM<^jm(i_&4_=m#fm|)_OhzkQH73sVNUh+;2S*yRt6ZIj?OiBdv&k|n zCxY?XRvHG+MDvZXE`PyNr@C1a2rTU#VD0z?OQ}QUc_6SfK1|_9;q+vsd}Rxwxl2`8 zylJN+6d`ObJF~(T*{Ng>I^BtD8AbPMT7))wU1ZnPMVcX-TagOJc42g}jzHAFMkY8? zY)U3t_;qpfa$T@$8}=@@4(EFut6EtIrjGcenXQrqMnBr*LrdpDMZ1W70_w7FbdTFk z`noGwAyPy`p1)E-m1a$T<8Lj3u@JGdWEG+iQUr@P{s}Ec&X*313F_rMu^HsTH$Ths zc8eyBvL5)U_rJp1riFIK?tH8nZb`)x)p;C67AK_5;dio zZ?U-`D%xv9Gs85z??Xq*sdk;15geSr`W9Viyewsp6we9_2NWrWXc_G6N_q>a#GR!H zimq}ICq(C`2gRzSX7c2X)#O$eM)ya5Or&8!dr$rrS<6-%>4bW*iC@?2>y`JF6k~d# z?g(xp`G;?CefvbOH`?}k_f|gr@60Zma-k}!hewlXv5Yr@c zZ*zTzuB4NK4xS~Q_Pkts)p+|w{Y~Mm5Oq(d^Rj10d|`^}&n${M-JjSj+jR{PTDFDE zGKkc?=gUPERJ!h0V`C5W4S|y)SG#XdK;eUWe@5O}xn-RV)Au+sRe^3#+@RxWOStU6 z$=GNkNq57Gptlf~xT|_$;35dQF);su3}yQ!s=3P(+ik@4w7ndg=i6TBkeIYP_SmdV z(qP1SDGZnWNJCrhe6KP;rxY_?5H%_rJk#`_%!QF4^Zrfbwg0vouk$|$3Vy5bL%x^O z=ObVF3gVq!Z9%5fCDvS8o&CKinE~77(VLgG0XNgjgnofE3Fg#~YLe`oj(tH~7JqVg zjJLiBDivxMRjd1qAJN$tGRU?e3_B_Z^TcE9Ci@ugbp6}L0df_;uD9i%*adH`LKu8c z3w*8D&#H)n1dlu1yaS|MI$QdeQ!aM;P5#XV{Xi;NJ!a|_4_$OK`|k+kuEHzomOGyS z@e}SOQE=en=gaOvhw`geku}IS&Ne3O3rkGlg=rNz*s&tEcaBeh9b^eT*3;e2wykAc z3O!WR&eg8DLUcltAyC{&HL{Dw$il%nf0oSL~cz zrApa+`uVSFHN>&WWJJhCf~DapVTdSSFuc3ut?G9b;p%Eb^Ng49Owo>N8$z^m!+t9GFa;_>@5uGp8(rS$oCc2L^`<(u z9y?^ZWSmhZn?L@NdUbI8*Ecr>GgYGsG-F!zsQvPxW@OMiht<^a^CU?J8n`A6I^+NZ zU-6)iFeR(S*^b0TlQjbI*~2Ujct(xBHT7#)YJLnTyF>HtIK3xQsdG`_U_!8#v`Wp&KTfyocy{gJUeYLAkE>jBf!ngphgH`*>(_ zACWTD7IjH*xH<35G+)}FG1%S1m->Ne*0xf=LT0mZX&X-a4(gifs{-$Uk|V(V9MO(|ogKK$Ymvt*a%TBSP9 zsWYxiqncaDdl5~5OUVO4 z$51{{p0{L|fmt6;+1pqi3pe&JdXKRS6@@$(`W?vxSP2nSQWP#^b8nm8afu`PyXK&O zO>aNO_1@PtaP?Pw%^uiLQ_kZbh=r!{Z4p3R-FHySwkAf&0eKLXFWz74*=VZ>9Nio(<(NoLT+uto&GVjhRzt(#5 z^yXu}y909&eO-}B&fyf-5o;3xVbNqt#r)xcuG+4-!UyG=l;0Cg1+)Y4Zz%9K`GbcJ zv9(T#-?l8@txhFRn2z7sL4;E220!CzTv&dthqyV;nj8ZMWZI1#R|U0fl`qip-I$q( zt3j(I%AQZa-Pk2Rds~5Cx%VTRtn>Y7hA;l0y_A9l=?_m`klgUuSN;**s~+2lktWf} zq>HgwEymWLB9^gOpC=OKD@^M;p<%7Yk)|zA->Bc2m#HyMs~-gKtNk|MWc|t{zL1pw zb~I5R7@Rv($4w8y;G=9bb<(yer8&M2vpca!%U$R%^JFq#4wM67NYXF?Umce~{qo~c=y5seijy3sz&Q-nP zzhdm!Si|5jm?x)sEtZiVL(%bOy*MJ-{IkTkrI12jb^pLFoRk#;rTro+20776;mmztLJZ?4rR`zofEK&D+$G* z_cv9N+dzBtkl$oKE@s(_MGW_oXn#Sm8SogtuI??ZqLXcyWF%kbh@ESsM+GvLvZE*p zwd9KE3<3WIl4%5Hgo+Sbqvg%(?HjmBx$Fw*wrJ@_YH;-p)ON^or!Mz$G(i%`Z&$ed zG?!x5X%f^8yE zQBTXAQ<~d^2LrLc=lyoXaQ?fB?m)FP6!QMGt>V&I_awLSR*elBn|kV=N&?}a(FQ46 z22zT!k4%Jk@WQdsC#-L#=l>-HAda6q(=80!k=P2J350#hU&Tv097m_`o7uY2JS^(AE&vzLVvgp;&}z#kt4ZMVh0FZLzE+mXPNnlT z!>O0bh6mYpO|B|flc4F0gAqQo)P?uqWf)%&s8vz&nZ~pg#eJTwp@+(A6!L2q2q}94 zb@90ch&~!w*%;En{L<9?srJe7xuV^)R`Trf)(yp$_L_=P=MYUUk6H%qH-*%AhF4^0ys1Mwzd)Ph%LkKq4T_KbryH5(pF048|Dyq3JRx^*2`;B8=#7p zf~AExV8h#QRx>)REEIpl<(qS2F-ob*2qPd;%ls&BR1p_dbW5B^IsI4irzGq&7_CVH z^Wbn7mo7!PNf=hCrP!KEutB73^Wu1}ZuJVH*7oFRN9D*H;T>_xqP&p^)R*@faqaaAW8mt;5QKcu(ZA|F2vd%k z0K#ECdly{Q*4X5Q+&PfcWaBhOe(Y%b$vAbHd|7=_L>W1590%G8$QFhK26)&x7nIX9uUPw<@D?PFyVafn zj+2ETNq|hltgJ1K7c0s!ioZ9&r26u-b1%Qt?7WmMP3;s%i`L57CuMakGA+c{P>-gY z=w15#w%fXITijj*jR;6zJqfwSSvGz$gq?;dZrY|f>jf5FQ&&|e! zq{p`V#26T(Pk;^c8c7<@kN+rM-2zu_h?|diWXpdH$joWeE!2mbMgo_5n}lf+hbsk2 zAb>r9-9?oRaU-<$vU1#6Gv~2%Q z9BD=uhTZ#4cZ-^IZ1U7^P&S-NqSA?Q7Ea{vFfm+wV? zc*r>aU2)xyW`Ty3+ACdhrfX{VcbIZdK*|%qJaPV%Ho?qbmgDmqd|9{_BXwx4-{uc!NPzr7D2yB;+jt>e zlxM`uh5$usLu`0SGeSV)H%FJ5Nn18vL@yejul7|*O&p6%$T2o4HhmPmm9|p0`H%A) z|Br)RHl#vp9;db|9wHY1@}FduAbQW7dN%>S~*=S3TDWpANFMQBo0^n^k6A z0()Kd!q=>JtGDQFH8FATlz{Rlk~CQ|{YXoojOvKBtFe6yr3rdx{v%MK=@E~gEk7q2 z^VY;^`!8WC^eCYveb@VI{#DNYdF*1zyk!H#5=sK!q>(R=73g4;(3gX=!9^Vd90 z4a1PDU0XyzFE=<_9x`uujyY`3yCJZSdZdWPLu!`~|8)iQmm^y9kY8CoP4d2}`7lrT z5@+pH@6GMFM(O+!TL-rH0tqi?^*^aC8;R1f+w2PWo{RU|2<5m}>TjA=R-?=^siw4o z$hW<+D2>68Ekq0qpc5IG!UI%xG5v<@-(~jfc9HgwN;S0<{m==-t=jaibz0>$SZf(pJ&DPOQ1gZ3SrUa3atBJ1YbQH;GR#EYN)UKKN_qxJb{OOm0+b7o;^ z>JXj!gUkQT8`|m;a^hSA@vLQ@MeyuBtZj=P(`-s}Og<!foQEPYD(A_GcokyEFn zT0h@#(GB>fLZH*mf+8b=35&ZA>$bKu`l4D8^D5S)^0{K9-syv?Yq{wDGG#owwla~Q z1n$kiC`QEcyq^bS@vL6;-~h-|W1guRbGhXEcJyFSXH(4B-wf8la2HSDlm9{^X%vz4 z{7KB_=N8E>dD&w7!afZLfu6B1Um2`kks`n=`K5>O%h`vO3n3mI;v@M zZcr4A)#j%i{U?nY5t>bRB;&2`BzjBLNVSyvaPD&IUCCPMN_C7$akHG~0HtiihmE7z z$b9YH_jrk|*O#%@Hu3~~3VztNR31}xuCl7SqA|jM^*nlCHP5fhqp_!lO%muKuGHo{ z2$=N9ALAWKy%73j-?W%}-$#?&R)q1hR~>(%txm3+xm0dIZgOEtgO~nG{hW$4Z$P?@ zqX8?2fmu&@<|-xe_a1+RhboWP8iNgy$1abTPRU{B9FGeq$sEzvU__@5GK_;WHy14x zcDwh%F)#&T8!n+HR*b17<9kEKj@QaV)cerrgBrU^YNWZUt8{6hh=Tbf?4|DbGS-u! z3Sxb;5_Nt{7Lb!ZPYHe=Y8XHk>h)UqkL^m`A@p`}ve`+@bxE5|Cs@<9Wo{2YJxv@D z9dCggGXgg~vVFp|gOx~_Ty1Jj5)-0RzImmr#x9y|jOhSEB7QF;#P+qj&`v*C%|s0Q z$?%luf|Mi-j(@=IKm857&fyXodmv&qtfCK#3O5t3lq+~s%fV<$ zRS-cl7ak85UYRl{gPI`aNl4*v$9b<&iIKg5qc~XNq*fo*t-~&I8?tBw+pco@U6>j% zSXEdK8e9Ui84jcO-8grAmtb-)|EFQRwl_-;yZ1NLKTpl*^Gls4O2#=4#vLj5jW2m( zv*A0D(ahmmg2`qipL@cc|7D4hjoF3__X~`o5Rt{7kGxUzd{v0u{FuF}VUVwCf0d9h z^tM38c*$I%5Awj}a|lVgz=uHUYqE|E?$0`hF<3fb7!iChutxv|hkyF*I5JB8%LF4( zwMZ_bT_4`}^-PSm?OBb)Y&`+hmqf5=B5bT7C)lxV7$ zSdd3Re)}sR94(?v$*U#FE)u?q8o}^a7Y-z}`lB@vE*61Wf>rOOqQ}p4{nh9VUqsbH zZ!eRW #include "core/task/include/task.hpp" -#include "example_threads/common/include/common.hpp" +#include "example_processes/common/include/common.hpp" -namespace nesterov_a_test_task { +namespace nesterov_a_test_task_processes { class NesterovATestTaskMPI : public BaseTask { public: @@ -17,4 +17,4 @@ class NesterovATestTaskMPI : public BaseTask { bool PostProcessingImpl() override; }; -} // namespace nesterov_a_test_task +} // namespace nesterov_a_test_task_processes diff --git a/tasks/example_threads/mpi/src/ops_mpi.cpp b/tasks/example_processes/mpi/src/ops_mpi.cpp similarity index 89% rename from tasks/example_threads/mpi/src/ops_mpi.cpp rename to tasks/example_processes/mpi/src/ops_mpi.cpp index 80ef31245..c9c6c4705 100644 --- a/tasks/example_threads/mpi/src/ops_mpi.cpp +++ b/tasks/example_processes/mpi/src/ops_mpi.cpp @@ -1,4 +1,4 @@ -#include "example_threads/mpi/include/ops_mpi.hpp" +#include "example_processes/mpi/include/ops_mpi.hpp" #include @@ -6,7 +6,7 @@ #include #include -namespace nesterov_a_test_task { +namespace nesterov_a_test_task_processes { NesterovATestTaskMPI::NesterovATestTaskMPI(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); @@ -57,4 +57,4 @@ bool NesterovATestTaskMPI::PostProcessingImpl() { return GetOutput() > 0; } -} // namespace nesterov_a_test_task +} // namespace nesterov_a_test_task_processes diff --git a/tasks/example_processes/seq/include/ops_seq.hpp b/tasks/example_processes/seq/include/ops_seq.hpp new file mode 100644 index 000000000..01f0792b0 --- /dev/null +++ b/tasks/example_processes/seq/include/ops_seq.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +#include "core/task/include/task.hpp" +#include "example_processes/common/include/common.hpp" + +namespace nesterov_a_test_task_processes { + +class NesterovATestTaskSEQ : public BaseTask { + public: + static constexpr ppc::core::TypeOfTask GetStaticTypeOfTask() { return ppc::core::TypeOfTask::kSEQ; } + explicit NesterovATestTaskSEQ(const InType& in); + bool ValidationImpl() override; + bool PreProcessingImpl() override; + bool RunImpl() override; + bool PostProcessingImpl() override; +}; + +} // namespace nesterov_a_test_task_processes diff --git a/tasks/example_processes/seq/src/ops_seq.cpp b/tasks/example_processes/seq/src/ops_seq.cpp new file mode 100644 index 000000000..53f96e51a --- /dev/null +++ b/tasks/example_processes/seq/src/ops_seq.cpp @@ -0,0 +1,50 @@ +#include "example_processes/seq/include/ops_seq.hpp" + +#include +#include +#include + +namespace nesterov_a_test_task_processes { + +NesterovATestTaskSEQ::NesterovATestTaskSEQ(const InType& in) { + SetTypeOfTask(GetStaticTypeOfTask()); + GetInput() = in; + GetOutput() = 0; +} + +bool NesterovATestTaskSEQ::ValidationImpl() { return (GetInput() > 0) && (GetOutput() == 0); } + +bool NesterovATestTaskSEQ::PreProcessingImpl() { + GetOutput() = 2 * GetInput(); + return GetOutput() > 0; +} + +bool NesterovATestTaskSEQ::RunImpl() { + for (InType i = 0; i < GetInput(); i++) { + for (InType j = 0; j < GetInput(); j++) { + for (InType k = 0; k < GetInput(); k++) { + std::vector tmp(i + j + k, 1); + GetOutput() += std::accumulate(tmp.begin(), tmp.end(), 0); + GetOutput() -= i + j + k; + } + } + } + + const int num_threads = ppc::util::GetNumThreads(); + GetOutput() *= num_threads; + + int counter = 0; + for (int i = 0; i < num_threads; i++) { + counter++; + } + + GetOutput() /= counter; + return GetOutput() > 0; +} + +bool NesterovATestTaskSEQ::PostProcessingImpl() { + GetOutput() -= GetInput(); + return GetOutput() > 0; +} + +} // namespace nesterov_a_test_task_processes diff --git a/tasks/example_processes/settings.json b/tasks/example_processes/settings.json new file mode 100644 index 000000000..8094719ab --- /dev/null +++ b/tasks/example_processes/settings.json @@ -0,0 +1,11 @@ +{ + "tasks_type": "processes", + "tasks": { + "mpi": "enabled", + "seq": "enabled" + }, + "plagiarism": { + "mpi": "original", + "seq": "original" + } +} diff --git a/tasks/example_processes/tests/functional/main.cpp b/tasks/example_processes/tests/functional/main.cpp new file mode 100644 index 000000000..0cfa5655a --- /dev/null +++ b/tasks/example_processes/tests/functional/main.cpp @@ -0,0 +1,72 @@ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "core/util/include/func_test_util.hpp" +#include "core/util/include/util.hpp" +#include "example_processes/mpi/include/ops_mpi.hpp" +#include "example_processes/seq/include/ops_seq.hpp" + +namespace nesterov_a_test_task_processes { + +class NesterovARunFuncTestsProcesses : public ppc::util::BaseRunFuncTests { + public: + static std::string PrintTestParam(const TestType &test_param) { + return std::to_string(std::get<0>(test_param)) + "_" + std::get<1>(test_param); + } + + protected: + void SetUp() override { + int width = -1; + int height = -1; + int channels = -1; + std::vector img; + // Read image + { + std::string abs_path = ppc::util::GetAbsoluteTaskPath(PPC_ID_example_processes, "pic.jpg"); + auto *data = stbi_load(abs_path.c_str(), &width, &height, &channels, 0); + if (data == nullptr) { + throw std::runtime_error("Failed to load image: " + std::string(stbi_failure_reason())); + } + img = std::vector(data, data + (static_cast(width * height * channels))); + stbi_image_free(data); + if (std::cmp_not_equal(width, height)) { + throw std::runtime_error("width != height: "); + } + } + + TestType params = std::get(GetParam()); + input_data_ = width - height + std::min(std::accumulate(img.begin(), img.end(), 0), channels); + } + + bool CheckTestOutputData(OutType &output_data) final { return (input_data_ == output_data); } + + InType GetTestInputData() final { return input_data_; } + + private: + InType input_data_ = 0; +}; + +namespace { + +TEST_P(NesterovARunFuncTestsProcesses, MatmulFromPic) { ExecuteTest(GetParam()); } + +const std::array kTestParam = {std::make_tuple(3, "3"), std::make_tuple(5, "5"), std::make_tuple(7, "7")}; + +INIT_FUNC_TASK_GENERATOR(InType, kTestParam, PPC_SETTINGS_example_threads) + +const auto kTestTasksList = std::tuple_cat(ADD_FUNC_TASK(NesterovATestTaskMPI), ADD_FUNC_TASK(NesterovATestTaskSEQ)); + +INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTestsProcesses, + ppc::util::ExpandToValues(kTestTasksList), + NesterovARunFuncTestsProcesses::PrintFuncTestName); + +} // namespace + +} // namespace nesterov_a_test_task_processes diff --git a/tasks/example_processes/tests/performance/main.cpp b/tasks/example_processes/tests/performance/main.cpp new file mode 100644 index 000000000..bd6c585a6 --- /dev/null +++ b/tasks/example_processes/tests/performance/main.cpp @@ -0,0 +1,40 @@ +#include +#include + +#include +#include +#include +#include +#include + +#include "core/perf/include/perf.hpp" +#include "core/util/include/perf_test_util.hpp" +#include "core/util/include/util.hpp" +#include "example_processes/mpi/include/ops_mpi.hpp" +#include "example_processes/seq/include/ops_seq.hpp" + +namespace nesterov_a_test_task_processes { + +class ExampleRunPerfTestProcesses : public ppc::util::BaseRunPerfTests { + const int kCount_ = 111; + InType input_data_{}; + + void SetUp() override { input_data_ = kCount_; } + + bool CheckTestOutputData(OutType& output_data) final { return input_data_ == output_data; } + + InType GetTestInputData() final { return input_data_; } +}; + +INIT_PERF_TASK_GENERATOR(InType, PPC_SETTINGS_example_threads) + +using PerfTasks = perf_tasks_type_list; + +const auto kAllPerfTasks = std::tuple_cat(MakeTask(PerfTasks{})); + +TEST_P(ExampleRunPerfTestProcesses, RunPerfModes) { ExecuteTest(GetParam()); } + +INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, ExampleRunPerfTestProcesses, ppc::util::TupleToGTestValues(kAllPerfTasks), + ExampleRunPerfTestProcesses::CustomPerfTestName); + +} // namespace nesterov_a_test_task_processes diff --git a/tasks/example_threads/all/include/ops_all.hpp b/tasks/example_threads/all/include/ops_all.hpp index 7012c2353..c57011bb0 100644 --- a/tasks/example_threads/all/include/ops_all.hpp +++ b/tasks/example_threads/all/include/ops_all.hpp @@ -4,7 +4,7 @@ #include "example_threads/common/include/common.hpp" -namespace nesterov_a_test_task { +namespace nesterov_a_test_task_threads { class NesterovATestTaskALL : public BaseTask { public: @@ -16,4 +16,4 @@ class NesterovATestTaskALL : public BaseTask { bool PostProcessingImpl() override; }; -} // namespace nesterov_a_test_task +} // namespace nesterov_a_test_task_threads diff --git a/tasks/example_threads/all/src/ops_all.cpp b/tasks/example_threads/all/src/ops_all.cpp index 8e4cde071..438c00a28 100644 --- a/tasks/example_threads/all/src/ops_all.cpp +++ b/tasks/example_threads/all/src/ops_all.cpp @@ -12,7 +12,7 @@ #include "core/util/include/util.hpp" #include "oneapi/tbb/parallel_for.h" -namespace nesterov_a_test_task { +namespace nesterov_a_test_task_threads { NesterovATestTaskALL::NesterovATestTaskALL(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); @@ -81,4 +81,4 @@ bool NesterovATestTaskALL::PostProcessingImpl() { return GetOutput() > 0; } -} // namespace nesterov_a_test_task +} // namespace nesterov_a_test_task_threads diff --git a/tasks/example_threads/common/include/common.hpp b/tasks/example_threads/common/include/common.hpp index 5530796a8..fb94b3190 100644 --- a/tasks/example_threads/common/include/common.hpp +++ b/tasks/example_threads/common/include/common.hpp @@ -6,11 +6,11 @@ #include "core/task/include/task.hpp" #include "core/util/include/util.hpp" -namespace nesterov_a_test_task { +namespace nesterov_a_test_task_threads { using InType = int; using OutType = int; using TestType = std::tuple; using BaseTask = ppc::core::Task; -} // namespace nesterov_a_test_task +} // namespace nesterov_a_test_task_threads diff --git a/tasks/example_threads/info.json b/tasks/example_threads/info.json index a6abcae41..61f220253 100644 --- a/tasks/example_threads/info.json +++ b/tasks/example_threads/info.json @@ -3,7 +3,6 @@ "first_name": "Нестеров", "last_name": "Александр", "middle_name": "Юрьевич", - "group_number": "АБВ-123", - "tasks_type": "threads" + "group_number": "АБВ-123" } -} \ No newline at end of file +} diff --git a/tasks/example_threads/omp/include/ops_omp.hpp b/tasks/example_threads/omp/include/ops_omp.hpp index 7351d66b5..cfbe1c463 100644 --- a/tasks/example_threads/omp/include/ops_omp.hpp +++ b/tasks/example_threads/omp/include/ops_omp.hpp @@ -6,7 +6,7 @@ #include "core/task/include/task.hpp" #include "example_threads/common/include/common.hpp" -namespace nesterov_a_test_task { +namespace nesterov_a_test_task_threads { class NesterovATestTaskOMP : public BaseTask { public: @@ -18,4 +18,4 @@ class NesterovATestTaskOMP : public BaseTask { bool PostProcessingImpl() override; }; -} // namespace nesterov_a_test_task +} // namespace nesterov_a_test_task_threads diff --git a/tasks/example_threads/omp/src/ops_omp.cpp b/tasks/example_threads/omp/src/ops_omp.cpp index d454105c3..0cf4319f5 100644 --- a/tasks/example_threads/omp/src/ops_omp.cpp +++ b/tasks/example_threads/omp/src/ops_omp.cpp @@ -5,7 +5,7 @@ #include #include -namespace nesterov_a_test_task { +namespace nesterov_a_test_task_threads { NesterovATestTaskOMP::NesterovATestTaskOMP(const InType& in) { SetTypeOfTask(GetStaticTypeOfTask()); @@ -47,4 +47,4 @@ bool NesterovATestTaskOMP::PostProcessingImpl() { return GetOutput() > 0; } -} // namespace nesterov_a_test_task +} // namespace nesterov_a_test_task_threads diff --git a/tasks/example_threads/seq/include/ops_seq.hpp b/tasks/example_threads/seq/include/ops_seq.hpp index 2ddee637f..900df4ff4 100644 --- a/tasks/example_threads/seq/include/ops_seq.hpp +++ b/tasks/example_threads/seq/include/ops_seq.hpp @@ -6,7 +6,7 @@ #include "core/task/include/task.hpp" #include "example_threads/common/include/common.hpp" -namespace nesterov_a_test_task { +namespace nesterov_a_test_task_threads { class NesterovATestTaskSEQ : public BaseTask { public: @@ -18,4 +18,4 @@ class NesterovATestTaskSEQ : public BaseTask { bool PostProcessingImpl() override; }; -} // namespace nesterov_a_test_task +} // namespace nesterov_a_test_task_threads diff --git a/tasks/example_threads/seq/src/ops_seq.cpp b/tasks/example_threads/seq/src/ops_seq.cpp index 8ba19c4f9..5db1d7ad0 100644 --- a/tasks/example_threads/seq/src/ops_seq.cpp +++ b/tasks/example_threads/seq/src/ops_seq.cpp @@ -4,7 +4,7 @@ #include #include -namespace nesterov_a_test_task { +namespace nesterov_a_test_task_threads { NesterovATestTaskSEQ::NesterovATestTaskSEQ(const InType& in) { SetTypeOfTask(GetStaticTypeOfTask()); @@ -47,4 +47,4 @@ bool NesterovATestTaskSEQ::PostProcessingImpl() { return GetOutput() > 0; } -} // namespace nesterov_a_test_task +} // namespace nesterov_a_test_task_threads diff --git a/tasks/example_threads/settings.json b/tasks/example_threads/settings.json index aa6ac8d25..c9f530450 100644 --- a/tasks/example_threads/settings.json +++ b/tasks/example_threads/settings.json @@ -1,7 +1,7 @@ { + "tasks_type": "threads", "tasks": { "all": "enabled", - "mpi": "enabled", "omp": "enabled", "seq": "enabled", "stl": "enabled", @@ -9,10 +9,9 @@ }, "plagiarism": { "all": "original", - "mpi": "original", "omp": "plagiarized", "seq": "original", "stl": "original", "tbb": "original" } -} \ No newline at end of file +} diff --git a/tasks/example_threads/stl/include/ops_stl.hpp b/tasks/example_threads/stl/include/ops_stl.hpp index f1c2970a4..05bb6eab7 100644 --- a/tasks/example_threads/stl/include/ops_stl.hpp +++ b/tasks/example_threads/stl/include/ops_stl.hpp @@ -6,7 +6,7 @@ #include "core/task/include/task.hpp" #include "example_threads/common/include/common.hpp" -namespace nesterov_a_test_task { +namespace nesterov_a_test_task_threads { class NesterovATestTaskSTL : public BaseTask { public: @@ -18,4 +18,4 @@ class NesterovATestTaskSTL : public BaseTask { bool PostProcessingImpl() override; }; -} // namespace nesterov_a_test_task +} // namespace nesterov_a_test_task_threads diff --git a/tasks/example_threads/stl/src/ops_stl.cpp b/tasks/example_threads/stl/src/ops_stl.cpp index 35c91ee01..c53c37835 100644 --- a/tasks/example_threads/stl/src/ops_stl.cpp +++ b/tasks/example_threads/stl/src/ops_stl.cpp @@ -9,7 +9,7 @@ #include "core/util/include/util.hpp" -namespace nesterov_a_test_task { +namespace nesterov_a_test_task_threads { NesterovATestTaskSTL::NesterovATestTaskSTL(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); @@ -54,4 +54,4 @@ bool NesterovATestTaskSTL::PostProcessingImpl() { return GetOutput() > 0; } -} // namespace nesterov_a_test_task +} // namespace nesterov_a_test_task_threads diff --git a/tasks/example_threads/tbb/include/ops_tbb.hpp b/tasks/example_threads/tbb/include/ops_tbb.hpp index 389f497f6..d10256d17 100644 --- a/tasks/example_threads/tbb/include/ops_tbb.hpp +++ b/tasks/example_threads/tbb/include/ops_tbb.hpp @@ -6,7 +6,7 @@ #include "core/task/include/task.hpp" #include "example_threads/common/include/common.hpp" -namespace nesterov_a_test_task { +namespace nesterov_a_test_task_threads { class NesterovATestTaskTBB : public BaseTask { public: @@ -18,4 +18,4 @@ class NesterovATestTaskTBB : public BaseTask { bool PostProcessingImpl() override; }; -} // namespace nesterov_a_test_task +} // namespace nesterov_a_test_task_threads diff --git a/tasks/example_threads/tbb/src/ops_tbb.cpp b/tasks/example_threads/tbb/src/ops_tbb.cpp index cf39a1e74..5f426f283 100644 --- a/tasks/example_threads/tbb/src/ops_tbb.cpp +++ b/tasks/example_threads/tbb/src/ops_tbb.cpp @@ -10,7 +10,7 @@ #include "oneapi/tbb/parallel_for.h" -namespace nesterov_a_test_task { +namespace nesterov_a_test_task_threads { NesterovATestTaskTBB::NesterovATestTaskTBB(const InType &in) { SetTypeOfTask(GetStaticTypeOfTask()); @@ -51,4 +51,4 @@ bool NesterovATestTaskTBB::PostProcessingImpl() { return GetOutput() > 0; } -} // namespace nesterov_a_test_task +} // namespace nesterov_a_test_task_threads diff --git a/tasks/example_threads/tests/functional/main.cpp b/tasks/example_threads/tests/functional/main.cpp index 3576e1914..e4c4cd811 100644 --- a/tasks/example_threads/tests/functional/main.cpp +++ b/tasks/example_threads/tests/functional/main.cpp @@ -11,15 +11,14 @@ #include "core/util/include/func_test_util.hpp" #include "core/util/include/util.hpp" #include "example_threads/all/include/ops_all.hpp" -#include "example_threads/mpi/include/ops_mpi.hpp" #include "example_threads/omp/include/ops_omp.hpp" #include "example_threads/seq/include/ops_seq.hpp" #include "example_threads/stl/include/ops_stl.hpp" #include "example_threads/tbb/include/ops_tbb.hpp" -namespace nesterov_a_test_task { +namespace nesterov_a_test_task_threads { -class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests { +class NesterovARunFuncTestsThreads : public ppc::util::BaseRunFuncTests { public: static std::string PrintTestParam(const TestType &test_param) { return std::to_string(std::get<0>(test_param)) + "_" + std::get<1>(test_param); @@ -33,7 +32,7 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests img; // Read image { - std::string abs_path = ppc::util::GetAbsolutePath("example_threads/data/pic.jpg"); + std::string abs_path = ppc::util::GetAbsoluteTaskPath(std::string(PPC_ID_example_threads), "pic.jpg"); auto *data = stbi_load(abs_path.c_str(), &width, &height, &channels, 0); if (data == nullptr) { throw std::runtime_error("Failed to load image: " + std::string(stbi_failure_reason())); @@ -59,19 +58,19 @@ class NesterovARunFuncTests : public ppc::util::BaseRunFuncTests kTestParam = {std::make_tuple(3, "3"), std::make_tuple(5, "5"), std::make_tuple(7, "7")}; INIT_FUNC_TASK_GENERATOR(InType, kTestParam, PPC_SETTINGS_example_threads) -const auto kTestTasksList = std::tuple_cat(ADD_FUNC_TASK(NesterovATestTaskALL), ADD_FUNC_TASK(NesterovATestTaskMPI), - ADD_FUNC_TASK(NesterovATestTaskOMP), ADD_FUNC_TASK(NesterovATestTaskSEQ), - ADD_FUNC_TASK(NesterovATestTaskSTL), ADD_FUNC_TASK(NesterovATestTaskTBB)); +const auto kTestTasksList = std::tuple_cat(ADD_FUNC_TASK(NesterovATestTaskALL), ADD_FUNC_TASK(NesterovATestTaskOMP), + ADD_FUNC_TASK(NesterovATestTaskSEQ), ADD_FUNC_TASK(NesterovATestTaskSTL), + ADD_FUNC_TASK(NesterovATestTaskTBB)); -INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTests, ppc::util::ExpandToValues(kTestTasksList), - NesterovARunFuncTests::PrintFuncTestName); +INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTestsThreads, ppc::util::ExpandToValues(kTestTasksList), + NesterovARunFuncTestsThreads::PrintFuncTestName); } // namespace -} // namespace nesterov_a_test_task +} // namespace nesterov_a_test_task_threads diff --git a/tasks/example_threads/tests/performance/main.cpp b/tasks/example_threads/tests/performance/main.cpp index 385d9b924..c1219989d 100644 --- a/tasks/example_threads/tests/performance/main.cpp +++ b/tasks/example_threads/tests/performance/main.cpp @@ -11,15 +11,14 @@ #include "core/util/include/perf_test_util.hpp" #include "core/util/include/util.hpp" #include "example_threads/all/include/ops_all.hpp" -#include "example_threads/mpi/include/ops_mpi.hpp" #include "example_threads/omp/include/ops_omp.hpp" #include "example_threads/seq/include/ops_seq.hpp" #include "example_threads/stl/include/ops_stl.hpp" #include "example_threads/tbb/include/ops_tbb.hpp" -namespace nesterov_a_test_task { +namespace nesterov_a_test_task_threads { -class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { +class ExampleRunPerfTestThreads : public ppc::util::BaseRunPerfTests { const int kCount_ = 111; InType input_data_{}; @@ -32,14 +31,14 @@ class ExampleRunPerfTest : public ppc::util::BaseRunPerfTests { INIT_PERF_TASK_GENERATOR(InType, PPC_SETTINGS_example_threads) -using PerfTasks = perf_tasks_type_list; +using PerfTasks = perf_tasks_type_list; const auto kAllPerfTasks = std::tuple_cat(MakeTask(PerfTasks{})); -TEST_P(ExampleRunPerfTest, RunPerfModes) { ExecuteTest(GetParam()); } +TEST_P(ExampleRunPerfTestThreads, RunPerfModes) { ExecuteTest(GetParam()); } -INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, ExampleRunPerfTest, ppc::util::TupleToGTestValues(kAllPerfTasks), - ExampleRunPerfTest::CustomPerfTestName); +INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, ExampleRunPerfTestThreads, ppc::util::TupleToGTestValues(kAllPerfTasks), + ExampleRunPerfTestThreads::CustomPerfTestName); -} // namespace nesterov_a_test_task +} // namespace nesterov_a_test_task_threads From 5403c4049f108d65f975d03527badf2869d9bbef Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 16:37:01 +0200 Subject: [PATCH 084/141] Switch performance and functional tests in `example_processes` to use `PPC_SETTINGS_example_processes` --- tasks/example_processes/tests/functional/main.cpp | 2 +- tasks/example_processes/tests/performance/main.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/example_processes/tests/functional/main.cpp b/tasks/example_processes/tests/functional/main.cpp index 0cfa5655a..2ed69b457 100644 --- a/tasks/example_processes/tests/functional/main.cpp +++ b/tasks/example_processes/tests/functional/main.cpp @@ -59,7 +59,7 @@ TEST_P(NesterovARunFuncTestsProcesses, MatmulFromPic) { ExecuteTest(GetParam()); const std::array kTestParam = {std::make_tuple(3, "3"), std::make_tuple(5, "5"), std::make_tuple(7, "7")}; -INIT_FUNC_TASK_GENERATOR(InType, kTestParam, PPC_SETTINGS_example_threads) +INIT_FUNC_TASK_GENERATOR(InType, kTestParam, PPC_SETTINGS_example_processes) const auto kTestTasksList = std::tuple_cat(ADD_FUNC_TASK(NesterovATestTaskMPI), ADD_FUNC_TASK(NesterovATestTaskSEQ)); diff --git a/tasks/example_processes/tests/performance/main.cpp b/tasks/example_processes/tests/performance/main.cpp index bd6c585a6..2d4d34f6b 100644 --- a/tasks/example_processes/tests/performance/main.cpp +++ b/tasks/example_processes/tests/performance/main.cpp @@ -26,7 +26,7 @@ class ExampleRunPerfTestProcesses : public ppc::util::BaseRunPerfTests; From f45801ac57dd8a4a2a6c74d70b658f82e9cad2bc Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 17:00:11 +0200 Subject: [PATCH 085/141] Update CMake to link `fmtd` in Debug mode on non-MSVC builds --- modules/core/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index 119054344..b943fb7bb 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -29,7 +29,11 @@ target_link_directories(${exec_func_lib} PUBLIC "${CMAKE_BINARY_DIR}/ppc_libenvp if(MSVC) target_link_libraries(${exec_func_lib} PUBLIC fmt libenvpp) else() - target_link_libraries(${exec_func_lib} PUBLIC fmt envpp) + if(CMAKE_BUILD_TYPE STREQUAL "Debug") + target_link_libraries(${exec_func_lib} PUBLIC fmtd envpp) + else() + target_link_libraries(${exec_func_lib} PUBLIC fmt envpp) + endif() endif () add_dependencies(${exec_func_lib} ppc_json) From f5aca530635d65cb10d97c9cefef0db265383f10 Mon Sep 17 00:00:00 2001 From: anesterov Date: Sun, 8 Jun 2025 17:11:35 +0200 Subject: [PATCH 086/141] Refactor `CMakeLists.txt` to simplify `target_link_libraries` logic and improve readability. --- modules/core/CMakeLists.txt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index b943fb7bb..b5ddbea93 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -26,16 +26,19 @@ set_target_properties(${exec_func_lib} PROPERTIES LINKER_LANGUAGE CXX) add_dependencies(${exec_func_lib} ppc_libenvpp) target_link_directories(${exec_func_lib} PUBLIC "${CMAKE_BINARY_DIR}/ppc_libenvpp/install/lib") target_link_directories(${exec_func_lib} PUBLIC "${CMAKE_BINARY_DIR}/ppc_libenvpp/build") + if(MSVC) - target_link_libraries(${exec_func_lib} PUBLIC fmt libenvpp) + target_link_libraries(${exec_func_lib} PUBLIC libenvpp) else() - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - target_link_libraries(${exec_func_lib} PUBLIC fmtd envpp) - else() - target_link_libraries(${exec_func_lib} PUBLIC fmt envpp) - endif() + target_link_libraries(${exec_func_lib} PUBLIC envpp) endif () +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + target_link_libraries(${exec_func_lib} PUBLIC fmtd) +else() + target_link_libraries(${exec_func_lib} PUBLIC fmt) +endif() + add_dependencies(${exec_func_lib} ppc_json) target_link_directories(${exec_func_lib} INTERFACE "${CMAKE_BINARY_DIR}/ppc_json/install/include") From 38168980911f4990c285dbc1d341e4565abea65a Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 17:43:30 +0200 Subject: [PATCH 087/141] Switch `ubuntu-gcc-build-codecov` to Ninja and comment out `needs` dependencies in GitHub workflow file --- .github/workflows/main.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7fe0e1f56..ce4c77dc7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -978,9 +978,9 @@ jobs: PPC_NUM_THREADS: 13 ubuntu-gcc-build-codecov: needs: - - ubuntu-gcc-test-extended - - ubuntu-clang-test-extended - - macos-clang-test-extended +# - ubuntu-gcc-test-extended +# - ubuntu-clang-test-extended +# - macos-clang-test-extended runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 @@ -999,7 +999,7 @@ jobs: max-size: 1G - name: CMake configure run: > - cmake -S . -B build + cmake -S . -B build -GNinja -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_VERBOSE_MAKEFILE=ON -D USE_COVERAGE=ON From a4d58a11d2123b4e0731c5960db4fd37841b0c51 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 17:55:23 +0200 Subject: [PATCH 088/141] Expand GitHub Actions triggers and uncomment `needs` dependencies in workflows --- .github/workflows/main.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 495d59535..20b6a3bd2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -977,10 +977,10 @@ jobs: PPC_NUM_PROC: 1 PPC_NUM_THREADS: 13 ubuntu-gcc-build-codecov: -# needs: -# - ubuntu-gcc-test-extended -# - ubuntu-clang-test-extended -# - macos-clang-test-extended + needs: + - ubuntu-gcc-test-extended + - ubuntu-clang-test-extended + - macos-clang-test-extended runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 From 48fd9d92b4e088a2a51b4c26ddd48e1ad2917ae0 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 19:21:21 +0200 Subject: [PATCH 089/141] Refactor imports and update JSON pointer initialization across multiple modules and tasks Standardized header imports, removed unused includes, and introduced a shared JSON pointer initialization method (`InitJSONPtr`) for improved code reusability. Adjusted related logic in task handling for consistency and robustness. --- 3rdparty/stb_image_wrapper.cpp | 2 + modules/core/perf/func_tests/perf_tests.cpp | 1 + modules/core/perf/include/perf.hpp | 7 +- modules/core/task/include/task.hpp | 11 +-- modules/core/util/func_tests/util.cpp | 4 +- modules/core/util/include/func_test_util.hpp | 67 ++++++++++++------- modules/core/util/include/perf_test_util.hpp | 24 ++++--- modules/core/util/include/util.hpp | 3 + modules/core/util/src/util.cpp | 4 +- tasks/common/runners/functional.cpp | 2 +- tasks/common/runners/performance.cpp | 2 +- .../common/include/common.hpp | 5 +- tasks/example_processes/mpi/src/ops_mpi.cpp | 20 ++++-- .../example_processes/seq/include/ops_seq.hpp | 3 - tasks/example_processes/seq/src/ops_seq.cpp | 10 ++- .../tests/functional/main.cpp | 7 +- .../tests/performance/main.cpp | 7 +- tasks/example_threads/all/include/ops_all.hpp | 3 +- tasks/example_threads/all/src/ops_all.cpp | 7 +- .../example_threads/common/include/common.hpp | 5 +- tasks/example_threads/omp/include/ops_omp.hpp | 3 - tasks/example_threads/omp/src/ops_omp.cpp | 5 +- tasks/example_threads/seq/include/ops_seq.hpp | 3 - tasks/example_threads/seq/src/ops_seq.cpp | 13 +++- tasks/example_threads/stl/include/ops_stl.hpp | 3 - tasks/example_threads/stl/src/ops_stl.cpp | 4 +- tasks/example_threads/tbb/include/ops_tbb.hpp | 3 - tasks/example_threads/tbb/src/ops_tbb.cpp | 3 +- .../example_threads/tests/functional/main.cpp | 7 +- .../tests/performance/main.cpp | 7 +- 30 files changed, 146 insertions(+), 99 deletions(-) diff --git a/3rdparty/stb_image_wrapper.cpp b/3rdparty/stb_image_wrapper.cpp index 72063ea3a..b8d05c3e5 100644 --- a/3rdparty/stb_image_wrapper.cpp +++ b/3rdparty/stb_image_wrapper.cpp @@ -1,2 +1,4 @@ #define STB_IMAGE_IMPLEMENTATION + +// NOLINTNEXTLINE(misc-include-cleaner) #include "stb_library.hpp" diff --git a/modules/core/perf/func_tests/perf_tests.cpp b/modules/core/perf/func_tests/perf_tests.cpp index 7cb66e2a3..5f33d6523 100644 --- a/modules/core/perf/func_tests/perf_tests.cpp +++ b/modules/core/perf/func_tests/perf_tests.cpp @@ -71,6 +71,7 @@ TEST(perf_tests, check_perf_pipeline_uint8_t_slow_test) { perf_analyzer.PipelineRun(perf_attr); // Get perf statistic + // NOLINTNEXTLINE(cppcoreguidelines-avoid-goto) ASSERT_ANY_THROW(perf_analyzer.PrintPerfStatistic("check_perf_pipeline_uint8_t_slow_test")); } diff --git a/modules/core/perf/include/perf.hpp b/modules/core/perf/include/perf.hpp index 117783094..54e31ac9a 100644 --- a/modules/core/perf/include/perf.hpp +++ b/modules/core/perf/include/perf.hpp @@ -2,7 +2,12 @@ #include #include +#include +#include #include +#include +#include +#include #include "core/task/include/task.hpp" @@ -58,7 +63,7 @@ class Perf { task_->PostProcessing(); } // Pint results for automation checkers - void PrintPerfStatistic(std::string test_id) const { + void PrintPerfStatistic(const std::string& test_id) const { std::string type_test_name; if (perf_results_.type_of_running == PerfResults::TypeOfRunning::kTaskRun) { type_test_name = "task_run"; diff --git a/modules/core/task/include/task.hpp b/modules/core/task/include/task.hpp index 87caed22b..5d3d48368 100644 --- a/modules/core/task/include/task.hpp +++ b/modules/core/task/include/task.hpp @@ -3,17 +3,17 @@ #include #include #include -#include +#include #include #include #include #include #include #include +#include #include #include #include -#include using namespace std::chrono; @@ -34,11 +34,12 @@ inline std::string GetStringTaskType(TypeOfTask type_of_task, const std::string if (!file.is_open()) { throw std::runtime_error("Failed to open file settings.json"); } - nlohmann::json list_settings; - file >> list_settings; + + auto list_settings = ppc::util::InitJSONPtr(); + file >> *list_settings; auto to_type_str = [&](const std::string &type) -> std::string { - return type + "_" + std::string(list_settings["tasks"][type]); + return type + "_" + std::string((*list_settings)["tasks"][type]); }; if (type_of_task == TypeOfTask::kALL) { diff --git a/modules/core/util/func_tests/util.cpp b/modules/core/util/func_tests/util.cpp index db376daa6..929272926 100644 --- a/modules/core/util/func_tests/util.cpp +++ b/modules/core/util/func_tests/util.cpp @@ -2,9 +2,7 @@ #include -#include -#include -#include +#include #include "omp.h" diff --git a/modules/core/util/include/func_test_util.hpp b/modules/core/util/include/func_test_util.hpp index 886e12040..24ea6ddc7 100644 --- a/modules/core/util/include/func_test_util.hpp +++ b/modules/core/util/include/func_test_util.hpp @@ -1,15 +1,16 @@ #pragma once #include -#include #include #include +#include #include -#include -#include +#include +#include +#include -#include "core/perf/include/perf.hpp" +#include "core/task/include/task.hpp" #include "core/util/include/util.hpp" namespace ppc::util { @@ -44,31 +45,53 @@ class BaseRunFuncTests : public ::testing::TestWithParam(info.param) + "_" + Derived::PrintTestParam(test_param); } - protected: void ExecuteTest(FuncTestParam test_param) { - ASSERT_FALSE(std::get(test_param).find("unknown") != std::string::npos); - if (std::get(test_param).find("disabled") != std::string::npos) { + const std::string& test_name = std::get(test_param); + + validateTestName(test_name); + + if (isTestDisabled(test_name)) { GTEST_SKIP(); } - auto which_task = [&](const std::string& substring) { - return std::get(test_param).find(substring) != std::string::npos; - }; - - if (!ppc::util::IsUnderMpirun() && (which_task("_all") || which_task("_mpi"))) { - std::cerr << "kALL and kMPI tasks are not under mpirun" << '\n'; + if (shouldSkipNonMpiTask(test_name)) { + std::cerr << "kALL and kMPI tasks are not under mpirun\n"; GTEST_SKIP(); } - task_ = std::get(test_param)(GetTestInputData()); - ASSERT_TRUE(task_->Validation()); - ASSERT_TRUE(task_->PreProcessing()); - ASSERT_TRUE(task_->Run()); - ASSERT_TRUE(task_->PostProcessing()); - ASSERT_TRUE(CheckTestOutputData(task_->GetOutput())); + initializeAndRunTask(test_param); } private: + static constexpr std::string UNKNOWN_TEST = "unknown"; + static constexpr std::string DISABLED_TEST = "disabled"; + static constexpr std::string ALL_TASK = "_all"; + static constexpr std::string MPI_TASK = "_mpi"; + + void validateTestName(const std::string& test_name) { + EXPECT_FALSE(test_name.find(UNKNOWN_TEST) != std::string::npos); + } + + bool isTestDisabled(const std::string& test_name) { return test_name.find(DISABLED_TEST) != std::string::npos; } + + bool shouldSkipNonMpiTask(const std::string& test_name) { + auto containsSubstring = [&](const std::string& substring) { + return test_name.find(substring) != std::string::npos; + }; + + return !ppc::util::IsUnderMpirun() && (containsSubstring(ALL_TASK) || containsSubstring(MPI_TASK)); + } + + void initializeAndRunTask(const FuncTestParam& test_param) { + task_ = std::get(test_param)(GetTestInputData()); + + EXPECT_TRUE(task_->Validation()); + EXPECT_TRUE(task_->PreProcessing()); + EXPECT_TRUE(task_->Run()); + EXPECT_TRUE(task_->PostProcessing()); + EXPECT_TRUE(CheckTestOutputData(task_->GetOutput())); + } + ppc::core::TaskPtr task_; }; @@ -98,10 +121,6 @@ auto ExpandToValues(const Tuple& t) { return GenTaskTuplesImpl(std::make_index_sequence{}); \ } -#if 1 -#define ADD_FUNC_TASK(TASK) TaskListGenerator() -#else -#define ADD_FUNC_TASK(TASK) std::tuple<>() -#endif +#define ADD_FUNC_TASK(TASK) TaskListGenerator() // std::tuple<>() } // namespace ppc::util diff --git a/modules/core/util/include/perf_test_util.hpp b/modules/core/util/include/perf_test_util.hpp index 67e897501..51429a85e 100644 --- a/modules/core/util/include/perf_test_util.hpp +++ b/modules/core/util/include/perf_test_util.hpp @@ -5,11 +5,19 @@ #include #include +#include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include "core/perf/include/perf.hpp" +#include "core/task/include/task.hpp" #include "core/util/include/util.hpp" namespace ppc::util { @@ -93,7 +101,6 @@ class BaseRunPerfTests : public ::testing::TestWithParam task_; }; -#if 1 #define ADD_PERF_TASK(TaskType, InputTypeParam, SettingsPath) \ std::tuple(std::make_tuple(ppc::core::TaskGetter, \ std::string(ppc::util::GetNamespace()) + "_" + \ @@ -103,19 +110,18 @@ class BaseRunPerfTests : public ::testing::TestWithParam()) + "_" + \ ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), SettingsPath), \ ppc::core::PerfResults::TypeOfRunning::kTaskRun)) -#else -#define ADD_PERF_TASK(TaskType, InputTypeParam, SettingsPath) std::make_tuple() -#endif + +// #define ADD_PERF_TASK(TaskType, InputTypeParam, SettingsPath) std::make_tuple() template -auto TupleToGTestValuesImpl(Tuple&& tup, std::index_sequence) { +auto TupleToGTestValuesImpl(Tuple&& tup, std::index_sequence /*unused*/) { return ::testing::Values(std::get(std::forward(tup))...); } template auto TupleToGTestValues(Tuple&& tup) { - constexpr size_t size = std::tuple_size>::value; - return TupleToGTestValuesImpl(std::forward(tup), std::make_index_sequence{}); + constexpr size_t kSize = std::tuple_size>::value; + return TupleToGTestValuesImpl(std::forward(tup), std::make_index_sequence{}); } #define INIT_PERF_TASK_GENERATOR(InType, EnvVarSettingsPath) \ diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index 107b47328..f84c1f837 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -90,6 +91,8 @@ constexpr std::string_view GetNamespace() { #endif } +inline std::shared_ptr InitJSONPtr() { return std::make_shared(); } + bool IsUnderMpirun(); } // namespace ppc::util diff --git a/modules/core/util/src/util.cpp b/modules/core/util/src/util.cpp index a7db755b1..e1eb3f3d3 100644 --- a/modules/core/util/src/util.cpp +++ b/modules/core/util/src/util.cpp @@ -3,12 +3,12 @@ #include #include #include -#include +#include #include namespace { -static std::string GetAbsolutePath(const std::string& relative_path) { +std::string GetAbsolutePath(const std::string& relative_path) { const std::filesystem::path path = std::string(PPC_PATH_TO_PROJECT) + "/tasks/" + relative_path; return path.string(); } diff --git a/tasks/common/runners/functional.cpp b/tasks/common/runners/functional.cpp index d4052d5d3..cb45c43c4 100644 --- a/tasks/common/runners/functional.cpp +++ b/tasks/common/runners/functional.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include @@ -9,6 +8,7 @@ #include #include "core/util/include/util.hpp" +#include "mpi.h" #include "oneapi/tbb/global_control.h" class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { diff --git a/tasks/common/runners/performance.cpp b/tasks/common/runners/performance.cpp index a32b13c25..2b46e2ca1 100644 --- a/tasks/common/runners/performance.cpp +++ b/tasks/common/runners/performance.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include @@ -9,6 +8,7 @@ #include #include "core/util/include/util.hpp" +#include "mpi.h" #include "oneapi/tbb/global_control.h" class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { diff --git a/tasks/example_processes/common/include/common.hpp b/tasks/example_processes/common/include/common.hpp index 339aed794..1e953987b 100644 --- a/tasks/example_processes/common/include/common.hpp +++ b/tasks/example_processes/common/include/common.hpp @@ -1,10 +1,9 @@ #pragma once -#include -#include +#include +#include #include "core/task/include/task.hpp" -#include "core/util/include/util.hpp" namespace nesterov_a_test_task_processes { diff --git a/tasks/example_processes/mpi/src/ops_mpi.cpp b/tasks/example_processes/mpi/src/ops_mpi.cpp index c9c6c4705..927b96faa 100644 --- a/tasks/example_processes/mpi/src/ops_mpi.cpp +++ b/tasks/example_processes/mpi/src/ops_mpi.cpp @@ -1,11 +1,13 @@ #include "example_processes/mpi/include/ops_mpi.hpp" -#include - #include -#include +#include #include +#include "core/util/include/util.hpp" +#include "example_processes/common/include/common.hpp" +#include "mpi.h" + namespace nesterov_a_test_task_processes { NesterovATestTaskMPI::NesterovATestTaskMPI(const InType &in) { @@ -22,6 +24,11 @@ bool NesterovATestTaskMPI::PreProcessingImpl() { } bool NesterovATestTaskMPI::RunImpl() { + auto input = GetInput(); + if (input == 0) { + return false; + } + for (InType i = 0; i < GetInput(); i++) { for (InType j = 0; j < GetInput(); j++) { for (InType k = 0; k < GetInput(); k++) { @@ -35,7 +42,7 @@ bool NesterovATestTaskMPI::RunImpl() { const int num_threads = ppc::util::GetNumThreads(); GetOutput() *= num_threads; - int rank = -1; + int rank = 0; MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { @@ -45,7 +52,10 @@ bool NesterovATestTaskMPI::RunImpl() { for (int i = 0; i < num_threads; i++) { counter++; } - GetOutput() /= counter; + + if (counter != 0) { + GetOutput() /= counter; + } } MPI_Barrier(MPI_COMM_WORLD); diff --git a/tasks/example_processes/seq/include/ops_seq.hpp b/tasks/example_processes/seq/include/ops_seq.hpp index 01f0792b0..5c73ad682 100644 --- a/tasks/example_processes/seq/include/ops_seq.hpp +++ b/tasks/example_processes/seq/include/ops_seq.hpp @@ -1,8 +1,5 @@ #pragma once -#include -#include - #include "core/task/include/task.hpp" #include "example_processes/common/include/common.hpp" diff --git a/tasks/example_processes/seq/src/ops_seq.cpp b/tasks/example_processes/seq/src/ops_seq.cpp index 53f96e51a..8ff6a206e 100644 --- a/tasks/example_processes/seq/src/ops_seq.cpp +++ b/tasks/example_processes/seq/src/ops_seq.cpp @@ -1,9 +1,12 @@ #include "example_processes/seq/include/ops_seq.hpp" #include -#include +#include #include +#include "core/util/include/util.hpp" +#include "example_processes/common/include/common.hpp" + namespace nesterov_a_test_task_processes { NesterovATestTaskSEQ::NesterovATestTaskSEQ(const InType& in) { @@ -20,6 +23,11 @@ bool NesterovATestTaskSEQ::PreProcessingImpl() { } bool NesterovATestTaskSEQ::RunImpl() { + auto input = GetInput(); + if (input == 0) { + return false; + } + for (InType i = 0; i < GetInput(); i++) { for (InType j = 0; j < GetInput(); j++) { for (InType k = 0; k < GetInput(); k++) { diff --git a/tasks/example_processes/tests/functional/main.cpp b/tasks/example_processes/tests/functional/main.cpp index 2ed69b457..d64604691 100644 --- a/tasks/example_processes/tests/functional/main.cpp +++ b/tasks/example_processes/tests/functional/main.cpp @@ -1,15 +1,20 @@ #include -#include +#include +#include #include #include +#include #include +#include #include +#include #include #include #include "core/util/include/func_test_util.hpp" #include "core/util/include/util.hpp" +#include "example_processes/common/include/common.hpp" #include "example_processes/mpi/include/ops_mpi.hpp" #include "example_processes/seq/include/ops_seq.hpp" diff --git a/tasks/example_processes/tests/performance/main.cpp b/tasks/example_processes/tests/performance/main.cpp index 2d4d34f6b..f1a590027 100644 --- a/tasks/example_processes/tests/performance/main.cpp +++ b/tasks/example_processes/tests/performance/main.cpp @@ -1,15 +1,10 @@ #include -#include -#include -#include -#include #include -#include -#include "core/perf/include/perf.hpp" #include "core/util/include/perf_test_util.hpp" #include "core/util/include/util.hpp" +#include "example_processes/common/include/common.hpp" #include "example_processes/mpi/include/ops_mpi.hpp" #include "example_processes/seq/include/ops_seq.hpp" diff --git a/tasks/example_threads/all/include/ops_all.hpp b/tasks/example_threads/all/include/ops_all.hpp index c57011bb0..9e5ba0ffc 100644 --- a/tasks/example_threads/all/include/ops_all.hpp +++ b/tasks/example_threads/all/include/ops_all.hpp @@ -1,7 +1,6 @@ #pragma once -#include - +#include "core/task/include/task.hpp" #include "example_threads/common/include/common.hpp" namespace nesterov_a_test_task_threads { diff --git a/tasks/example_threads/all/src/ops_all.cpp b/tasks/example_threads/all/src/ops_all.cpp index 438c00a28..a86d56864 100644 --- a/tasks/example_threads/all/src/ops_all.cpp +++ b/tasks/example_threads/all/src/ops_all.cpp @@ -1,15 +1,14 @@ #include "example_threads/all/include/ops_all.hpp" -#include - #include #include -#include -#include +#include #include #include #include "core/util/include/util.hpp" +#include "example_threads/common/include/common.hpp" +#include "mpi.h" #include "oneapi/tbb/parallel_for.h" namespace nesterov_a_test_task_threads { diff --git a/tasks/example_threads/common/include/common.hpp b/tasks/example_threads/common/include/common.hpp index fb94b3190..21a29015a 100644 --- a/tasks/example_threads/common/include/common.hpp +++ b/tasks/example_threads/common/include/common.hpp @@ -1,10 +1,9 @@ #pragma once -#include -#include +#include +#include #include "core/task/include/task.hpp" -#include "core/util/include/util.hpp" namespace nesterov_a_test_task_threads { diff --git a/tasks/example_threads/omp/include/ops_omp.hpp b/tasks/example_threads/omp/include/ops_omp.hpp index cfbe1c463..e82c75b83 100644 --- a/tasks/example_threads/omp/include/ops_omp.hpp +++ b/tasks/example_threads/omp/include/ops_omp.hpp @@ -1,8 +1,5 @@ #pragma once -#include -#include - #include "core/task/include/task.hpp" #include "example_threads/common/include/common.hpp" diff --git a/tasks/example_threads/omp/src/ops_omp.cpp b/tasks/example_threads/omp/src/ops_omp.cpp index 0cf4319f5..b10e5139f 100644 --- a/tasks/example_threads/omp/src/ops_omp.cpp +++ b/tasks/example_threads/omp/src/ops_omp.cpp @@ -2,9 +2,12 @@ #include #include -#include +#include #include +#include "core/util/include/util.hpp" +#include "example_threads/common/include/common.hpp" + namespace nesterov_a_test_task_threads { NesterovATestTaskOMP::NesterovATestTaskOMP(const InType& in) { diff --git a/tasks/example_threads/seq/include/ops_seq.hpp b/tasks/example_threads/seq/include/ops_seq.hpp index 900df4ff4..5688226ca 100644 --- a/tasks/example_threads/seq/include/ops_seq.hpp +++ b/tasks/example_threads/seq/include/ops_seq.hpp @@ -1,8 +1,5 @@ #pragma once -#include -#include - #include "core/task/include/task.hpp" #include "example_threads/common/include/common.hpp" diff --git a/tasks/example_threads/seq/src/ops_seq.cpp b/tasks/example_threads/seq/src/ops_seq.cpp index 5db1d7ad0..073ab1c61 100644 --- a/tasks/example_threads/seq/src/ops_seq.cpp +++ b/tasks/example_threads/seq/src/ops_seq.cpp @@ -1,9 +1,12 @@ #include "example_threads/seq/include/ops_seq.hpp" #include -#include +#include #include +#include "core/util/include/util.hpp" +#include "example_threads/common/include/common.hpp" + namespace nesterov_a_test_task_threads { NesterovATestTaskSEQ::NesterovATestTaskSEQ(const InType& in) { @@ -20,6 +23,10 @@ bool NesterovATestTaskSEQ::PreProcessingImpl() { } bool NesterovATestTaskSEQ::RunImpl() { + if (GetInput() == 0) { + return false; + } + for (InType i = 0; i < GetInput(); i++) { for (InType j = 0; j < GetInput(); j++) { for (InType k = 0; k < GetInput(); k++) { @@ -38,7 +45,9 @@ bool NesterovATestTaskSEQ::RunImpl() { counter++; } - GetOutput() /= counter; + if (counter != 0) { + GetOutput() /= counter; + } return GetOutput() > 0; } diff --git a/tasks/example_threads/stl/include/ops_stl.hpp b/tasks/example_threads/stl/include/ops_stl.hpp index 05bb6eab7..503b89f13 100644 --- a/tasks/example_threads/stl/include/ops_stl.hpp +++ b/tasks/example_threads/stl/include/ops_stl.hpp @@ -1,8 +1,5 @@ #pragma once -#include -#include - #include "core/task/include/task.hpp" #include "example_threads/common/include/common.hpp" diff --git a/tasks/example_threads/stl/src/ops_stl.cpp b/tasks/example_threads/stl/src/ops_stl.cpp index c53c37835..ea23bdb99 100644 --- a/tasks/example_threads/stl/src/ops_stl.cpp +++ b/tasks/example_threads/stl/src/ops_stl.cpp @@ -2,12 +2,12 @@ #include #include -#include -#include +#include #include #include #include "core/util/include/util.hpp" +#include "example_threads/common/include/common.hpp" namespace nesterov_a_test_task_threads { diff --git a/tasks/example_threads/tbb/include/ops_tbb.hpp b/tasks/example_threads/tbb/include/ops_tbb.hpp index d10256d17..4a637a529 100644 --- a/tasks/example_threads/tbb/include/ops_tbb.hpp +++ b/tasks/example_threads/tbb/include/ops_tbb.hpp @@ -1,8 +1,5 @@ #pragma once -#include -#include - #include "core/task/include/task.hpp" #include "example_threads/common/include/common.hpp" diff --git a/tasks/example_threads/tbb/src/ops_tbb.cpp b/tasks/example_threads/tbb/src/ops_tbb.cpp index 5f426f283..0f057e676 100644 --- a/tasks/example_threads/tbb/src/ops_tbb.cpp +++ b/tasks/example_threads/tbb/src/ops_tbb.cpp @@ -5,9 +5,10 @@ #include #include #include -#include +#include #include +#include "example_threads/common/include/common.hpp" #include "oneapi/tbb/parallel_for.h" namespace nesterov_a_test_task_threads { diff --git a/tasks/example_threads/tests/functional/main.cpp b/tasks/example_threads/tests/functional/main.cpp index e4c4cd811..036bbd533 100644 --- a/tasks/example_threads/tests/functional/main.cpp +++ b/tasks/example_threads/tests/functional/main.cpp @@ -1,16 +1,21 @@ #include -#include +#include +#include #include #include +#include #include +#include #include +#include #include #include #include "core/util/include/func_test_util.hpp" #include "core/util/include/util.hpp" #include "example_threads/all/include/ops_all.hpp" +#include "example_threads/common/include/common.hpp" #include "example_threads/omp/include/ops_omp.hpp" #include "example_threads/seq/include/ops_seq.hpp" #include "example_threads/stl/include/ops_stl.hpp" diff --git a/tasks/example_threads/tests/performance/main.cpp b/tasks/example_threads/tests/performance/main.cpp index c1219989d..c7bc9c1a5 100644 --- a/tasks/example_threads/tests/performance/main.cpp +++ b/tasks/example_threads/tests/performance/main.cpp @@ -1,16 +1,11 @@ #include -#include -#include -#include -#include #include -#include -#include "core/perf/include/perf.hpp" #include "core/util/include/perf_test_util.hpp" #include "core/util/include/util.hpp" #include "example_threads/all/include/ops_all.hpp" +#include "example_threads/common/include/common.hpp" #include "example_threads/omp/include/ops_omp.hpp" #include "example_threads/seq/include/ops_seq.hpp" #include "example_threads/stl/include/ops_stl.hpp" From 9a5a27222d7eeaa3ad29ba4629e5b52a1c7cf2e4 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 19:24:45 +0200 Subject: [PATCH 090/141] Simplify codecov ignore patterns to focus on task-related tests and runners. --- codecov.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/codecov.yml b/codecov.yml index 2e8324752..a7c1e7f7c 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,12 +1,6 @@ ignore: - - "**/perf_tests/**" - - "**/func_tests/**" - - "**/all/runner.cpp" - - "**/mpi/runner.cpp" - - "**/omp/runner.cpp" - - "**/seq/runner.cpp" - - "**/stl/runner.cpp" - - "**/tbb/runner.cpp" + - "**/tasks/**/tests/**" + - "**/tasks/common/runners/**" coverage: status: project: From 72cae177bab9bfa7c9967666ed7e3519f39511e3 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 19:24:45 +0200 Subject: [PATCH 091/141] Simplify codecov ignore patterns to focus on task-related tests and runners. --- codecov.yml | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/codecov.yml b/codecov.yml index 2e8324752..0a7fa368d 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,12 +1,8 @@ ignore: - - "**/perf_tests/**" - - "**/func_tests/**" - - "**/all/runner.cpp" - - "**/mpi/runner.cpp" - - "**/omp/runner.cpp" - - "**/seq/runner.cpp" - - "**/stl/runner.cpp" - - "**/tbb/runner.cpp" + - "**/tasks/**/tests/**" + - "**/tasks/common/runners/**" + - "**/modules/core/util/include/func_test_util.hpp" + - "**/modules/core/util/include/perf_test_util.hpp" coverage: status: project: From d352ce0beeb705a64a31996a075a2f8a6bbf7edd Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 20:17:25 +0200 Subject: [PATCH 092/141] Refactor task and test initialization methods, improve naming consistency, and clean up MPI-related imports across modules and tasks --- modules/core/perf/func_tests/perf_tests.cpp | 1 + modules/core/util/include/func_test_util.hpp | 69 ++++++++++--------- modules/core/util/include/perf_test_util.hpp | 33 ++++----- modules/core/util/include/util.hpp | 3 +- tasks/common/runners/functional.cpp | 2 +- tasks/common/runners/performance.cpp | 2 +- tasks/example_processes/mpi/src/ops_mpi.cpp | 3 +- tasks/example_processes/seq/src/ops_seq.cpp | 7 +- .../tests/functional/main.cpp | 6 +- .../tests/performance/main.cpp | 13 ++-- tasks/example_threads/all/src/ops_all.cpp | 3 +- .../example_threads/tests/functional/main.cpp | 11 +-- .../tests/performance/main.cpp | 15 ++-- 13 files changed, 85 insertions(+), 83 deletions(-) diff --git a/modules/core/perf/func_tests/perf_tests.cpp b/modules/core/perf/func_tests/perf_tests.cpp index 5f33d6523..495c9f891 100644 --- a/modules/core/perf/func_tests/perf_tests.cpp +++ b/modules/core/perf/func_tests/perf_tests.cpp @@ -86,6 +86,7 @@ TEST(perf_tests, check_perf_task_exception) { ppc::core::Perf, uint32_t> perf_analyzer(test_task); // Get perf statistic + // NOLINTNEXTLINE(cppcoreguidelines-avoid-goto) ASSERT_ANY_THROW(perf_analyzer.PrintPerfStatistic("check_perf_task_exception")); // Create Perf attributes diff --git a/modules/core/util/include/func_test_util.hpp b/modules/core/util/include/func_test_util.hpp index 24ea6ddc7..343b3b7b3 100644 --- a/modules/core/util/include/func_test_util.hpp +++ b/modules/core/util/include/func_test_util.hpp @@ -6,9 +6,11 @@ #include #include +#include #include #include #include +#include #include "core/task/include/task.hpp" #include "core/util/include/util.hpp" @@ -45,44 +47,44 @@ class BaseRunFuncTests : public ::testing::TestWithParam(info.param) + "_" + Derived::PrintTestParam(test_param); } + protected: + const std::string kUnknownTest = "unknown"; + const std::string kDisabledTest = "disabled"; + const std::string kAllTask = "_all"; + const std::string kMpiTask = "_mpi"; + void ExecuteTest(FuncTestParam test_param) { const std::string& test_name = std::get(test_param); - validateTestName(test_name); + ValidateTestName(test_name); - if (isTestDisabled(test_name)) { + if (IsTestDisabled(test_name)) { GTEST_SKIP(); } - if (shouldSkipNonMpiTask(test_name)) { + if (ShouldSkipNonMpiTask(test_name)) { std::cerr << "kALL and kMPI tasks are not under mpirun\n"; GTEST_SKIP(); } - initializeAndRunTask(test_param); + InitializeAndRunTask(test_param); } - private: - static constexpr std::string UNKNOWN_TEST = "unknown"; - static constexpr std::string DISABLED_TEST = "disabled"; - static constexpr std::string ALL_TASK = "_all"; - static constexpr std::string MPI_TASK = "_mpi"; - - void validateTestName(const std::string& test_name) { - EXPECT_FALSE(test_name.find(UNKNOWN_TEST) != std::string::npos); + void ValidateTestName(const std::string& test_name) { + EXPECT_FALSE(test_name.find(kUnknownTest) != std::string::npos); } - bool isTestDisabled(const std::string& test_name) { return test_name.find(DISABLED_TEST) != std::string::npos; } + bool IsTestDisabled(const std::string& test_name) { return test_name.find(kDisabledTest) != std::string::npos; } - bool shouldSkipNonMpiTask(const std::string& test_name) { - auto containsSubstring = [&](const std::string& substring) { + bool ShouldSkipNonMpiTask(const std::string& test_name) { + auto contains_substring = [&](const std::string& substring) { return test_name.find(substring) != std::string::npos; }; - return !ppc::util::IsUnderMpirun() && (containsSubstring(ALL_TASK) || containsSubstring(MPI_TASK)); + return !ppc::util::IsUnderMpirun() && (contains_substring(kAllTask) || contains_substring(kMpiTask)); } - void initializeAndRunTask(const FuncTestParam& test_param) { + void InitializeAndRunTask(const FuncTestParam& test_param) { task_ = std::get(test_param)(GetTestInputData()); EXPECT_TRUE(task_->Validation()); @@ -92,6 +94,7 @@ class BaseRunFuncTests : public ::testing::TestWithParamGetOutput())); } + private: ppc::core::TaskPtr task_; }; @@ -106,21 +109,23 @@ auto ExpandToValues(const Tuple& t) { return ExpandToValuesImpl(t, std::make_index_sequence{}); } -#define INIT_FUNC_TASK_GENERATOR(InTypeParam, SizesParam, SettingsPath) \ - template \ - auto GenTaskTuplesImpl(std::index_sequence) { \ - return std::make_tuple( \ - std::make_tuple(ppc::core::TaskGetter, \ - std::string(ppc::util::GetNamespace()) + std::string("_") + \ - ppc::core::GetStringTaskType(Task::GetStaticTypeOfTask(), SettingsPath), \ - SizesParam[Is])...); \ - } \ - \ - template \ - auto TaskListGenerator() { \ - return GenTaskTuplesImpl(std::make_index_sequence{}); \ - } +template +auto GenTaskTuplesImpl(const SizesContainer& sizes, const std::string& settings_path, std::index_sequence) { + return std::make_tuple(std::make_tuple(ppc::core::TaskGetter, + std::string(GetNamespace()) + "_" + + ppc::core::GetStringTaskType(Task::GetStaticTypeOfTask(), settings_path), + sizes[Is])...); +} + +template +auto TaskListGenerator(const SizesContainer& sizes, const std::string& settings_path) { + return GenTaskTuplesImpl(sizes, settings_path, + std::make_index_sequence>>{}); +} -#define ADD_FUNC_TASK(TASK) TaskListGenerator() // std::tuple<>() +template +constexpr auto AddFuncTask(const SizesContainer& sizes, const std::string& settings_path) { + return TaskListGenerator(sizes, settings_path); +} } // namespace ppc::util diff --git a/modules/core/util/include/perf_test_util.hpp b/modules/core/util/include/perf_test_util.hpp index 51429a85e..200adbcd2 100644 --- a/modules/core/util/include/perf_test_util.hpp +++ b/modules/core/util/include/perf_test_util.hpp @@ -3,15 +3,16 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include -#include #include #include #include @@ -101,17 +102,16 @@ class BaseRunPerfTests : public ::testing::TestWithParam task_; }; -#define ADD_PERF_TASK(TaskType, InputTypeParam, SettingsPath) \ - std::tuple(std::make_tuple(ppc::core::TaskGetter, \ - std::string(ppc::util::GetNamespace()) + "_" + \ - ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), SettingsPath), \ - ppc::core::PerfResults::TypeOfRunning::kPipeline), \ - std::make_tuple(ppc::core::TaskGetter, \ - std::string(ppc::util::GetNamespace()) + "_" + \ - ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), SettingsPath), \ - ppc::core::PerfResults::TypeOfRunning::kTaskRun)) +template +auto MakePerfTaskTuples(const std::string& settings_path) { + const auto name = std::string(GetNamespace()) + "_" + + ppc::core::GetStringTaskType(TaskType::GetStaticTypeOfTask(), settings_path); -// #define ADD_PERF_TASK(TaskType, InputTypeParam, SettingsPath) std::make_tuple() + return std::make_tuple(std::make_tuple(ppc::core::TaskGetter, name, + ppc::core::PerfResults::TypeOfRunning::kPipeline), + std::make_tuple(ppc::core::TaskGetter, name, + ppc::core::PerfResults::TypeOfRunning::kTaskRun)); +} template auto TupleToGTestValuesImpl(Tuple&& tup, std::index_sequence /*unused*/) { @@ -124,12 +124,9 @@ auto TupleToGTestValues(Tuple&& tup) { return TupleToGTestValuesImpl(std::forward(tup), std::make_index_sequence{}); } -#define INIT_PERF_TASK_GENERATOR(InType, EnvVarSettingsPath) \ - template \ - struct perf_tasks_type_list {}; \ - template \ - auto MakeTask(perf_tasks_type_list) { \ - return std::tuple_cat(ADD_PERF_TASK(Ts, InType, EnvVarSettingsPath)...); \ - } +template +auto MakeAllPerfTasks(const std::string& settings_path) { + return std::tuple_cat(MakePerfTaskTuples(settings_path)...); +} } // namespace ppc::util diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index f84c1f837..b645f2966 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -11,7 +11,7 @@ #pragma warning(disable : 4459) #endif -#include +#include // NOLINT(misc-include-cleaner) #ifdef _MSC_VER #pragma warning(pop) @@ -91,6 +91,7 @@ constexpr std::string_view GetNamespace() { #endif } +// NOLINTNEXTLINE(misc-include-cleaner) inline std::shared_ptr InitJSONPtr() { return std::make_shared(); } bool IsUnderMpirun(); diff --git a/tasks/common/runners/functional.cpp b/tasks/common/runners/functional.cpp index cb45c43c4..d4052d5d3 100644 --- a/tasks/common/runners/functional.cpp +++ b/tasks/common/runners/functional.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -8,7 +9,6 @@ #include #include "core/util/include/util.hpp" -#include "mpi.h" #include "oneapi/tbb/global_control.h" class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { diff --git a/tasks/common/runners/performance.cpp b/tasks/common/runners/performance.cpp index 2b46e2ca1..a32b13c25 100644 --- a/tasks/common/runners/performance.cpp +++ b/tasks/common/runners/performance.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -8,7 +9,6 @@ #include #include "core/util/include/util.hpp" -#include "mpi.h" #include "oneapi/tbb/global_control.h" class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { diff --git a/tasks/example_processes/mpi/src/ops_mpi.cpp b/tasks/example_processes/mpi/src/ops_mpi.cpp index 927b96faa..1a6fb1687 100644 --- a/tasks/example_processes/mpi/src/ops_mpi.cpp +++ b/tasks/example_processes/mpi/src/ops_mpi.cpp @@ -1,12 +1,13 @@ #include "example_processes/mpi/include/ops_mpi.hpp" +#include + #include #include #include #include "core/util/include/util.hpp" #include "example_processes/common/include/common.hpp" -#include "mpi.h" namespace nesterov_a_test_task_processes { diff --git a/tasks/example_processes/seq/src/ops_seq.cpp b/tasks/example_processes/seq/src/ops_seq.cpp index 8ff6a206e..8528c11f4 100644 --- a/tasks/example_processes/seq/src/ops_seq.cpp +++ b/tasks/example_processes/seq/src/ops_seq.cpp @@ -23,8 +23,7 @@ bool NesterovATestTaskSEQ::PreProcessingImpl() { } bool NesterovATestTaskSEQ::RunImpl() { - auto input = GetInput(); - if (input == 0) { + if (GetInput() == 0) { return false; } @@ -46,7 +45,9 @@ bool NesterovATestTaskSEQ::RunImpl() { counter++; } - GetOutput() /= counter; + if (counter != 0) { + GetOutput() /= counter; + } return GetOutput() > 0; } diff --git a/tasks/example_processes/tests/functional/main.cpp b/tasks/example_processes/tests/functional/main.cpp index d64604691..7e1e3fa47 100644 --- a/tasks/example_processes/tests/functional/main.cpp +++ b/tasks/example_processes/tests/functional/main.cpp @@ -64,9 +64,9 @@ TEST_P(NesterovARunFuncTestsProcesses, MatmulFromPic) { ExecuteTest(GetParam()); const std::array kTestParam = {std::make_tuple(3, "3"), std::make_tuple(5, "5"), std::make_tuple(7, "7")}; -INIT_FUNC_TASK_GENERATOR(InType, kTestParam, PPC_SETTINGS_example_processes) - -const auto kTestTasksList = std::tuple_cat(ADD_FUNC_TASK(NesterovATestTaskMPI), ADD_FUNC_TASK(NesterovATestTaskSEQ)); +const auto kTestTasksList = + std::tuple_cat(ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_example_processes), + ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_example_processes)); INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTestsProcesses, ppc::util::ExpandToValues(kTestTasksList), diff --git a/tasks/example_processes/tests/performance/main.cpp b/tasks/example_processes/tests/performance/main.cpp index f1a590027..7a9f2a59a 100644 --- a/tasks/example_processes/tests/performance/main.cpp +++ b/tasks/example_processes/tests/performance/main.cpp @@ -21,15 +21,12 @@ class ExampleRunPerfTestProcesses : public ppc::util::BaseRunPerfTests; - -const auto kAllPerfTasks = std::tuple_cat(MakeTask(PerfTasks{})); - TEST_P(ExampleRunPerfTestProcesses, RunPerfModes) { ExecuteTest(GetParam()); } -INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, ExampleRunPerfTestProcesses, ppc::util::TupleToGTestValues(kAllPerfTasks), - ExampleRunPerfTestProcesses::CustomPerfTestName); +const auto kAllPerfTasks = + ppc::util::MakeAllPerfTasks(PPC_SETTINGS_example_processes); + +INSTANTIATE_TEST_SUITE_P(RunModeTests, ExampleRunPerfTestProcesses, ppc::util::TupleToGTestValues(kAllPerfTasks), + ExampleRunPerfTestProcesses::CustomPerfTestName); } // namespace nesterov_a_test_task_processes diff --git a/tasks/example_threads/all/src/ops_all.cpp b/tasks/example_threads/all/src/ops_all.cpp index a86d56864..07d899c34 100644 --- a/tasks/example_threads/all/src/ops_all.cpp +++ b/tasks/example_threads/all/src/ops_all.cpp @@ -1,5 +1,7 @@ #include "example_threads/all/include/ops_all.hpp" +#include + #include #include #include @@ -8,7 +10,6 @@ #include "core/util/include/util.hpp" #include "example_threads/common/include/common.hpp" -#include "mpi.h" #include "oneapi/tbb/parallel_for.h" namespace nesterov_a_test_task_threads { diff --git a/tasks/example_threads/tests/functional/main.cpp b/tasks/example_threads/tests/functional/main.cpp index 036bbd533..43a444c98 100644 --- a/tasks/example_threads/tests/functional/main.cpp +++ b/tasks/example_threads/tests/functional/main.cpp @@ -67,11 +67,12 @@ TEST_P(NesterovARunFuncTestsThreads, MatmulFromPic) { ExecuteTest(GetParam()); } const std::array kTestParam = {std::make_tuple(3, "3"), std::make_tuple(5, "5"), std::make_tuple(7, "7")}; -INIT_FUNC_TASK_GENERATOR(InType, kTestParam, PPC_SETTINGS_example_threads) - -const auto kTestTasksList = std::tuple_cat(ADD_FUNC_TASK(NesterovATestTaskALL), ADD_FUNC_TASK(NesterovATestTaskOMP), - ADD_FUNC_TASK(NesterovATestTaskSEQ), ADD_FUNC_TASK(NesterovATestTaskSTL), - ADD_FUNC_TASK(NesterovATestTaskTBB)); +const auto kTestTasksList = + std::tuple_cat(ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_example_threads), + ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_example_threads), + ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_example_threads), + ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_example_threads), + ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_example_threads)); INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTestsThreads, ppc::util::ExpandToValues(kTestTasksList), NesterovARunFuncTestsThreads::PrintFuncTestName); diff --git a/tasks/example_threads/tests/performance/main.cpp b/tasks/example_threads/tests/performance/main.cpp index c7bc9c1a5..ae99bf7ad 100644 --- a/tasks/example_threads/tests/performance/main.cpp +++ b/tasks/example_threads/tests/performance/main.cpp @@ -24,16 +24,13 @@ class ExampleRunPerfTestThreads : public ppc::util::BaseRunPerfTests; - -const auto kAllPerfTasks = std::tuple_cat(MakeTask(PerfTasks{})); - TEST_P(ExampleRunPerfTestThreads, RunPerfModes) { ExecuteTest(GetParam()); } -INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, ExampleRunPerfTestThreads, ppc::util::TupleToGTestValues(kAllPerfTasks), - ExampleRunPerfTestThreads::CustomPerfTestName); +const auto kAllPerfTasks = + ppc::util::MakeAllPerfTasks(PPC_SETTINGS_example_threads); + +INSTANTIATE_TEST_SUITE_P(RunModeTests, ExampleRunPerfTestThreads, ppc::util::TupleToGTestValues(kAllPerfTasks), + ExampleRunPerfTestThreads::CustomPerfTestName); } // namespace nesterov_a_test_task_threads From 1472579c459ebb10bc16d815c584f854891f7fec Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 22:37:57 +0200 Subject: [PATCH 093/141] Refactor test suite instantiations, consolidate test name utilities, and streamline MPI-related imports and logic --- modules/core/util/include/func_test_util.hpp | 18 ++++++-------- modules/core/util/include/perf_test_util.hpp | 24 ++++++++----------- modules/core/util/src/func_test_util.cpp | 11 +++++++++ .../example_processes/mpi/include/ops_mpi.hpp | 2 -- .../tests/functional/main.cpp | 8 ++++--- .../tests/performance/main.cpp | 8 ++++--- .../example_threads/tests/functional/main.cpp | 7 ++++-- .../tests/performance/main.cpp | 10 ++++---- 8 files changed, 48 insertions(+), 40 deletions(-) create mode 100644 modules/core/util/src/func_test_util.cpp diff --git a/modules/core/util/include/func_test_util.hpp b/modules/core/util/include/func_test_util.hpp index 343b3b7b3..5493e80d0 100644 --- a/modules/core/util/include/func_test_util.hpp +++ b/modules/core/util/include/func_test_util.hpp @@ -8,8 +8,10 @@ #include #include #include +#include #include #include +#include #include #include "core/task/include/task.hpp" @@ -48,11 +50,6 @@ class BaseRunFuncTests : public ::testing::TestWithParam test_param) { const std::string& test_name = std::get(test_param); @@ -70,18 +67,16 @@ class BaseRunFuncTests : public ::testing::TestWithParam& test_param) { @@ -110,7 +105,8 @@ auto ExpandToValues(const Tuple& t) { } template -auto GenTaskTuplesImpl(const SizesContainer& sizes, const std::string& settings_path, std::index_sequence) { +auto GenTaskTuplesImpl(const SizesContainer& sizes, const std::string& settings_path, + std::index_sequence /*unused*/) { return std::make_tuple(std::make_tuple(ppc::core::TaskGetter, std::string(GetNamespace()) + "_" + ppc::core::GetStringTaskType(Task::GetStaticTypeOfTask(), settings_path), diff --git a/modules/core/util/include/perf_test_util.hpp b/modules/core/util/include/perf_test_util.hpp index 200adbcd2..38140aa95 100644 --- a/modules/core/util/include/perf_test_util.hpp +++ b/modules/core/util/include/perf_test_util.hpp @@ -1,10 +1,7 @@ #pragma once #include -#include #include -#include -#include #include #include @@ -23,6 +20,9 @@ namespace ppc::util { +double GetTimeMPI(); +int GetMPIRank(); + template using PerfTestParam = std::tuple(InType)>, std::string, ppc::core::PerfResults::TypeOfRunning>; @@ -40,18 +40,16 @@ class BaseRunPerfTests : public ::testing::TestWithParamGetDynamicTypeOfTask() == ppc::core::TypeOfTask::kTBB) { - const tbb::tick_count t0 = tbb::tick_count::now(); - perf_attrs.current_timer = [t0] { return (tbb::tick_count::now() - t0).seconds(); }; - } else if (task_->GetDynamicTypeOfTask() == ppc::core::TypeOfTask::kMPI || - task_->GetDynamicTypeOfTask() == ppc::core::TypeOfTask::kALL) { - const double t0 = MPI_Wtime(); - perf_attrs.current_timer = [t0] { return MPI_Wtime() - t0; }; + if (task_->GetDynamicTypeOfTask() == ppc::core::TypeOfTask::kMPI || + task_->GetDynamicTypeOfTask() == ppc::core::TypeOfTask::kALL) { + const double t0 = GetTimeMPI(); + perf_attrs.current_timer = [t0] { return GetTimeMPI() - t0; }; } else if (task_->GetDynamicTypeOfTask() == ppc::core::TypeOfTask::kOMP) { const double t0 = omp_get_wtime(); perf_attrs.current_timer = [t0] { return omp_get_wtime() - t0; }; } else if (task_->GetDynamicTypeOfTask() == ppc::core::TypeOfTask::kSEQ || - task_->GetDynamicTypeOfTask() == ppc::core::TypeOfTask::kSTL) { + task_->GetDynamicTypeOfTask() == ppc::core::TypeOfTask::kSTL || + task_->GetDynamicTypeOfTask() == ppc::core::TypeOfTask::kTBB) { const auto t0 = std::chrono::high_resolution_clock::now(); perf_attrs.current_timer = [&] { auto now = std::chrono::high_resolution_clock::now(); @@ -88,9 +86,7 @@ class BaseRunPerfTests : public ::testing::TestWithParam + +#include "core/util/include/perf_test_util.hpp" + +double ppc::util::GetTimeMPI() { return MPI_Wtime(); } + +int ppc::util::GetMPIRank() { + int rank = -1; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + return rank; +} diff --git a/tasks/example_processes/mpi/include/ops_mpi.hpp b/tasks/example_processes/mpi/include/ops_mpi.hpp index 8dbc23eed..2d80c6d57 100644 --- a/tasks/example_processes/mpi/include/ops_mpi.hpp +++ b/tasks/example_processes/mpi/include/ops_mpi.hpp @@ -1,7 +1,5 @@ #pragma once -#include - #include "core/task/include/task.hpp" #include "example_processes/common/include/common.hpp" diff --git a/tasks/example_processes/tests/functional/main.cpp b/tasks/example_processes/tests/functional/main.cpp index 7e1e3fa47..424f6588a 100644 --- a/tasks/example_processes/tests/functional/main.cpp +++ b/tasks/example_processes/tests/functional/main.cpp @@ -68,9 +68,11 @@ const auto kTestTasksList = std::tuple_cat(ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_example_processes), ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_example_processes)); -INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTestsProcesses, - ppc::util::ExpandToValues(kTestTasksList), - NesterovARunFuncTestsProcesses::PrintFuncTestName); +const auto kGtestValues = ppc::util::ExpandToValues(kTestTasksList); + +const auto kPerfTestName = NesterovARunFuncTestsProcesses::PrintFuncTestName; + +INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTestsProcesses, kGtestValues, kPerfTestName); } // namespace diff --git a/tasks/example_processes/tests/performance/main.cpp b/tasks/example_processes/tests/performance/main.cpp index 7a9f2a59a..163e9c284 100644 --- a/tasks/example_processes/tests/performance/main.cpp +++ b/tasks/example_processes/tests/performance/main.cpp @@ -3,7 +3,6 @@ #include #include "core/util/include/perf_test_util.hpp" -#include "core/util/include/util.hpp" #include "example_processes/common/include/common.hpp" #include "example_processes/mpi/include/ops_mpi.hpp" #include "example_processes/seq/include/ops_seq.hpp" @@ -26,7 +25,10 @@ TEST_P(ExampleRunPerfTestProcesses, RunPerfModes) { ExecuteTest(GetParam()); } const auto kAllPerfTasks = ppc::util::MakeAllPerfTasks(PPC_SETTINGS_example_processes); -INSTANTIATE_TEST_SUITE_P(RunModeTests, ExampleRunPerfTestProcesses, ppc::util::TupleToGTestValues(kAllPerfTasks), - ExampleRunPerfTestProcesses::CustomPerfTestName); +const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); + +const auto kPerfTestName = ExampleRunPerfTestProcesses::CustomPerfTestName; + +INSTANTIATE_TEST_SUITE_P(RunModeTests, ExampleRunPerfTestProcesses, kGtestValues, kPerfTestName); } // namespace nesterov_a_test_task_processes diff --git a/tasks/example_threads/tests/functional/main.cpp b/tasks/example_threads/tests/functional/main.cpp index 43a444c98..fb5f56365 100644 --- a/tasks/example_threads/tests/functional/main.cpp +++ b/tasks/example_threads/tests/functional/main.cpp @@ -74,8 +74,11 @@ const auto kTestTasksList = ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_example_threads), ppc::util::AddFuncTask(kTestParam, PPC_SETTINGS_example_threads)); -INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTestsThreads, ppc::util::ExpandToValues(kTestTasksList), - NesterovARunFuncTestsThreads::PrintFuncTestName); +const auto kGtestValues = ppc::util::ExpandToValues(kTestTasksList); + +const auto kPerfTestName = NesterovARunFuncTestsThreads::PrintFuncTestName; + +INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTestsThreads, kGtestValues, kPerfTestName); } // namespace diff --git a/tasks/example_threads/tests/performance/main.cpp b/tasks/example_threads/tests/performance/main.cpp index ae99bf7ad..d889d6748 100644 --- a/tasks/example_threads/tests/performance/main.cpp +++ b/tasks/example_threads/tests/performance/main.cpp @@ -1,9 +1,6 @@ #include -#include - #include "core/util/include/perf_test_util.hpp" -#include "core/util/include/util.hpp" #include "example_threads/all/include/ops_all.hpp" #include "example_threads/common/include/common.hpp" #include "example_threads/omp/include/ops_omp.hpp" @@ -30,7 +27,10 @@ const auto kAllPerfTasks = ppc::util::MakeAllPerfTasks(PPC_SETTINGS_example_threads); -INSTANTIATE_TEST_SUITE_P(RunModeTests, ExampleRunPerfTestThreads, ppc::util::TupleToGTestValues(kAllPerfTasks), - ExampleRunPerfTestThreads::CustomPerfTestName); +const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); + +const auto kPerfTestName = ExampleRunPerfTestThreads::CustomPerfTestName; + +INSTANTIATE_TEST_SUITE_P(RunModeTests, ExampleRunPerfTestThreads, kGtestValues, kPerfTestName); } // namespace nesterov_a_test_task_threads From 5b95764d38df557a2707c45875a0e170513758c6 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 22:50:50 +0200 Subject: [PATCH 094/141] Refactor test folder structure, update imports, adjust CMake and Codecov ignore patterns for consistency --- .github/workflows/main.yml | 13 +++++-------- codecov.yml | 9 +++++---- modules/core/CMakeLists.txt | 2 +- .../core/perf/{func_tests => tests}/perf_tests.cpp | 2 +- .../core/perf/{func_tests => tests}/test_task.hpp | 0 .../core/task/{func_tests => tests}/task_tests.cpp | 2 +- .../core/task/{func_tests => tests}/test_task.hpp | 0 modules/core/util/{func_tests => tests}/util.cpp | 0 8 files changed, 13 insertions(+), 15 deletions(-) rename modules/core/perf/{func_tests => tests}/perf_tests.cpp (98%) rename modules/core/perf/{func_tests => tests}/test_task.hpp (100%) rename modules/core/task/{func_tests => tests}/task_tests.cpp (98%) rename modules/core/task/{func_tests => tests}/test_task.hpp (100%) rename modules/core/util/{func_tests => tests}/util.cpp (100%) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 20b6a3bd2..1654521f2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1038,14 +1038,11 @@ jobs: gcovr -r ../ \ --exclude '.*3rdparty/.*' \ --exclude '/usr/.*' \ - --exclude '.*/perf_tests/.*' \ - --exclude '.*/func_tests/.*' \ - --exclude '.*/all/runner.cpp' \ - --exclude '.*/mpi/runner.cpp' \ - --exclude '.*/omp/runner.cpp' \ - --exclude '.*/seq/runner.cpp' \ - --exclude '.*/stl/runner.cpp' \ - --exclude '.*/tbb/runner.cpp' \ + --exclude '.*tasks/.*/tests/.*' \ + --exclude '.*tasks/common/runners/.*' \ + --exclude '.*modules/core/util/include/perf_test_util.hpp' \ + --exclude '.*modules/core/util/include/func_test_util.hpp' \ + --exclude '.*modules/core/util/src/func_test_util.cpp' \ --xml --output ../coverage.xml \ --html=../cov-report/index.html --html-details - name: Upload coverage reports to Codecov diff --git a/codecov.yml b/codecov.yml index 0a7fa368d..ad21bc6f5 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,8 +1,9 @@ ignore: - - "**/tasks/**/tests/**" - - "**/tasks/common/runners/**" - - "**/modules/core/util/include/func_test_util.hpp" - - "**/modules/core/util/include/perf_test_util.hpp" + - "tasks/**/tests/**" + - "tasks/common/runners/**" + - "modules/core/util/include/perf_test_util.hpp" + - "modules/core/util/include/func_test_util.hpp" + - "modules/core/util/src/func_test_util.cpp" coverage: status: project: diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index b5ddbea93..a9792eefe 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -15,7 +15,7 @@ foreach(subd ${subdirs}) file(GLOB_RECURSE TMP_LIB_SOURCE_FILES ${PATH_PREFIX}/include/* ${PATH_PREFIX}/src/*) list(APPEND LIB_SOURCE_FILES ${TMP_LIB_SOURCE_FILES}) - file(GLOB_RECURSE TMP_FUNC_TESTS_SOURCE_FILES ${PATH_PREFIX}/func_tests/*) + file(GLOB_RECURSE TMP_FUNC_TESTS_SOURCE_FILES ${PATH_PREFIX}/tests/*) list(APPEND FUNC_TESTS_SOURCE_FILES ${TMP_FUNC_TESTS_SOURCE_FILES}) endforeach() diff --git a/modules/core/perf/func_tests/perf_tests.cpp b/modules/core/perf/tests/perf_tests.cpp similarity index 98% rename from modules/core/perf/func_tests/perf_tests.cpp rename to modules/core/perf/tests/perf_tests.cpp index 495c9f891..57767f71d 100644 --- a/modules/core/perf/func_tests/perf_tests.cpp +++ b/modules/core/perf/tests/perf_tests.cpp @@ -5,8 +5,8 @@ #include #include -#include "core/perf/func_tests/test_task.hpp" #include "core/perf/include/perf.hpp" +#include "core/perf/tests/test_task.hpp" TEST(perf_tests, check_perf_pipeline) { // Create data diff --git a/modules/core/perf/func_tests/test_task.hpp b/modules/core/perf/tests/test_task.hpp similarity index 100% rename from modules/core/perf/func_tests/test_task.hpp rename to modules/core/perf/tests/test_task.hpp diff --git a/modules/core/task/func_tests/task_tests.cpp b/modules/core/task/tests/task_tests.cpp similarity index 98% rename from modules/core/task/func_tests/task_tests.cpp rename to modules/core/task/tests/task_tests.cpp index ff09b10e6..ec16979af 100644 --- a/modules/core/task/func_tests/task_tests.cpp +++ b/modules/core/task/tests/task_tests.cpp @@ -4,7 +4,7 @@ #include #include -#include "core/task/func_tests/test_task.hpp" +#include "core/task/tests/test_task.hpp" #include "core/util/include/util.hpp" TEST(task_tests, check_int32_t) { diff --git a/modules/core/task/func_tests/test_task.hpp b/modules/core/task/tests/test_task.hpp similarity index 100% rename from modules/core/task/func_tests/test_task.hpp rename to modules/core/task/tests/test_task.hpp diff --git a/modules/core/util/func_tests/util.cpp b/modules/core/util/tests/util.cpp similarity index 100% rename from modules/core/util/func_tests/util.cpp rename to modules/core/util/tests/util.cpp From 82ec6f3eb9bc62d144fb58bc59e240a702b95397 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 23:02:16 +0200 Subject: [PATCH 095/141] Remove `run_perf_counter.py`, `performance-list` option, and related GitHub Action steps for unused performance counting functionality. --- .github/workflows/main.yml | 6 ----- scripts/run_perf_counter.py | 48 ------------------------------------- scripts/run_tests.py | 7 +----- 3 files changed, 1 insertion(+), 60 deletions(-) delete mode 100644 scripts/run_perf_counter.py diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1654521f2..01903ef08 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1078,12 +1078,6 @@ jobs: run: | mkdir -p install tar -xzvf ubuntu-gcc-install-ubuntu-24.04.tar.gz -C install - - name: Run perf count checker - run: | - python3 scripts/run_perf_counter.py --required-tests-number=2 - env: - PPC_NUM_THREADS: 2 - PPC_NUM_PROC: 2 - name: Run perf tests run: | bash -e scripts/generate_perf_results.sh diff --git a/scripts/run_perf_counter.py b/scripts/run_perf_counter.py deleted file mode 100644 index f8840fcbe..000000000 --- a/scripts/run_perf_counter.py +++ /dev/null @@ -1,48 +0,0 @@ -import subprocess -import re -import sys -from pathlib import Path - - -def init_cmd_args(): - import argparse - parser = argparse.ArgumentParser() - parser.add_argument( - "--required-tests-number", - required=True, - type=int, - help="Specify the number of tests to run (must be an integer)." - ) - args = parser.parse_args() - _args_dict = vars(args) - return _args_dict - - -def get_project_path(): - script_path = Path(__file__).resolve() - script_dir = script_path.parent - return script_dir.parent - - -def run_script(_script_path): - result = subprocess.run( - f"{sys.executable} {_script_path} --running-type=performance-list", shell=True, capture_output=True, text=True) - if result.returncode != 0: - raise Exception(f"Subprocess return {result.returncode}.") - - print(result.stdout) - print(result.stderr) - return result.stdout.splitlines() - - -if __name__ == "__main__": - args_dict = init_cmd_args() - tests_list = run_script(Path(get_project_path()) / "scripts/run_tests.py") - tests_number = int((len(tests_list) / 3) * 2) - - pattern = r".*GetParam().*" - test_matches = [test_name for test_name in tests_list if re.match(pattern, test_name)] - required_tests_number = int((args_dict["required_tests_number"] + 1) * len(test_matches) / 3) - - if tests_number != required_tests_number: - raise Exception(f"Count of all tests {tests_number} != count of required tests {required_tests_number}.") diff --git a/scripts/run_tests.py b/scripts/run_tests.py index 1119a6052..6bc6cafad 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -10,7 +10,7 @@ def init_cmd_args(): parser.add_argument( "--running-type", required=True, - choices=["threads", "processes", "performance", "performance-list"], + choices=["threads", "processes", "performance"], help="Specify the execution mode. Choose 'threads' for multithreading or 'processes' for multiprocessing." ) parser.add_argument( @@ -112,9 +112,6 @@ def run_performance(self): for task_type in ["omp", "seq", "stl", "tbb"]: self.__run_exec(f"{self.work_dir / 'ppc_perf_tests'} {self.__get_gtest_settings(1, '_' + task_type)}") - def run_performance_list(self): - self.__run_exec(f"{self.work_dir / 'ppc_perf_tests'} --gtest_list_tests") - if __name__ == "__main__": args_dict = init_cmd_args() @@ -130,7 +127,5 @@ def run_performance_list(self): ppc_runner.run_processes(args_dict["additional_mpi_args"]) elif args_dict["running_type"] == "performance": ppc_runner.run_performance() - elif args_dict["running_type"] == "performance-list": - ppc_runner.run_performance_list() else: raise Exception("running-type is wrong!") From d1f9626d4001187cf65b71ec70a0c61dba7594cd Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 23:34:33 +0200 Subject: [PATCH 096/141] Simplify apt package list in static analysis GitHub workflow by removing unused MPI-related dependencies. --- .github/workflows/static-analysis-pr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/static-analysis-pr.yml b/.github/workflows/static-analysis-pr.yml index e5aa5c86c..b9dcae8fa 100644 --- a/.github/workflows/static-analysis-pr.yml +++ b/.github/workflows/static-analysis-pr.yml @@ -24,7 +24,7 @@ jobs: id: review with: build_dir: build - apt_packages: mpich,libmpich*,mpi*,openmpi-bin,ninja-build,libomp-19-dev,valgrind + apt_packages: libmpich-dev,ninja-build,libomp-19-dev,valgrind cmake_command: > cmake -S . -B build -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache @@ -57,7 +57,7 @@ jobs: id: review with: build_dir: build - apt_packages: mpich,libmpich*,mpi*,openmpi-bin,ninja-build,libomp-19-dev,valgrind + apt_packages: libmpich-dev,ninja-build,libomp-19-dev,valgrind cmake_command: > cmake -S . -B build -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache From ab415f8a0d8185c8e89509283ecb53bfab7ec4f3 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 8 Jun 2025 23:59:16 +0200 Subject: [PATCH 097/141] Replace `libmpich-dev` with OpenMPI packages in static analysis workflow for improved compatibility. --- .github/workflows/static-analysis-pr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/static-analysis-pr.yml b/.github/workflows/static-analysis-pr.yml index b9dcae8fa..379f68402 100644 --- a/.github/workflows/static-analysis-pr.yml +++ b/.github/workflows/static-analysis-pr.yml @@ -24,7 +24,7 @@ jobs: id: review with: build_dir: build - apt_packages: libmpich-dev,ninja-build,libomp-19-dev,valgrind + apt_packages: openmpi-bin,openmpi-common,libopenmpi-dev,ninja-build,libomp-19-dev,valgrind cmake_command: > cmake -S . -B build -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache @@ -57,7 +57,7 @@ jobs: id: review with: build_dir: build - apt_packages: libmpich-dev,ninja-build,libomp-19-dev,valgrind + apt_packages: openmpi-bin,openmpi-common,libopenmpi-dev,ninja-build,libomp-19-dev,valgrind cmake_command: > cmake -S . -B build -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache From 149f0e014aa3574aec86d232430f2b5a06075d21 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Mon, 9 Jun 2025 00:02:36 +0200 Subject: [PATCH 098/141] Update GitHub Actions and Codecov ignore patterns to exclude module test directories. --- .github/workflows/main.yml | 1 + codecov.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 01903ef08..2c4a2589e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1039,6 +1039,7 @@ jobs: --exclude '.*3rdparty/.*' \ --exclude '/usr/.*' \ --exclude '.*tasks/.*/tests/.*' \ + --exclude '.*modules/.*/tests/.*' \ --exclude '.*tasks/common/runners/.*' \ --exclude '.*modules/core/util/include/perf_test_util.hpp' \ --exclude '.*modules/core/util/include/func_test_util.hpp' \ diff --git a/codecov.yml b/codecov.yml index ad21bc6f5..c0647754f 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,5 +1,6 @@ ignore: - "tasks/**/tests/**" + - "modules/**/tests/**" - "tasks/common/runners/**" - "modules/core/util/include/perf_test_util.hpp" - "modules/core/util/include/func_test_util.hpp" From c1e553079bebe9bae27b6b61092288761107b568 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Fri, 13 Jun 2025 00:05:47 +0200 Subject: [PATCH 099/141] Adjust performance test parameters and computation to improve consistency across modules. --- modules/core/perf/include/perf.hpp | 4 ++-- tasks/example_processes/tests/performance/main.cpp | 2 +- tasks/example_threads/tests/performance/main.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/core/perf/include/perf.hpp b/modules/core/perf/include/perf.hpp index 54e31ac9a..0190562c5 100644 --- a/modules/core/perf/include/perf.hpp +++ b/modules/core/perf/include/perf.hpp @@ -15,7 +15,7 @@ namespace ppc::core { struct PerfAttr { // count of task's running - uint64_t num_running = 10; + uint64_t num_running = 5; std::function current_timer = [&] { return -1.0; }; }; @@ -102,7 +102,7 @@ class Perf { pipeline(); } auto end = perf_attr.current_timer(); - perf_results.time_sec = end - begin; + perf_results.time_sec = (end - begin) / perf_attr.num_running; } }; diff --git a/tasks/example_processes/tests/performance/main.cpp b/tasks/example_processes/tests/performance/main.cpp index 163e9c284..2a192ce2f 100644 --- a/tasks/example_processes/tests/performance/main.cpp +++ b/tasks/example_processes/tests/performance/main.cpp @@ -10,7 +10,7 @@ namespace nesterov_a_test_task_processes { class ExampleRunPerfTestProcesses : public ppc::util::BaseRunPerfTests { - const int kCount_ = 111; + const int kCount_ = 200; InType input_data_{}; void SetUp() override { input_data_ = kCount_; } diff --git a/tasks/example_threads/tests/performance/main.cpp b/tasks/example_threads/tests/performance/main.cpp index d889d6748..a49731afa 100644 --- a/tasks/example_threads/tests/performance/main.cpp +++ b/tasks/example_threads/tests/performance/main.cpp @@ -11,7 +11,7 @@ namespace nesterov_a_test_task_threads { class ExampleRunPerfTestThreads : public ppc::util::BaseRunPerfTests { - const int kCount_ = 111; + const int kCount_ = 200; InType input_data_{}; void SetUp() override { input_data_ = kCount_; } From 9aadb7241507614bb778fc8f3087c936b4f64e21 Mon Sep 17 00:00:00 2001 From: Nesterov Alexander Date: Fri, 13 Jun 2025 18:53:41 +0200 Subject: [PATCH 100/141] Update CMakeLists.txt Co-authored-by: Arseniy Obolenskiy --- tasks/example_processes/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/example_processes/CMakeLists.txt b/tasks/example_processes/CMakeLists.txt index 2c6bfd2ac..af92b2ab9 100644 --- a/tasks/example_processes/CMakeLists.txt +++ b/tasks/example_processes/CMakeLists.txt @@ -35,7 +35,7 @@ foreach (dir_type ${technologies}) endif () # Print type of directories - message(STATUS "-- -- ${dir_type}") + message(STATUS " -- ${dir_type}") # Create task library file(GLOB_RECURSE lib_source_files "${base_dir}/include/*" "${base_dir}/src/*") From d3842c75c87847e5025317971683efc173fca43c Mon Sep 17 00:00:00 2001 From: Nesterov Alexander Date: Fri, 13 Jun 2025 20:28:08 +0200 Subject: [PATCH 101/141] Update settings.json --- tasks/example_processes/settings.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tasks/example_processes/settings.json b/tasks/example_processes/settings.json index 8094719ab..b1a0d5257 100644 --- a/tasks/example_processes/settings.json +++ b/tasks/example_processes/settings.json @@ -3,9 +3,5 @@ "tasks": { "mpi": "enabled", "seq": "enabled" - }, - "plagiarism": { - "mpi": "original", - "seq": "original" } } From 201a6d3f4ee892a7d8f1d2a8b309bd2f1cf8d6b5 Mon Sep 17 00:00:00 2001 From: Nesterov Alexander Date: Fri, 13 Jun 2025 20:28:43 +0200 Subject: [PATCH 102/141] Update settings.json --- tasks/example_threads/settings.json | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tasks/example_threads/settings.json b/tasks/example_threads/settings.json index c9f530450..f8c285c85 100644 --- a/tasks/example_threads/settings.json +++ b/tasks/example_threads/settings.json @@ -6,12 +6,5 @@ "seq": "enabled", "stl": "enabled", "tbb": "enabled" - }, - "plagiarism": { - "all": "original", - "omp": "plagiarized", - "seq": "original", - "stl": "original", - "tbb": "original" } } From 1df223e1825a6baf6438f8ba34f66572cbef8c13 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Fri, 13 Jun 2025 21:00:00 +0200 Subject: [PATCH 103/141] Replace `fmt::println` with `std::cerr` and `std::format` for error logging in functional and performance runners. --- tasks/common/runners/functional.cpp | 11 +++++++---- tasks/common/runners/performance.cpp | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/tasks/common/runners/functional.cpp b/tasks/common/runners/functional.cpp index d4052d5d3..0c5599948 100644 --- a/tasks/common/runners/functional.cpp +++ b/tasks/common/runners/functional.cpp @@ -4,6 +4,8 @@ #include #include +#include +#include #include #include #include @@ -27,10 +29,11 @@ class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status); if (flag != 0) { - fmt::println( - stderr, - "[ PROCESS {} ] [ FAILED ] {}.{}: MPI message queue has an unread message from process {} with tag {}", - rank, "test_suite_name", "test_name", status.MPI_SOURCE, status.MPI_TAG); + std::cerr << std::format( + "[ PROCESS {} ] [ FAILED ] {}.{}: MPI message queue has an unread message from process {} " + "with tag {}", + rank, "test_suite_name", "test_name", status.MPI_SOURCE, status.MPI_TAG) + << '\n'; MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); } diff --git a/tasks/common/runners/performance.cpp b/tasks/common/runners/performance.cpp index a32b13c25..3ebe7f6f3 100644 --- a/tasks/common/runners/performance.cpp +++ b/tasks/common/runners/performance.cpp @@ -4,6 +4,8 @@ #include #include +#include +#include #include #include #include @@ -27,10 +29,11 @@ class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status); if (flag != 0) { - fmt::println(stderr, - "[ PROCESS {} ] [ FAILED ] MPI message queue has an unread message from process {} with tag {}", - rank, status.MPI_SOURCE, status.MPI_TAG); - + std::cerr + << std::format( + "[ PROCESS {} ] [ FAILED ] MPI message queue has an unread message from process {} with tag {}", + rank, status.MPI_SOURCE, status.MPI_TAG) + << '\n'; MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); } From dc2f909f8220472911ff4f424d6a8019984479b6 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Fri, 13 Jun 2025 21:02:06 +0200 Subject: [PATCH 104/141] Add `private` access specifier for implementation methods in task headers --- tasks/example_processes/mpi/include/ops_mpi.hpp | 2 ++ tasks/example_processes/seq/include/ops_seq.hpp | 2 ++ tasks/example_threads/all/include/ops_all.hpp | 2 ++ tasks/example_threads/omp/include/ops_omp.hpp | 2 ++ tasks/example_threads/seq/include/ops_seq.hpp | 2 ++ tasks/example_threads/stl/include/ops_stl.hpp | 2 ++ tasks/example_threads/tbb/include/ops_tbb.hpp | 2 ++ 7 files changed, 14 insertions(+) diff --git a/tasks/example_processes/mpi/include/ops_mpi.hpp b/tasks/example_processes/mpi/include/ops_mpi.hpp index 2d80c6d57..7fc57c29f 100644 --- a/tasks/example_processes/mpi/include/ops_mpi.hpp +++ b/tasks/example_processes/mpi/include/ops_mpi.hpp @@ -9,6 +9,8 @@ class NesterovATestTaskMPI : public BaseTask { public: static constexpr ppc::core::TypeOfTask GetStaticTypeOfTask() { return ppc::core::TypeOfTask::kMPI; } explicit NesterovATestTaskMPI(const InType &in); + + private: bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; diff --git a/tasks/example_processes/seq/include/ops_seq.hpp b/tasks/example_processes/seq/include/ops_seq.hpp index 5c73ad682..3b8f03baf 100644 --- a/tasks/example_processes/seq/include/ops_seq.hpp +++ b/tasks/example_processes/seq/include/ops_seq.hpp @@ -9,6 +9,8 @@ class NesterovATestTaskSEQ : public BaseTask { public: static constexpr ppc::core::TypeOfTask GetStaticTypeOfTask() { return ppc::core::TypeOfTask::kSEQ; } explicit NesterovATestTaskSEQ(const InType& in); + + private: bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; diff --git a/tasks/example_threads/all/include/ops_all.hpp b/tasks/example_threads/all/include/ops_all.hpp index 9e5ba0ffc..9a2deade2 100644 --- a/tasks/example_threads/all/include/ops_all.hpp +++ b/tasks/example_threads/all/include/ops_all.hpp @@ -9,6 +9,8 @@ class NesterovATestTaskALL : public BaseTask { public: static constexpr ppc::core::TypeOfTask GetStaticTypeOfTask() { return ppc::core::TypeOfTask::kALL; } explicit NesterovATestTaskALL(const InType &in); + + private: bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; diff --git a/tasks/example_threads/omp/include/ops_omp.hpp b/tasks/example_threads/omp/include/ops_omp.hpp index e82c75b83..1fc5cd4c8 100644 --- a/tasks/example_threads/omp/include/ops_omp.hpp +++ b/tasks/example_threads/omp/include/ops_omp.hpp @@ -9,6 +9,8 @@ class NesterovATestTaskOMP : public BaseTask { public: static constexpr ppc::core::TypeOfTask GetStaticTypeOfTask() { return ppc::core::TypeOfTask::kOMP; } explicit NesterovATestTaskOMP(const InType& in); + + private: bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; diff --git a/tasks/example_threads/seq/include/ops_seq.hpp b/tasks/example_threads/seq/include/ops_seq.hpp index 5688226ca..dccae8530 100644 --- a/tasks/example_threads/seq/include/ops_seq.hpp +++ b/tasks/example_threads/seq/include/ops_seq.hpp @@ -9,6 +9,8 @@ class NesterovATestTaskSEQ : public BaseTask { public: static constexpr ppc::core::TypeOfTask GetStaticTypeOfTask() { return ppc::core::TypeOfTask::kSEQ; } explicit NesterovATestTaskSEQ(const InType& in); + + private: bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; diff --git a/tasks/example_threads/stl/include/ops_stl.hpp b/tasks/example_threads/stl/include/ops_stl.hpp index 503b89f13..554ac1e37 100644 --- a/tasks/example_threads/stl/include/ops_stl.hpp +++ b/tasks/example_threads/stl/include/ops_stl.hpp @@ -9,6 +9,8 @@ class NesterovATestTaskSTL : public BaseTask { public: static constexpr ppc::core::TypeOfTask GetStaticTypeOfTask() { return ppc::core::TypeOfTask::kSTL; } explicit NesterovATestTaskSTL(const InType& in); + + private: bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; diff --git a/tasks/example_threads/tbb/include/ops_tbb.hpp b/tasks/example_threads/tbb/include/ops_tbb.hpp index 4a637a529..d88ffafb5 100644 --- a/tasks/example_threads/tbb/include/ops_tbb.hpp +++ b/tasks/example_threads/tbb/include/ops_tbb.hpp @@ -9,6 +9,8 @@ class NesterovATestTaskTBB : public BaseTask { public: static constexpr ppc::core::TypeOfTask GetStaticTypeOfTask() { return ppc::core::TypeOfTask::kTBB; } explicit NesterovATestTaskTBB(const InType& in); + + private: bool ValidationImpl() override; bool PreProcessingImpl() override; bool RunImpl() override; From d9a890f0a2d656ed43ed19a8caacf228faf508a8 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Fri, 13 Jun 2025 21:05:09 +0200 Subject: [PATCH 105/141] Refine CMake library source file glob patterns to explicitly target .h, .hpp, and .cpp files. --- tasks/example_processes/CMakeLists.txt | 4 ++-- tasks/example_threads/CMakeLists.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tasks/example_processes/CMakeLists.txt b/tasks/example_processes/CMakeLists.txt index af92b2ab9..7c72af8f2 100644 --- a/tasks/example_processes/CMakeLists.txt +++ b/tasks/example_processes/CMakeLists.txt @@ -38,8 +38,8 @@ foreach (dir_type ${technologies}) message(STATUS " -- ${dir_type}") # Create task library - file(GLOB_RECURSE lib_source_files "${base_dir}/include/*" "${base_dir}/src/*") - file(GLOB source_files "${base_dir}/src/*") + file(GLOB_RECURSE lib_source_files "${base_dir}/include/*.h" "${base_dir}/include/*.hpp" "${base_dir}/src/*.cpp") + file(GLOB source_files "${base_dir}/src/*.cpp") list(LENGTH source_files result_length) set(name_lib "${TASK_NAME}_${dir_type}") diff --git a/tasks/example_threads/CMakeLists.txt b/tasks/example_threads/CMakeLists.txt index 2c6bfd2ac..1e330815f 100644 --- a/tasks/example_threads/CMakeLists.txt +++ b/tasks/example_threads/CMakeLists.txt @@ -38,8 +38,8 @@ foreach (dir_type ${technologies}) message(STATUS "-- -- ${dir_type}") # Create task library - file(GLOB_RECURSE lib_source_files "${base_dir}/include/*" "${base_dir}/src/*") - file(GLOB source_files "${base_dir}/src/*") + file(GLOB_RECURSE lib_source_files "${base_dir}/include/*.h" "${base_dir}/include/*.hpp" "${base_dir}/src/*.cpp") + file(GLOB source_files "${base_dir}/src/*.cpp") list(LENGTH source_files result_length) set(name_lib "${TASK_NAME}_${dir_type}") From 26048443b4d6403678659888428b3be0604a3557 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sat, 14 Jun 2025 00:25:44 +0200 Subject: [PATCH 106/141] Replace `fmt` with `std::format` and `std::cerr`, adjust test suite instantiations with `_NOLINT`, and correct performance metric computation. --- modules/core/perf/include/perf.hpp | 2 +- tasks/common/runners/functional.cpp | 4 ++-- tasks/common/runners/performance.cpp | 4 ++-- tasks/example_processes/tests/performance/main.cpp | 4 +--- tasks/example_threads/tests/performance/main.cpp | 2 +- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/modules/core/perf/include/perf.hpp b/modules/core/perf/include/perf.hpp index 0190562c5..2373c8296 100644 --- a/modules/core/perf/include/perf.hpp +++ b/modules/core/perf/include/perf.hpp @@ -102,7 +102,7 @@ class Perf { pipeline(); } auto end = perf_attr.current_timer(); - perf_results.time_sec = (end - begin) / perf_attr.num_running; + perf_results.time_sec = (end - begin) / static_cast(perf_attr.num_running); } }; diff --git a/tasks/common/runners/functional.cpp b/tasks/common/runners/functional.cpp index 0c5599948..44742e009 100644 --- a/tasks/common/runners/functional.cpp +++ b/tasks/common/runners/functional.cpp @@ -1,9 +1,9 @@ -#include #include #include #include #include +#include #include #include #include @@ -67,7 +67,7 @@ class WorkerTestFailurePrinter : public ::testing::EmptyTestEventListener { static void PrintProcessRank() { int rank = -1; MPI_Comm_rank(MPI_COMM_WORLD, &rank); - fmt::print(" [ PROCESS {} ] ", rank); + std::cerr << std::format(" [ PROCESS {} ] ", rank); } std::shared_ptr<::testing::TestEventListener> base_; diff --git a/tasks/common/runners/performance.cpp b/tasks/common/runners/performance.cpp index 3ebe7f6f3..02091091b 100644 --- a/tasks/common/runners/performance.cpp +++ b/tasks/common/runners/performance.cpp @@ -1,9 +1,9 @@ -#include #include #include #include #include +#include #include #include #include @@ -67,7 +67,7 @@ class WorkerTestFailurePrinter : public ::testing::EmptyTestEventListener { static void PrintProcessRank() { int rank = -1; MPI_Comm_rank(MPI_COMM_WORLD, &rank); - fmt::print(" [ PROCESS {} ] ", rank); + std::cerr << std::format(" [ PROCESS {} ] ", rank); } std::shared_ptr<::testing::TestEventListener> base_; diff --git a/tasks/example_processes/tests/performance/main.cpp b/tasks/example_processes/tests/performance/main.cpp index 2a192ce2f..385b45a47 100644 --- a/tasks/example_processes/tests/performance/main.cpp +++ b/tasks/example_processes/tests/performance/main.cpp @@ -1,7 +1,5 @@ #include -#include - #include "core/util/include/perf_test_util.hpp" #include "example_processes/common/include/common.hpp" #include "example_processes/mpi/include/ops_mpi.hpp" @@ -29,6 +27,6 @@ const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); const auto kPerfTestName = ExampleRunPerfTestProcesses::CustomPerfTestName; -INSTANTIATE_TEST_SUITE_P(RunModeTests, ExampleRunPerfTestProcesses, kGtestValues, kPerfTestName); +INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, ExampleRunPerfTestProcesses, kGtestValues, kPerfTestName); } // namespace nesterov_a_test_task_processes diff --git a/tasks/example_threads/tests/performance/main.cpp b/tasks/example_threads/tests/performance/main.cpp index a49731afa..5dc6672d9 100644 --- a/tasks/example_threads/tests/performance/main.cpp +++ b/tasks/example_threads/tests/performance/main.cpp @@ -31,6 +31,6 @@ const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); const auto kPerfTestName = ExampleRunPerfTestThreads::CustomPerfTestName; -INSTANTIATE_TEST_SUITE_P(RunModeTests, ExampleRunPerfTestThreads, kGtestValues, kPerfTestName); +INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, ExampleRunPerfTestThreads, kGtestValues, kPerfTestName); } // namespace nesterov_a_test_task_threads From 9d071075c5a2ccd69e0bd2df01ff9a512df205e1 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sat, 14 Jun 2025 00:57:40 +0200 Subject: [PATCH 107/141] Refactor functional and performance runners by extracting MPI-related logic into `ppc::core::Init` for improved modularity. --- modules/core/runners/include/runners.hpp | 28 +++++++ modules/core/runners/src/runners.cpp | 87 +++++++++++++++++++++ tasks/common/runners/functional.cpp | 91 +--------------------- tasks/common/runners/performance.cpp | 97 +----------------------- 4 files changed, 119 insertions(+), 184 deletions(-) create mode 100644 modules/core/runners/include/runners.hpp create mode 100644 modules/core/runners/src/runners.cpp diff --git a/modules/core/runners/include/runners.hpp b/modules/core/runners/include/runners.hpp new file mode 100644 index 000000000..e490a8e43 --- /dev/null +++ b/modules/core/runners/include/runners.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include + +namespace ppc::core { + +class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { + public: + UnreadMessagesDetector() = default; + void OnTestEnd(const ::testing::TestInfo& /*test_info*/) override; + + private: +}; + +class WorkerTestFailurePrinter : public ::testing::EmptyTestEventListener { + public: + explicit WorkerTestFailurePrinter(std::shared_ptr<::testing::TestEventListener> base) : base_(std::move(base)) {} + void OnTestEnd(const ::testing::TestInfo& test_info) override; + void OnTestPartResult(const ::testing::TestPartResult& test_part_result) override; + + private: + static void PrintProcessRank(); + std::shared_ptr<::testing::TestEventListener> base_; +}; + +int Init(int argc, char** argv); + +} // namespace ppc::core diff --git a/modules/core/runners/src/runners.cpp b/modules/core/runners/src/runners.cpp new file mode 100644 index 000000000..f36b46b65 --- /dev/null +++ b/modules/core/runners/src/runners.cpp @@ -0,0 +1,87 @@ +#include "core/runners/include/runners.hpp" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "core/util/include/util.hpp" +#include "oneapi/tbb/global_control.h" + +namespace ppc::core { + +void UnreadMessagesDetector::OnTestEnd(const ::testing::TestInfo& /*test_info*/) { + int rank = -1; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + MPI_Barrier(MPI_COMM_WORLD); + + int flag = -1; + MPI_Status status; + + MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status); + + if (flag != 0) { + std::cerr + << std::format( + "[ PROCESS {} ] [ FAILED ] MPI message queue has an unread message from process {} with tag {}", + rank, status.MPI_SOURCE, status.MPI_TAG) + << '\n'; + MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); + } + + MPI_Barrier(MPI_COMM_WORLD); +} + +void WorkerTestFailurePrinter::OnTestEnd(const ::testing::TestInfo& test_info) { + if (test_info.result()->Passed()) { + return; + } + PrintProcessRank(); + base_->OnTestEnd(test_info); +} + +void WorkerTestFailurePrinter::OnTestPartResult(const ::testing::TestPartResult& test_part_result) { + if (test_part_result.passed() || test_part_result.skipped()) { + return; + } + PrintProcessRank(); + base_->OnTestPartResult(test_part_result); +} + +void WorkerTestFailurePrinter::PrintProcessRank() { + int rank = -1; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + std::cerr << std::format(" [ PROCESS {} ] ", rank); +} + +int Init(int argc, char** argv) { + MPI_Init(&argc, &argv); + + // Limit the number of threads in TBB + tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetNumThreads()); + + ::testing::InitGoogleTest(&argc, argv); + + auto& listeners = ::testing::UnitTest::GetInstance()->listeners(); + int rank = -1; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + if (rank != 0 && (argc < 2 || argv[1] != std::string("--print-workers"))) { + auto* listener = listeners.Release(listeners.default_result_printer()); + listeners.Append(new ppc::core::WorkerTestFailurePrinter(std::shared_ptr<::testing::TestEventListener>(listener))); + } + listeners.Append(new ppc::core::UnreadMessagesDetector()); + auto status = RUN_ALL_TESTS(); + + MPI_Finalize(); + return status; +} + +} // namespace ppc::core diff --git a/tasks/common/runners/functional.cpp b/tasks/common/runners/functional.cpp index 44742e009..4a8b0e286 100644 --- a/tasks/common/runners/functional.cpp +++ b/tasks/common/runners/functional.cpp @@ -1,99 +1,12 @@ #include -#include -#include - -#include -#include -#include -#include -#include -#include -#include +#include "core/runners/include/runners.hpp" #include "core/util/include/util.hpp" #include "oneapi/tbb/global_control.h" -class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { - public: - UnreadMessagesDetector() = default; - - void OnTestEnd(const ::testing::TestInfo& /*test_info*/) override { - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - - MPI_Barrier(MPI_COMM_WORLD); - - int flag = -1; - MPI_Status status; - - MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status); - - if (flag != 0) { - std::cerr << std::format( - "[ PROCESS {} ] [ FAILED ] {}.{}: MPI message queue has an unread message from process {} " - "with tag {}", - rank, "test_suite_name", "test_name", status.MPI_SOURCE, status.MPI_TAG) - << '\n'; - MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); - } - - MPI_Barrier(MPI_COMM_WORLD); - } - - private: -}; - -class WorkerTestFailurePrinter : public ::testing::EmptyTestEventListener { - public: - explicit WorkerTestFailurePrinter(std::shared_ptr<::testing::TestEventListener> base) : base_(std::move(base)) {} - - void OnTestEnd(const ::testing::TestInfo& test_info) override { - if (test_info.result()->Passed()) { - return; - } - PrintProcessRank(); - base_->OnTestEnd(test_info); - } - - void OnTestPartResult(const ::testing::TestPartResult& test_part_result) override { - if (test_part_result.passed() || test_part_result.skipped()) { - return; - } - PrintProcessRank(); - base_->OnTestPartResult(test_part_result); - } - - private: - static void PrintProcessRank() { - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - std::cerr << std::format(" [ PROCESS {} ] ", rank); - } - - std::shared_ptr<::testing::TestEventListener> base_; -}; - int main(int argc, char** argv) { if (ppc::util::IsUnderMpirun()) { - MPI_Init(&argc, &argv); - - // Limit the number of threads in TBB - tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetNumThreads()); - - ::testing::InitGoogleTest(&argc, argv); - - auto& listeners = ::testing::UnitTest::GetInstance()->listeners(); - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - if (rank != 0 && (argc < 2 || argv[1] != std::string("--print-workers"))) { - auto* listener = listeners.Release(listeners.default_result_printer()); - listeners.Append(new WorkerTestFailurePrinter(std::shared_ptr<::testing::TestEventListener>(listener))); - } - listeners.Append(new UnreadMessagesDetector()); - auto status = RUN_ALL_TESTS(); - - MPI_Finalize(); - return status; + return ppc::core::Init(argc, argv); } // Limit the number of threads in TBB diff --git a/tasks/common/runners/performance.cpp b/tasks/common/runners/performance.cpp index 02091091b..83b9bd261 100644 --- a/tasks/common/runners/performance.cpp +++ b/tasks/common/runners/performance.cpp @@ -1,96 +1,3 @@ -#include -#include -#include +#include "core/runners/include/runners.hpp" -#include -#include -#include -#include -#include -#include -#include - -#include "core/util/include/util.hpp" -#include "oneapi/tbb/global_control.h" - -class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { - public: - UnreadMessagesDetector() = default; - - void OnTestEnd(const ::testing::TestInfo& /*test_info*/) override { - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - - MPI_Barrier(MPI_COMM_WORLD); - - int flag = -1; - MPI_Status status; - - MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status); - - if (flag != 0) { - std::cerr - << std::format( - "[ PROCESS {} ] [ FAILED ] MPI message queue has an unread message from process {} with tag {}", - rank, status.MPI_SOURCE, status.MPI_TAG) - << '\n'; - MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); - } - - MPI_Barrier(MPI_COMM_WORLD); - } - - private: -}; - -class WorkerTestFailurePrinter : public ::testing::EmptyTestEventListener { - public: - explicit WorkerTestFailurePrinter(std::shared_ptr<::testing::TestEventListener> base) : base_(std::move(base)) {} - - void OnTestEnd(const ::testing::TestInfo& test_info) override { - if (test_info.result()->Passed()) { - return; - } - PrintProcessRank(); - base_->OnTestEnd(test_info); - } - - void OnTestPartResult(const ::testing::TestPartResult& test_part_result) override { - if (test_part_result.passed() || test_part_result.skipped()) { - return; - } - PrintProcessRank(); - base_->OnTestPartResult(test_part_result); - } - - private: - static void PrintProcessRank() { - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - std::cerr << std::format(" [ PROCESS {} ] ", rank); - } - - std::shared_ptr<::testing::TestEventListener> base_; -}; - -int main(int argc, char** argv) { - MPI_Init(&argc, &argv); - - // Limit the number of threads in TBB - tbb::global_control control(tbb::global_control::max_allowed_parallelism, ppc::util::GetNumThreads()); - - ::testing::InitGoogleTest(&argc, argv); - - auto& listeners = ::testing::UnitTest::GetInstance()->listeners(); - int rank = -1; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - if (rank != 0 && (argc < 2 || argv[1] != std::string("--print-workers"))) { - auto* listener = listeners.Release(listeners.default_result_printer()); - listeners.Append(new WorkerTestFailurePrinter(std::shared_ptr<::testing::TestEventListener>(listener))); - } - listeners.Append(new UnreadMessagesDetector()); - auto status = RUN_ALL_TESTS(); - - MPI_Finalize(); - return status; -} +int main(int argc, char** argv) { return ppc::core::Init(argc, argv); } From 578d82956f6fa1147aa010920df5094c3d43ce2f Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sat, 14 Jun 2025 01:01:55 +0200 Subject: [PATCH 108/141] Rename `perf` module to `performance` across headers, sources, and tests for improved clarity and consistency. --- .../include/perf.hpp => performance/include/performance.hpp} | 0 modules/core/{perf => performance}/tests/perf_tests.cpp | 4 ++-- modules/core/{perf => performance}/tests/test_task.hpp | 0 modules/core/util/include/perf_test_util.hpp | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename modules/core/{perf/include/perf.hpp => performance/include/performance.hpp} (100%) rename modules/core/{perf => performance}/tests/perf_tests.cpp (97%) rename modules/core/{perf => performance}/tests/test_task.hpp (100%) diff --git a/modules/core/perf/include/perf.hpp b/modules/core/performance/include/performance.hpp similarity index 100% rename from modules/core/perf/include/perf.hpp rename to modules/core/performance/include/performance.hpp diff --git a/modules/core/perf/tests/perf_tests.cpp b/modules/core/performance/tests/perf_tests.cpp similarity index 97% rename from modules/core/perf/tests/perf_tests.cpp rename to modules/core/performance/tests/perf_tests.cpp index 57767f71d..0d46a741c 100644 --- a/modules/core/perf/tests/perf_tests.cpp +++ b/modules/core/performance/tests/perf_tests.cpp @@ -5,8 +5,8 @@ #include #include -#include "core/perf/include/perf.hpp" -#include "core/perf/tests/test_task.hpp" +#include "core/performance/include/performance.hpp" +#include "core/performance/tests/test_task.hpp" TEST(perf_tests, check_perf_pipeline) { // Create data diff --git a/modules/core/perf/tests/test_task.hpp b/modules/core/performance/tests/test_task.hpp similarity index 100% rename from modules/core/perf/tests/test_task.hpp rename to modules/core/performance/tests/test_task.hpp diff --git a/modules/core/util/include/perf_test_util.hpp b/modules/core/util/include/perf_test_util.hpp index 38140aa95..460f739ae 100644 --- a/modules/core/util/include/perf_test_util.hpp +++ b/modules/core/util/include/perf_test_util.hpp @@ -14,7 +14,7 @@ #include #include -#include "core/perf/include/perf.hpp" +#include "core/performance/include/performance.hpp" #include "core/task/include/task.hpp" #include "core/util/include/util.hpp" From daac04d959414072169c06fa83d0a1f231470be2 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sat, 14 Jun 2025 21:35:45 +0200 Subject: [PATCH 109/141] Anonymize student data in `example_processes` and `example_threads` task files. --- tasks/example_processes/info.json | 8 ++++---- tasks/example_threads/info.json | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tasks/example_processes/info.json b/tasks/example_processes/info.json index 61f220253..cfb6b22c4 100644 --- a/tasks/example_processes/info.json +++ b/tasks/example_processes/info.json @@ -1,8 +1,8 @@ { "student": { - "first_name": "Нестеров", - "last_name": "Александр", - "middle_name": "Юрьевич", - "group_number": "АБВ-123" + "first_name": "", + "last_name": "", + "middle_name": "", + "group_number": "" } } diff --git a/tasks/example_threads/info.json b/tasks/example_threads/info.json index 61f220253..cfb6b22c4 100644 --- a/tasks/example_threads/info.json +++ b/tasks/example_threads/info.json @@ -1,8 +1,8 @@ { "student": { - "first_name": "Нестеров", - "last_name": "Александр", - "middle_name": "Юрьевич", - "group_number": "АБВ-123" + "first_name": "", + "last_name": "", + "middle_name": "", + "group_number": "" } } From e16b65d9e09a2fbfa15164c53ef26e92077be5db Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sat, 14 Jun 2025 21:41:06 +0200 Subject: [PATCH 110/141] Include missing utility headers in `performance` test files and `runners` module; remove redundant include from `runners.cpp`. --- modules/core/runners/include/runners.hpp | 3 +++ modules/core/runners/src/runners.cpp | 1 - tasks/example_processes/tests/performance/main.cpp | 1 + tasks/example_threads/tests/performance/main.cpp | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/core/runners/include/runners.hpp b/modules/core/runners/include/runners.hpp index e490a8e43..bf04ec5f2 100644 --- a/modules/core/runners/include/runners.hpp +++ b/modules/core/runners/include/runners.hpp @@ -2,6 +2,9 @@ #include +#include +#include + namespace ppc::core { class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { diff --git a/modules/core/runners/src/runners.cpp b/modules/core/runners/src/runners.cpp index f36b46b65..92e98eec5 100644 --- a/modules/core/runners/src/runners.cpp +++ b/modules/core/runners/src/runners.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include "core/util/include/util.hpp" #include "oneapi/tbb/global_control.h" diff --git a/tasks/example_processes/tests/performance/main.cpp b/tasks/example_processes/tests/performance/main.cpp index 385b45a47..3c22a742b 100644 --- a/tasks/example_processes/tests/performance/main.cpp +++ b/tasks/example_processes/tests/performance/main.cpp @@ -1,6 +1,7 @@ #include #include "core/util/include/perf_test_util.hpp" +#include "core/util/include/util.hpp" #include "example_processes/common/include/common.hpp" #include "example_processes/mpi/include/ops_mpi.hpp" #include "example_processes/seq/include/ops_seq.hpp" diff --git a/tasks/example_threads/tests/performance/main.cpp b/tasks/example_threads/tests/performance/main.cpp index 5dc6672d9..a982cf4ac 100644 --- a/tasks/example_threads/tests/performance/main.cpp +++ b/tasks/example_threads/tests/performance/main.cpp @@ -1,6 +1,7 @@ #include #include "core/util/include/perf_test_util.hpp" +#include "core/util/include/util.hpp" #include "example_threads/all/include/ops_all.hpp" #include "example_threads/common/include/common.hpp" #include "example_threads/omp/include/ops_omp.hpp" From b6356f93163a86939415da8213d1998445ed347d Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sat, 14 Jun 2025 23:35:42 +0200 Subject: [PATCH 111/141] Simplify TBB library linking in `core` CMake configuration by using `${PPC_TBB_LIB_NAME}`. --- modules/core/CMakeLists.txt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index a9792eefe..6d51b05a2 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -54,11 +54,7 @@ target_link_libraries(${exec_func_lib} PUBLIC ${OpenMP_libomp_LIBRARY} OpenMP::O add_dependencies(${exec_func_lib} ppc_onetbb) target_link_directories(${exec_func_lib} PUBLIC ${CMAKE_BINARY_DIR}/ppc_onetbb/install/lib) if(NOT MSVC) - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - target_link_libraries(${exec_func_lib} PUBLIC tbb_debug) - else() - target_link_libraries(${exec_func_lib} PUBLIC tbb) - endif() + target_link_libraries(${exec_func_lib} PUBLIC ${PPC_TBB_LIB_NAME}) endif() find_package(MPI REQUIRED) From e4d463e7a967e571ddf34df0e99c5409b9b657e2 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 15 Jun 2025 00:42:17 +0200 Subject: [PATCH 112/141] Unify and streamline test configuration in `CMakeLists.txt` using helper functions; centralize reusable logic in `cmake/functions.cmake`. Remove `example_processes` and `example_threads` task-specific configurations. --- cmake/functions.cmake | 105 +++++++++++++++++++++++++ tasks/CMakeLists.txt | 73 +++++++++-------- tasks/example_processes/CMakeLists.txt | 58 -------------- tasks/example_threads/CMakeLists.txt | 58 -------------- 4 files changed, 140 insertions(+), 154 deletions(-) create mode 100644 cmake/functions.cmake delete mode 100644 tasks/example_processes/CMakeLists.txt delete mode 100644 tasks/example_threads/CMakeLists.txt diff --git a/cmake/functions.cmake b/cmake/functions.cmake new file mode 100644 index 000000000..e1cfcf669 --- /dev/null +++ b/cmake/functions.cmake @@ -0,0 +1,105 @@ +# ——— Helper function to add & register tests ————————————————————————— +function(ppc_add_test test_name test_src USE_FLAG) + if(${USE_FLAG}) + add_executable(${test_name} "${PROJECT_SOURCE_DIR}/${test_src}") + enable_testing() + add_test(NAME ${test_name} COMMAND ${test_name}) + install(TARGETS ${test_name} RUNTIME DESTINATION bin) + endif() +endfunction() + +# Function to configure tests +function(add_tests test_flag exec_target subdir) + if(${test_flag}) + # Gather all source files under tests/ + file(GLOB_RECURSE src_files + "${TEST_DIR}/${subdir}/*.cpp" + "${TEST_DIR}/${subdir}/*.cxx" + "${TEST_DIR}/${subdir}/*.cc" + ) + target_sources(${exec_target} PRIVATE ${src_files}) + list(APPEND TEST_EXECUTABLES ${exec_target}) + set(TEST_EXECUTABLES "${TEST_EXECUTABLES}" PARENT_SCOPE) + endif() +endfunction() + +# ============================================================================ +# Function: setup_implementation +# - NAME: implementation sub‐directory name (e.g. “mpi”) +# - PROJ_NAME: project base name +# - BASE_DIR: root source directory +# - TESTS: list of test executables to link against +# ============================================================================ +function(setup_implementation) + # parse named args: NAME, PROJ_NAME, BASE_DIR; multi‐value: TESTS + cmake_parse_arguments( + SETUP + "" # no plain options + "NAME;PROJ_NAME;BASE_DIR" + "TESTS" + ${ARGN} + ) + + # skip if impl dir doesn't exist + set(IMP_DIR "${SETUP_BASE_DIR}/${SETUP_NAME}") + if(NOT EXISTS "${IMP_DIR}") + return() + endif() + message(STATUS " -- ${SETUP_NAME}") + + # collect sources + file(GLOB_RECURSE CPP_SOURCES "${IMP_DIR}/src/*.cpp") + file(GLOB_RECURSE ALL_SOURCES + "${IMP_DIR}/include/*.h" + "${IMP_DIR}/include/*.hpp" + "${IMP_DIR}/src/*.cpp" + ) + + # create library (STATIC if .cpp exist, otherwise INTERFACE) + set(LIB_NAME "${SETUP_PROJ_NAME}_${SETUP_NAME}") + if(CPP_SOURCES) + add_library(${LIB_NAME} STATIC ${ALL_SOURCES}) + else() + add_library(${LIB_NAME} INTERFACE ${ALL_SOURCES}) + endif() + + # link core module + target_link_libraries(${LIB_NAME} PUBLIC core_module_lib) + + # and link into each enabled test executable + foreach(test_exec ${SETUP_TESTS}) + target_link_libraries(${test_exec} PUBLIC ${LIB_NAME}) + endforeach() +endfunction() + +# Function to configure each subproject +function(ppc_configure_subproject SUBDIR) + # Module-specific compile-time definitions + add_compile_definitions( + PPC_SETTINGS_${SUBDIR}="${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/settings.json" + PPC_ID_${SUBDIR}="${SUBDIR}" + ) + + # Switch project context to the subproject + project(${SUBDIR}) + + # Directory with tests and list of test executables (populated by setup_implementation) + set(TEST_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/tests") + set(TEST_EXECUTABLES "") + + # Register functional and performance test runners + add_tests(USE_FUNC_TESTS ${FUNC_TEST_EXEC} functional) + add_tests(USE_PERF_TESTS ${PERF_TEST_EXEC} performance) + + message(STATUS "${SUBDIR}") + + # List of implementations to configure + foreach(IMPL IN LISTS IMPLEMENTATIONS) + setup_implementation( + NAME ${IMPL} + PROJ_NAME ${SUBDIR} + TESTS "${TEST_EXECUTABLES}" + BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}" + ) + endforeach() +endfunction() diff --git a/tasks/CMakeLists.txt b/tasks/CMakeLists.txt index a424b52f1..9863ef1c1 100644 --- a/tasks/CMakeLists.txt +++ b/tasks/CMakeLists.txt @@ -1,44 +1,41 @@ +cmake_minimum_required(VERSION 3.15) +project(parallel_programming_course LANGUAGES C CXX) + message(STATUS "Student's tasks") -project("parallel_programming_course") -set(exec_func_tests "ppc_func_tests") -set(exec_perf_tests "ppc_perf_tests") - -# Init func tests executable files -set(list_of_exec_tests "") -if (USE_FUNC_TESTS) - add_executable(${exec_func_tests} "${CMAKE_CURRENT_SOURCE_DIR}/common/runners/functional.cpp") - list(APPEND list_of_exec_tests ${exec_func_tests}) -endif (USE_FUNC_TESTS) - -# Init perf tests executable files -if (USE_PERF_TESTS) - add_executable(${exec_perf_tests} "${CMAKE_CURRENT_SOURCE_DIR}/common/runners/performance.cpp") - list(APPEND list_of_exec_tests ${exec_perf_tests}) -endif (USE_PERF_TESTS) - -SUBDIRLIST(subdirs ${CMAKE_CURRENT_LIST_DIR}) -foreach(subd ${subdirs}) - if (subd STREQUAL "common") - continue() - endif () - - set(SETTINGS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${subd}/settings.json") - add_compile_definitions(PPC_SETTINGS_${subd}=\"${SETTINGS_PATH}\") - add_compile_definitions(PPC_ID_${subd}=\"${subd}\") - - add_subdirectory(${subd}) -endforeach() +# ——— Testing options ———————————————————————————————————————— +option(USE_FUNC_TESTS "Enable functional tests" OFF) +option(USE_PERF_TESTS "Enable performance tests" OFF) + +# Test runner executables +set(FUNC_TEST_EXEC ppc_func_tests) +set(PERF_TEST_EXEC ppc_perf_tests) -foreach (exec_func ${list_of_exec_tests}) - enable_testing() - add_test(NAME ${exec_func} COMMAND ${exec_func}) +# ——— Global compile definitions ————————————————————————————————————— +add_compile_definitions( + PATH_TO_PPC_PROJECT="${PROJECT_SOURCE_DIR}" +) - # Install the executable - install(TARGETS ${exec_func} RUNTIME DESTINATION bin) -endforeach () +# ——— Include helper scripts —————————————————————————————————————— +include(${CMAKE_SOURCE_DIR}/cmake/functions.cmake) -# Install the library -install(TARGETS ${name_lib} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) +# ——— Initialize test executables ————————————————————————————————————— +ppc_add_test(${FUNC_TEST_EXEC} common/runners/functional.cpp USE_FUNC_TESTS) +ppc_add_test(${PERF_TEST_EXEC} common/runners/performance.cpp USE_PERF_TESTS) + +# ——— List of implementations ———————————————————————————————————————— +set(IMPLEMENTATIONS all mpi omp seq stl tbb) + +# ——— Configure each subproject ————————————————————————————————————— +file(GLOB subdirs RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/*") +foreach(sub IN LISTS subdirs) + if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${sub}" AND NOT sub STREQUAL "common") + ppc_configure_subproject(${sub}) + endif() +endforeach() -add_compile_definitions(PATH_TO_PPC_PROJECT="${CMAKE_SOURCE_DIR}") +# ——— Install library target —————————————————————————————————————— +install(TARGETS ${name_lib} + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib +) diff --git a/tasks/example_processes/CMakeLists.txt b/tasks/example_processes/CMakeLists.txt deleted file mode 100644 index 7c72af8f2..000000000 --- a/tasks/example_processes/CMakeLists.txt +++ /dev/null @@ -1,58 +0,0 @@ -get_filename_component(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) -project(CURRENT_DIR_NAME) - -set(exec_func_tests "ppc_func_tests") -set(exec_perf_tests "ppc_perf_tests") -set(test_base_dir "${CMAKE_CURRENT_SOURCE_DIR}/tests") - -# Init func tests executable files -set(list_of_exec_tests "") -if (USE_FUNC_TESTS) - file(GLOB_RECURSE func_tests_source_files "${test_base_dir}/functional/*") - target_sources(${exec_func_tests} PRIVATE ${func_tests_source_files}) - list(APPEND list_of_exec_tests ${exec_func_tests}) -endif (USE_FUNC_TESTS) - -# Init perf tests executable files -if (USE_PERF_TESTS) - file(GLOB_RECURSE perf_tests_source_files "${test_base_dir}/performance/*") - target_sources(${exec_perf_tests} PRIVATE ${perf_tests_source_files}) - list(APPEND list_of_exec_tests ${exec_perf_tests}) -endif (USE_PERF_TESTS) - -# Print student task name -get_filename_component(TASK_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) -message(STATUS "-- ${TASK_NAME}") - -set(technologies "all" "mpi" "omp" "seq" "stl" "tbb") - -# Create lib -foreach (dir_type ${technologies}) - # Check directory existing - set(base_dir "${CMAKE_CURRENT_SOURCE_DIR}/${dir_type}") - if (NOT EXISTS "${base_dir}") - continue() - endif () - - # Print type of directories - message(STATUS " -- ${dir_type}") - - # Create task library - file(GLOB_RECURSE lib_source_files "${base_dir}/include/*.h" "${base_dir}/include/*.hpp" "${base_dir}/src/*.cpp") - file(GLOB source_files "${base_dir}/src/*.cpp") - - list(LENGTH source_files result_length) - set(name_lib "${TASK_NAME}_${dir_type}") - if(result_length EQUAL 0) - add_library(${name_lib} INTERFACE ${lib_source_files}) - else() - add_library(${name_lib} STATIC ${lib_source_files}) - endif() - set_target_properties(${name_lib} PROPERTIES LINKER_LANGUAGE CXX) - target_link_libraries(${name_lib} PUBLIC core_module_lib) - - # Link core library - foreach (exec_func ${list_of_exec_tests}) - target_link_libraries(${exec_func} PUBLIC ${name_lib}) - endforeach () -endforeach () diff --git a/tasks/example_threads/CMakeLists.txt b/tasks/example_threads/CMakeLists.txt deleted file mode 100644 index 1e330815f..000000000 --- a/tasks/example_threads/CMakeLists.txt +++ /dev/null @@ -1,58 +0,0 @@ -get_filename_component(CURRENT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) -project(CURRENT_DIR_NAME) - -set(exec_func_tests "ppc_func_tests") -set(exec_perf_tests "ppc_perf_tests") -set(test_base_dir "${CMAKE_CURRENT_SOURCE_DIR}/tests") - -# Init func tests executable files -set(list_of_exec_tests "") -if (USE_FUNC_TESTS) - file(GLOB_RECURSE func_tests_source_files "${test_base_dir}/functional/*") - target_sources(${exec_func_tests} PRIVATE ${func_tests_source_files}) - list(APPEND list_of_exec_tests ${exec_func_tests}) -endif (USE_FUNC_TESTS) - -# Init perf tests executable files -if (USE_PERF_TESTS) - file(GLOB_RECURSE perf_tests_source_files "${test_base_dir}/performance/*") - target_sources(${exec_perf_tests} PRIVATE ${perf_tests_source_files}) - list(APPEND list_of_exec_tests ${exec_perf_tests}) -endif (USE_PERF_TESTS) - -# Print student task name -get_filename_component(TASK_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) -message(STATUS "-- ${TASK_NAME}") - -set(technologies "all" "mpi" "omp" "seq" "stl" "tbb") - -# Create lib -foreach (dir_type ${technologies}) - # Check directory existing - set(base_dir "${CMAKE_CURRENT_SOURCE_DIR}/${dir_type}") - if (NOT EXISTS "${base_dir}") - continue() - endif () - - # Print type of directories - message(STATUS "-- -- ${dir_type}") - - # Create task library - file(GLOB_RECURSE lib_source_files "${base_dir}/include/*.h" "${base_dir}/include/*.hpp" "${base_dir}/src/*.cpp") - file(GLOB source_files "${base_dir}/src/*.cpp") - - list(LENGTH source_files result_length) - set(name_lib "${TASK_NAME}_${dir_type}") - if(result_length EQUAL 0) - add_library(${name_lib} INTERFACE ${lib_source_files}) - else() - add_library(${name_lib} STATIC ${lib_source_files}) - endif() - set_target_properties(${name_lib} PROPERTIES LINKER_LANGUAGE CXX) - target_link_libraries(${name_lib} PUBLIC core_module_lib) - - # Link core library - foreach (exec_func ${list_of_exec_tests}) - target_link_libraries(${exec_func} PUBLIC ${name_lib}) - endforeach () -endforeach () From bda42709be784e91fbcb627147d80d6749003e2e Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Sun, 15 Jun 2025 00:48:06 +0200 Subject: [PATCH 113/141] Simplify library linking in `core` CMake configuration by introducing `${PPC_ENVPP_LIB_NAME}` and `${PPC_FMT_LIB_NAME}` for streamlined dependency management. --- cmake/libenvpp.cmake | 13 +++++++++++++ modules/core/CMakeLists.txt | 14 ++------------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/cmake/libenvpp.cmake b/cmake/libenvpp.cmake index 8394879d5..449cd281e 100644 --- a/cmake/libenvpp.cmake +++ b/cmake/libenvpp.cmake @@ -12,3 +12,16 @@ ExternalProject_Add(ppc_libenvpp -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --config ${CMAKE_BUILD_TYPE} --parallel INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/install") + +string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_lower) +if(cmake_build_type_lower STREQUAL "debug") + set(PPC_FMT_LIB_NAME fmtd) +else() + set(PPC_FMT_LIB_NAME fmt) +endif() + +if(MSVC) + set(PPC_ENVPP_LIB_NAME libenvpp) +else() + set(PPC_ENVPP_LIB_NAME envpp) +endif () \ No newline at end of file diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index 6d51b05a2..26d597946 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -26,18 +26,8 @@ set_target_properties(${exec_func_lib} PROPERTIES LINKER_LANGUAGE CXX) add_dependencies(${exec_func_lib} ppc_libenvpp) target_link_directories(${exec_func_lib} PUBLIC "${CMAKE_BINARY_DIR}/ppc_libenvpp/install/lib") target_link_directories(${exec_func_lib} PUBLIC "${CMAKE_BINARY_DIR}/ppc_libenvpp/build") - -if(MSVC) - target_link_libraries(${exec_func_lib} PUBLIC libenvpp) -else() - target_link_libraries(${exec_func_lib} PUBLIC envpp) -endif () - -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - target_link_libraries(${exec_func_lib} PUBLIC fmtd) -else() - target_link_libraries(${exec_func_lib} PUBLIC fmt) -endif() +target_link_libraries(${exec_func_lib} PUBLIC ${PPC_ENVPP_LIB_NAME}) +target_link_libraries(${exec_func_lib} PUBLIC ${PPC_FMT_LIB_NAME}) add_dependencies(${exec_func_lib} ppc_json) target_link_directories(${exec_func_lib} INTERFACE "${CMAKE_BINARY_DIR}/ppc_json/install/include") From abbdf705c2fc5ccacb2878b7b48f2e4d04fbbe0f Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Mon, 16 Jun 2025 16:03:14 +0200 Subject: [PATCH 114/141] Unify and optimize GitHub workflows: - Consolidate `PPC_NUM_PROC` environment variable setup for functional and performance tests. - Standardize CMake configuration by deduplicating `-G Ninja` specification. - Update gcovr exclusions for more precise coverage reporting. - Add LLVM setup for Windows workflows to ensure correct compiler configuration. --- .github/workflows/codeql.yml | 3 +- .github/workflows/mac.yml | 22 ++++++---- .github/workflows/perf.yml | 8 +--- .github/workflows/static-analysis-pr.yml | 7 ++- .github/workflows/ubuntu.yml | 56 +++++++++++++++++------- .github/workflows/windows.yml | 28 ++++++++++-- 6 files changed, 82 insertions(+), 42 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 2c2989672..5b92d48fb 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -39,9 +39,8 @@ jobs: languages: ${{ matrix.language }} - name: CMake configure run: > - cmake -S . -B build + cmake -S . -B build -G Ninja -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -G Ninja -D CMAKE_BUILD_TYPE=RELEASE env: CC: gcc-14 diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index a14178ca4..87b184546 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -24,12 +24,11 @@ jobs: max-size: 1G - name: CMake configure run: > - cmake -S . -B build + cmake -S . -B build -G Ninja -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -G Ninja -DCMAKE_C_FLAGS="-I$(brew --prefix)/opt/libomp/include" + -DCMAKE_C_FLAGS="-I$(brew --prefix)/opt/libomp/include" -DCMAKE_CXX_FLAGS="-I$(brew --prefix)/opt/libomp/include" - -D CMAKE_BUILD_TYPE=RELEASE - -DCMAKE_INSTALL_PREFIX=install + -D CMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=install - name: Build project run: | cmake --build build --parallel @@ -66,12 +65,11 @@ jobs: max-size: 1G - name: CMake configure run: > - cmake -S . -B build + cmake -S . -B build -G Ninja -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -G Ninja -DCMAKE_C_FLAGS="-I$(brew --prefix)/opt/libomp/include" + -DCMAKE_C_FLAGS="-I$(brew --prefix)/opt/libomp/include" -DCMAKE_CXX_FLAGS="-I$(brew --prefix)/opt/libomp/include" - -D CMAKE_BUILD_TYPE=DEBUG - -DCMAKE_INSTALL_PREFIX=install + -D CMAKE_BUILD_TYPE=DEBUG -DCMAKE_INSTALL_PREFIX=install - name: Build project run: | cmake --build build --parallel @@ -131,18 +129,22 @@ jobs: - name: Run tests (threads, num_threads=1) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 1 - name: Run tests (threads, num_threads=2) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 2 - name: Run tests (threads, num_threads=3) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 3 - name: Run tests (threads, num_threads=4) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 4 macos-clang-test-extended: needs: @@ -169,16 +171,20 @@ jobs: - name: Run tests (threads, num_threads=5) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 5 - name: Run tests (threads, num_threads=7) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 7 - name: Run tests (threads, num_threads=11) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 11 - name: Run tests (threads, num_threads=13) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 13 diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index 4e45995de..96f1545d7 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -19,18 +19,12 @@ jobs: run: | mkdir -p install tar -xzvf ubuntu-gcc-install-ubuntu-24.04.tar.gz -C install - - name: Run perf count checker - run: | - python3 scripts/run_perf_counter.py --required-tests-number=2 - env: - PPC_NUM_THREADS: 2 - PPC_NUM_PROC: 2 - name: Run perf tests run: | bash -e scripts/generate_perf_results.sh env: - PPC_NUM_THREADS: 2 PPC_NUM_PROC: 2 + PPC_NUM_THREADS: 2 - name: Archive results uses: montudor/action-zip@v1 with: diff --git a/.github/workflows/static-analysis-pr.yml b/.github/workflows/static-analysis-pr.yml index 379f68402..1b1dd1441 100644 --- a/.github/workflows/static-analysis-pr.yml +++ b/.github/workflows/static-analysis-pr.yml @@ -26,9 +26,9 @@ jobs: build_dir: build apt_packages: openmpi-bin,openmpi-common,libopenmpi-dev,ninja-build,libomp-19-dev,valgrind cmake_command: > - cmake -S . -B build + cmake -S . -B build -G Ninja -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -G Ninja -D CMAKE_BUILD_TYPE=RELEASE -DCMAKE_EXPORT_COMPILE_COMMANDS=ON + -D CMAKE_BUILD_TYPE=RELEASE -DCMAKE_EXPORT_COMPILE_COMMANDS=ON config_file: .clang-tidy exclude: 3rdparty split_workflow: true @@ -59,9 +59,8 @@ jobs: build_dir: build apt_packages: openmpi-bin,openmpi-common,libopenmpi-dev,ninja-build,libomp-19-dev,valgrind cmake_command: > - cmake -S . -B build + cmake -S . -B build -G Ninja -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -G Ninja -D CMAKE_BUILD_TYPE=RELEASE -DCMAKE_EXPORT_COMPILE_COMMANDS=ON config_file: .clang-tidy exclude: 3rdparty diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 816d72fc2..ea0ad8761 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -24,9 +24,8 @@ jobs: max-size: 1G - name: CMake configure run: > - cmake -S . -B build + cmake -S . -B build -G Ninja -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -G Ninja -D CMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=install env: CC: gcc-14 @@ -76,9 +75,8 @@ jobs: max-size: 1G - name: CMake configure run: > - cmake -S . -B build + cmake -S . -B build -G Ninja -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -G Ninja -D CMAKE_BUILD_TYPE=DEBUG -DCMAKE_INSTALL_PREFIX=install env: CC: gcc-14 @@ -145,18 +143,22 @@ jobs: - name: Run func tests (threads, num_threads=1) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 1 - name: Run func tests (threads, num_threads=2) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 2 - name: Run func tests (threads, num_threads=3) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 3 - name: Run func tests (threads, num_threads=4) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 4 ubuntu-gcc-test-extended: needs: @@ -183,18 +185,22 @@ jobs: - name: Run func tests (threads, num_threads=5) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 5 - name: Run func tests (threads, num_threads=7) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 7 - name: Run func tests (threads, num_threads=11) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 11 - name: Run func tests (threads, num_threads=13) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 13 ubuntu-clang-build: runs-on: ${{ matrix.os }} @@ -220,9 +226,8 @@ jobs: max-size: 1G - name: CMake configure run: > - cmake -S . -B build + cmake -S . -B build -G Ninja -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -G Ninja -D CMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=install env: CC: clang-20 @@ -291,18 +296,22 @@ jobs: - name: Run tests (threads, num_threads=1) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 1 - name: Run tests (threads, num_threads=2) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 2 - name: Run tests (threads, num_threads=3) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 3 - name: Run tests (threads, num_threads=4) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 4 ubuntu-clang-test-extended: needs: @@ -331,18 +340,22 @@ jobs: - name: Run tests (threads, num_threads=5) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 5 - name: Run tests (threads, num_threads=7) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 7 - name: Run tests (threads, num_threads=11) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 11 - name: Run tests (threads, num_threads=13) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 13 ubuntu-clang-sanitizer-build: needs: @@ -371,9 +384,8 @@ jobs: max-size: 1G - name: CMake configure run: > - cmake -S . -B build + cmake -S . -B build -G Ninja -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -G Ninja -D CMAKE_BUILD_TYPE=RELEASE -D ENABLE_ADDRESS_SANITIZER=ON -D ENABLE_UB_SANITIZER=ON -D CMAKE_INSTALL_PREFIX=install env: @@ -432,6 +444,7 @@ jobs: - name: Run tests (threads, num_threads=1) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 1 PPC_ASAN_RUN: 1 ASAN_OPTIONS: abort_on_error=1 @@ -439,6 +452,7 @@ jobs: - name: Run tests (threads, num_threads=2) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 2 PPC_ASAN_RUN: 1 ASAN_OPTIONS: abort_on_error=1 @@ -446,6 +460,7 @@ jobs: - name: Run tests (threads, num_threads=3) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 3 PPC_ASAN_RUN: 1 ASAN_OPTIONS: abort_on_error=1 @@ -453,6 +468,7 @@ jobs: - name: Run tests (threads, num_threads=4) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 4 PPC_ASAN_RUN: 1 ASAN_OPTIONS: abort_on_error=1 @@ -485,21 +501,25 @@ jobs: - name: Run tests (threads, num_threads=5) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 5 PPC_ASAN_RUN: 1 - name: Run tests (threads, num_threads=7) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 7 PPC_ASAN_RUN: 1 - name: Run tests (threads, num_threads=11) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 11 PPC_ASAN_RUN: 1 - name: Run tests (threads, num_threads=13) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 13 PPC_ASAN_RUN: 1 ubuntu-gcc-build-codecov: @@ -524,7 +544,7 @@ jobs: max-size: 1G - name: CMake configure run: > - cmake -S . -B build + cmake -S . -B build -G Ninja -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_VERBOSE_MAKEFILE=ON -D USE_COVERAGE=ON @@ -539,18 +559,22 @@ jobs: - name: Run tests (threads, num_threads=1) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 1 - name: Run tests (threads, num_threads=2) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 2 - name: Run tests (threads, num_threads=3) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 3 - name: Run tests (threads, num_threads=4) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 4 - name: Generate gcovr Coverage Data run: | @@ -559,14 +583,12 @@ jobs: gcovr -r ../ \ --exclude '.*3rdparty/.*' \ --exclude '/usr/.*' \ - --exclude '.*/perf_tests/.*' \ - --exclude '.*/func_tests/.*' \ - --exclude '.*/all/runner.cpp' \ - --exclude '.*/mpi/runner.cpp' \ - --exclude '.*/omp/runner.cpp' \ - --exclude '.*/seq/runner.cpp' \ - --exclude '.*/stl/runner.cpp' \ - --exclude '.*/tbb/runner.cpp' \ + --exclude '.*tasks/.*/tests/.*' \ + --exclude '.*modules/.*/tests/.*' \ + --exclude '.*tasks/common/runners/.*' \ + --exclude '.*modules/core/util/include/perf_test_util.hpp' \ + --exclude '.*modules/core/util/include/func_test_util.hpp' \ + --exclude '.*modules/core/util/src/func_test_util.cpp' \ --xml --output ../coverage.xml \ --html=../cov-report/index.html --html-details - name: Upload coverage reports to Codecov diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 17536458d..2dceaec12 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -141,18 +141,22 @@ jobs: - name: Run tests (threads, num_threads=1) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 1 - name: Run tests (threads, num_threads=2) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 2 - name: Run tests (threads, num_threads=3) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 3 - name: Run tests (threads, num_threads=4) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 4 windows-msvc-test-extended: needs: @@ -181,18 +185,22 @@ jobs: - name: Run tests (threads, num_threads=5) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 5 - name: Run tests (threads, num_threads=7) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 7 - name: Run tests (threads, num_threads=11) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 11 - name: Run tests (threads, num_threads=13) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 13 windows-clang-build: runs-on: windows-latest @@ -207,6 +215,10 @@ jobs: uses: microsoft/setup-msbuild@v2 with: vs-version: 'latest' + - name: Setup LLVM + uses: KyleMayes/install-llvm-action@v2 + with: + version: "20.1.4" - name: Setup MPI uses: mpi4py/setup-mpi@v1 with: @@ -217,13 +229,13 @@ jobs: windows_compile_environment: msvc - name: Setup ninja uses: seanmiddleditch/gha-setup-ninja@v6 - - name: Setup MSVC for Ninja again - uses: ilammy/msvc-dev-cmd@v1 - name: CMake configure run: > - cmake -S . -B build -G Ninja -D CMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl + cmake -S . -B build -G Ninja + -D CMAKE_C_COMPILER=clang-cl -D CMAKE_CXX_COMPILER=clang-cl -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache - -D CMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=install + -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=install + -D CMAKE_PREFIX_PATH="C:/Program Files/LLVM" env: CC: clang-cl CXX: clang-cl @@ -271,18 +283,22 @@ jobs: - name: Run tests (threads, num_threads=1) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 1 - name: Run tests (threads, num_threads=2) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 2 - name: Run tests (threads, num_threads=3) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 3 - name: Run tests (threads, num_threads=4) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 4 windows-clang-test-extended: needs: @@ -311,16 +327,20 @@ jobs: - name: Run tests (threads, num_threads=5) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 5 - name: Run tests (threads, num_threads=7) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 7 - name: Run tests (threads, num_threads=11) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 11 - name: Run tests (threads, num_threads=13) run: python3 scripts/run_tests.py --running-type="threads" env: + PPC_NUM_PROC: 1 PPC_NUM_THREADS: 13 From fa7e0f41a68aa30f3c06347f1d943435a64af1b6 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Mon, 16 Jun 2025 16:07:26 +0200 Subject: [PATCH 115/141] Simplify `PipelineRun` by combining lambda function argument formatting. --- modules/core/performance/include/performance.hpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/modules/core/performance/include/performance.hpp b/modules/core/performance/include/performance.hpp index 2373c8296..32114e6c9 100644 --- a/modules/core/performance/include/performance.hpp +++ b/modules/core/performance/include/performance.hpp @@ -38,15 +38,12 @@ class Perf { void PipelineRun(const PerfAttr& perf_attr) { perf_results_.type_of_running = PerfResults::TypeOfRunning::kPipeline; - CommonRun( - perf_attr, - [&]() { - task_->Validation(); - task_->PreProcessing(); - task_->Run(); - task_->PostProcessing(); - }, - perf_results_); + CommonRun(perf_attr, [&]() { + task_->Validation(); + task_->PreProcessing(); + task_->Run(); + task_->PostProcessing(); + }, perf_results_); } // Check performance of task's Run() function void TaskRun(const PerfAttr& perf_attr) { From 72b9eab3437c72c93aabf41dff227702f77afc3f Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Mon, 16 Jun 2025 23:33:08 +0200 Subject: [PATCH 116/141] Refactor and extend tests and configurations: - Update `codecov.yml` and GitHub workflow exclusions for improved coverage and build precision. - Add new parameterized and edge case tests for utility and task-related functionality. - Standardize and clean up `NOLINT` macros in `util.hpp`. - Improve test readability by removing redundant comments and enhancing structure. - Extend `GetStringTaskType` tests with additional scenarios and file-based validation cases. - Introduce `GetNamespaceTest` for namespace extraction validations. --- .github/workflows/ubuntu.yml | 1 + .gitignore | 2 + codecov.yml | 1 + modules/core/performance/tests/perf_tests.cpp | 215 +++++++++++++++--- modules/core/util/include/util.hpp | 13 +- 5 files changed, 200 insertions(+), 32 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index ea0ad8761..1cb83985d 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -586,6 +586,7 @@ jobs: --exclude '.*tasks/.*/tests/.*' \ --exclude '.*modules/.*/tests/.*' \ --exclude '.*tasks/common/runners/.*' \ + --exclude '.*modules/core/runners/.*' \ --exclude '.*modules/core/util/include/perf_test_util.hpp' \ --exclude '.*modules/core/util/include/func_test_util.hpp' \ --exclude '.*modules/core/util/src/func_test_util.cpp' \ diff --git a/.gitignore b/.gitignore index b779f5650..599947e5f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ /build* +docs/build* /xml +docs/xml out mpich cmake-build-* diff --git a/codecov.yml b/codecov.yml index c0647754f..ed03862a6 100644 --- a/codecov.yml +++ b/codecov.yml @@ -2,6 +2,7 @@ ignore: - "tasks/**/tests/**" - "modules/**/tests/**" - "tasks/common/runners/**" + - "modules/core/runners/**" - "modules/core/util/include/perf_test_util.hpp" - "modules/core/util/include/func_test_util.hpp" - "modules/core/util/src/func_test_util.cpp" diff --git a/modules/core/performance/tests/perf_tests.cpp b/modules/core/performance/tests/perf_tests.cpp index 0d46a741c..830f3382b 100644 --- a/modules/core/performance/tests/perf_tests.cpp +++ b/modules/core/performance/tests/perf_tests.cpp @@ -9,56 +9,42 @@ #include "core/performance/tests/test_task.hpp" TEST(perf_tests, check_perf_pipeline) { - // Create data std::vector in(2000, 1); - // Create Task auto test_task = std::make_shared, uint32_t>>(in); - // Create Perf analyzer ppc::core::Perf, uint32_t> perf_analyzer(test_task); - // Create Perf attributes ppc::core::PerfAttr perf_attr; perf_analyzer.PipelineRun(perf_attr); - // Get perf statistic perf_analyzer.PrintPerfStatistic("check_perf_pipeline"); ASSERT_LE(perf_analyzer.GetPerfResults().time_sec, ppc::core::PerfResults::kMaxTime); EXPECT_EQ(test_task->GetOutput(), in.size()); } TEST(perf_tests, check_perf_pipeline_float) { - // Create data std::vector in(2000, 1); - // Create Task auto test_task = std::make_shared, float>>(in); - // Create Perf analyzer ppc::core::Perf, float> perf_analyzer(test_task); - // Create Perf attributes ppc::core::PerfAttr perf_attr; perf_analyzer.PipelineRun(perf_attr); - // Get perf statistic perf_analyzer.PrintPerfStatistic("check_perf_pipeline_float"); ASSERT_LE(perf_analyzer.GetPerfResults().time_sec, ppc::core::PerfResults::kMaxTime); EXPECT_EQ(test_task->GetOutput(), in.size()); } TEST(perf_tests, check_perf_pipeline_uint8_t_slow_test) { - // Create data std::vector in(128, 1); - // Create Task auto test_task = std::make_shared, uint8_t>>(in); - // Create Perf analyzer ppc::core::Perf, uint8_t> perf_analyzer(test_task); - // Create Perf attributes ppc::core::PerfAttr perf_attr; perf_attr.num_running = 1; @@ -70,46 +56,217 @@ TEST(perf_tests, check_perf_pipeline_uint8_t_slow_test) { }; perf_analyzer.PipelineRun(perf_attr); - // Get perf statistic - // NOLINTNEXTLINE(cppcoreguidelines-avoid-goto) - ASSERT_ANY_THROW(perf_analyzer.PrintPerfStatistic("check_perf_pipeline_uint8_t_slow_test")); + ASSERT_ANY_THROW_NOLINT(perf_analyzer.PrintPerfStatistic("check_perf_pipeline_uint8_t_slow_test")); } TEST(perf_tests, check_perf_task_exception) { - // Create data std::vector in(2000, 1); - // Create Task auto test_task = std::make_shared, uint32_t>>(in); - // Create Perf analyzer ppc::core::Perf, uint32_t> perf_analyzer(test_task); - // Get perf statistic - // NOLINTNEXTLINE(cppcoreguidelines-avoid-goto) - ASSERT_ANY_THROW(perf_analyzer.PrintPerfStatistic("check_perf_task_exception")); + ASSERT_ANY_THROW_NOLINT(perf_analyzer.PrintPerfStatistic("check_perf_task_exception")); - // Create Perf attributes ppc::core::PerfAttr perf_attr; perf_analyzer.TaskRun(perf_attr); } TEST(perf_tests, check_perf_task_float) { - // Create data std::vector in(2000, 1); - // Create Task auto test_task = std::make_shared, float>>(in); - // Create Perf analyzer ppc::core::Perf, float> perf_analyzer(test_task); - // Create Perf attributes ppc::core::PerfAttr perf_attr; perf_analyzer.TaskRun(perf_attr); - // Get perf statistic perf_analyzer.PrintPerfStatistic("check_perf_task_float"); ASSERT_LE(perf_analyzer.GetPerfResults().time_sec, ppc::core::PerfResults::kMaxTime); EXPECT_EQ(test_task->GetOutput(), in.size()); } + +struct ParamTestCase { + ppc::core::PerfResults::TypeOfRunning input; + std::string expected_output; +}; + +class GetStringParamNameParamTest : public ::testing::TestWithParam {}; + +TEST_P(GetStringParamNameParamTest, ReturnsExpectedString) { + const auto& param = GetParam(); + EXPECT_EQ(ppc::core::GetStringParamName(param.input), param.expected_output); +} + +INSTANTIATE_TEST_SUITE_P(ParamTests, GetStringParamNameParamTest, + ::testing::Values(ParamTestCase{ppc::core::PerfResults::kTaskRun, "task_run"}, + ParamTestCase{ppc::core::PerfResults::kPipeline, "pipeline"}, + ParamTestCase{static_cast(999), + "none"})); + +struct TaskTypeTestCase { + ppc::core::TypeOfTask type; + std::string expected; + std::string label; +}; + +class GetStringTaskTypeTest : public ::testing::TestWithParam { + protected: + std::string temp_path; + + void SetUp() override { + temp_path = std::filesystem::temp_directory_path() / "test_settings.json"; + nlohmann::json j; + j["tasks"]["all"] = "ALL"; + j["tasks"]["stl"] = "STL"; + j["tasks"]["omp"] = "OMP"; + j["tasks"]["mpi"] = "MPI"; + j["tasks"]["tbb"] = "TBB"; + j["tasks"]["seq"] = "SEQ"; + + std::ofstream(temp_path) << j.dump(); + } + + void TearDown() override { std::filesystem::remove(temp_path); } +}; + +TEST_P(GetStringTaskTypeTest, ReturnsExpectedString) { + const auto& param = GetParam(); + EXPECT_EQ(GetStringTaskType(param.type, temp_path), param.expected) << "Failed on: " << param.label; +} + +INSTANTIATE_TEST_SUITE_P_NOLINT(AllTypeCases, GetStringTaskTypeTest, + ::testing::Values(TaskTypeTestCase{ppc::core::TypeOfTask::kALL, "all_ALL", "kALL"}, + TaskTypeTestCase{ppc::core::TypeOfTask::kSTL, "stl_STL", "kSTL"}, + TaskTypeTestCase{ppc::core::TypeOfTask::kOMP, "omp_OMP", "kOMP"}, + TaskTypeTestCase{ppc::core::TypeOfTask::kMPI, "mpi_MPI", "kMPI"}, + TaskTypeTestCase{ppc::core::TypeOfTask::kTBB, "tbb_TBB", "kTBB"}, + TaskTypeTestCase{ppc::core::TypeOfTask::kSEQ, "seq_SEQ", "kSEQ"})); + +DEATH_TEST(GetStringTaskTypeStandaloneTest, ThrowsIfFileMissing) { + std::string missing_path = "non_existent_settings.json"; + EXPECT_THROW_NOLINT(GetStringTaskType(ppc::core::TypeOfTask::kSEQ, missing_path), std::runtime_error); +} + +TEST(GetStringTaskTypeStandaloneTest, ReturnsUnknownForInvalidEnum) { + std::string path = std::filesystem::temp_directory_path() / "tmp_settings.json"; + std::ofstream(path) << R"({"tasks":{"seq":"SEQ"}})"; + + auto result = GetStringTaskType(static_cast(999), path); + EXPECT_EQ(result, "unknown"); + + std::filesystem::remove(path); +} + +TEST(GetStringTaskTypeEdgeCases, ThrowsIfFileCannotBeOpened) { + EXPECT_THROW_NOLINT(GetStringTaskType(ppc::core::TypeOfTask::kSEQ, "definitely_missing_file.json"), + std::runtime_error); +} + +TEST(GetStringTaskTypeEdgeCases, ThrowsIfJsonIsMalformed) { + std::string path = std::filesystem::temp_directory_path() / "bad_json.json"; + std::ofstream(path) << "{ this is not valid json "; + EXPECT_THROW_NOLINT(GetStringTaskType(ppc::core::TypeOfTask::kSEQ, path), nlohmann::json::parse_error); + std::filesystem::remove(path); +} + +TEST(GetStringTaskTypeEdgeCases, ThrowsIfJsonValueIsNull) { + std::string path = std::filesystem::temp_directory_path() / "null_value.json"; + std::ofstream(path) << R"({"tasks": { "seq": null }})"; + + EXPECT_THROW(GetStringTaskType(ppc::core::TypeOfTask::kSEQ, path), nlohmann::json::type_error); + + std::filesystem::remove(path); +} + +TEST(GetStringTaskTypeEdgeCases, ReturnsUnknownIfEnumOutOfRange) { + std::string path = std::filesystem::temp_directory_path() / "ok.json"; + std::ofstream(path) << R"({"tasks":{"seq":"SEQ"}})"; + auto result = GetStringTaskType(static_cast(255), path); + EXPECT_EQ(result, "unknown"); + std::filesystem::remove(path); +} + +TEST(GetStringTaskStatusTest, HandlesEnabledAndDisabled) { + EXPECT_EQ(GetStringTaskStatus(ppc::core::StatusOfTask::kEnabled), "enabled"); + EXPECT_EQ(GetStringTaskStatus(ppc::core::StatusOfTask::kDisabled), "disabled"); +} + +class DummyTask : public ppc::core::Task { + public: + using Task::Task; + bool ValidationImpl() override { return true; } + bool PreProcessingImpl() override { return true; } + bool RunImpl() override { return true; } + bool PostProcessingImpl() override { return true; } +}; + +class SlowTask : public ppc::core::Task { + public: + using Task::Task; + bool ValidationImpl() override { return true; } + bool PreProcessingImpl() override { return true; } + bool RunImpl() override { return true; } + bool PostProcessingImpl() override { + std::this_thread::sleep_for(std::chrono::seconds(2)); + return true; + } +}; + +TEST(TaskTest, GetDynamicTypeReturnsCorrectEnum) { + DummyTask task; + task.SetTypeOfTask(ppc::core::TypeOfTask::kOMP); + task.Validation(); + task.PreProcessing(); + task.Run(); + task.PostProcessing(); + EXPECT_EQ(task.GetDynamicTypeOfTask(), ppc::core::TypeOfTask::kOMP); +} + +DEATH_TEST(TaskTest, DestructorTerminatesIfWrongOrder) { + testing::FLAGS_gtest_death_test_style = "threadsafe"; + ASSERT_DEATH_IF_SUPPORTED( + { + DummyTask task; + task.Run(); + }, + ""); +} + +namespace my { +namespace nested { +struct Type {}; +} // namespace nested + +class Another {}; +} // namespace my + +namespace { +struct NoNamespace {}; +} // anonymous namespace + +template +class GetNamespaceTest : public ::testing::Test {}; + +using TestTypes = ::testing::Types>; + +TYPED_TEST_SUITE(GetNamespaceTest, TestTypes); + +TYPED_TEST(GetNamespaceTest, ExtractsNamespaceCorrectly) { + constexpr std::string_view ns = ppc::util::GetNamespace(); + + if constexpr (std::is_same_v) { + EXPECT_EQ(ns, "my::nested"); + } else if constexpr (std::is_same_v) { + EXPECT_EQ(ns, "my"); + } else if constexpr (std::is_same_v) { + EXPECT_EQ(ns, ""); + } else if constexpr (std::is_same_v) { + EXPECT_EQ(ns, ""); + } else if constexpr (std::is_same_v>) { + EXPECT_EQ(ns, "std"); + } else { + FAIL() << "Unhandled type in test"; + } +} diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index b645f2966..f0704cf6d 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -18,12 +18,19 @@ #endif /* NOLINTBEGIN */ -#define INSTANTIATE_TEST_SUITE_P_NOLINT(prefix, test_case_name, generator, custom_test_name) \ - INSTANTIATE_TEST_SUITE_P(prefix, test_case_name, generator, custom_test_name) +#define ASSERT_ANY_THROW_NOLINT(...) ASSERT_ANY_THROW(__VA_ARGS__) /* NOLINTEND */ /* NOLINTBEGIN */ -#define DEATH_TEST(test_suite_name, test_name) TEST(test_suite_name, test_name) +#define EXPECT_THROW_NOLINT(...) EXPECT_THROW(__VA_ARGS__) +/* NOLINTEND */ + +/* NOLINTBEGIN */ +#define INSTANTIATE_TEST_SUITE_P_NOLINT(...) INSTANTIATE_TEST_SUITE_P(__VA_ARGS__) +/* NOLINTEND */ + +/* NOLINTBEGIN */ +#define DEATH_TEST(...) TEST(__VA_ARGS__) /* NOLINTEND */ namespace ppc::util { From b4d452cbee8a4d8aea2d58fbf974f8bd1b2837c3 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Mon, 16 Jun 2025 23:48:09 +0200 Subject: [PATCH 117/141] Add C++ standard requirements to CMake module configurations - Enforce `CMAKE_CXX_STANDARD` and `CMAKE_CXX_STANDARD_REQUIRED` across all relevant submodules (`onetbb`, `libenvpp`, `json`, `gtest`). --- cmake/gtest.cmake | 4 +++- cmake/json.cmake | 1 + cmake/libenvpp.cmake | 1 + cmake/onetbb.cmake | 1 + modules/core/performance/tests/perf_tests.cpp | 8 +------- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/cmake/gtest.cmake b/cmake/gtest.cmake index d20e815b7..5e495fd76 100644 --- a/cmake/gtest.cmake +++ b/cmake/gtest.cmake @@ -7,6 +7,8 @@ ExternalProject_Add(ppc_googletest INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_googletest/install" CONFIGURE_COMMAND "${CMAKE_COMMAND}" -S "${CMAKE_SOURCE_DIR}/3rdparty/googletest/" -B "${CMAKE_CURRENT_BINARY_DIR}/ppc_googletest/build/" -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -G${CMAKE_GENERATOR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} -Dgtest_force_shared_crt=ON -DCMAKE_CXX_FLAGS="-w" -DCMAKE_C_FLAGS="-w" + -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} + -Dgtest_force_shared_crt=ON -DCMAKE_CXX_FLAGS="-w" -DCMAKE_C_FLAGS="-w" + -D CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} -D CMAKE_CXX_STANDARD_REQUIRED=ON BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_googletest/build" --config ${CMAKE_BUILD_TYPE} --parallel INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_googletest/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_googletest/install") diff --git a/cmake/json.cmake b/cmake/json.cmake index 3fd9b0d42..5da720d90 100644 --- a/cmake/json.cmake +++ b/cmake/json.cmake @@ -8,5 +8,6 @@ ExternalProject_Add(ppc_json CONFIGURE_COMMAND "${CMAKE_COMMAND}" -S "${CMAKE_SOURCE_DIR}/3rdparty/json/" -B "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/build/" -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -G${CMAKE_GENERATOR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} + -D CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} -D CMAKE_CXX_STANDARD_REQUIRED=ON BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/build" --config ${CMAKE_BUILD_TYPE} --parallel INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/install") diff --git a/cmake/libenvpp.cmake b/cmake/libenvpp.cmake index 449cd281e..583525cf4 100644 --- a/cmake/libenvpp.cmake +++ b/cmake/libenvpp.cmake @@ -10,6 +10,7 @@ ExternalProject_Add(ppc_libenvpp CONFIGURE_COMMAND "${CMAKE_COMMAND}" -S "${CMAKE_SOURCE_DIR}/3rdparty/libenvpp/" -B "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build/" -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -G${CMAKE_GENERATOR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} + -D CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} -D CMAKE_CXX_STANDARD_REQUIRED=ON BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --config ${CMAKE_BUILD_TYPE} --parallel INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/install") diff --git a/cmake/onetbb.cmake b/cmake/onetbb.cmake index 174be9865..3a2d4efa1 100644 --- a/cmake/onetbb.cmake +++ b/cmake/onetbb.cmake @@ -19,6 +19,7 @@ ExternalProject_Add(ppc_onetbb -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} -G${CMAKE_GENERATOR} -DTBB_TEST=OFF -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -D CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} -D CMAKE_CXX_STANDARD_REQUIRED=ON BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" --config ${CMAKE_BUILD_TYPE} --parallel INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install" TEST_COMMAND ${ppc_onetbb_TEST_COMMAND} diff --git a/modules/core/performance/tests/perf_tests.cpp b/modules/core/performance/tests/perf_tests.cpp index 830f3382b..356d159a1 100644 --- a/modules/core/performance/tests/perf_tests.cpp +++ b/modules/core/performance/tests/perf_tests.cpp @@ -242,14 +242,10 @@ struct Type {}; class Another {}; } // namespace my -namespace { -struct NoNamespace {}; -} // anonymous namespace - template class GetNamespaceTest : public ::testing::Test {}; -using TestTypes = ::testing::Types>; +using TestTypes = ::testing::Types>; TYPED_TEST_SUITE(GetNamespaceTest, TestTypes); @@ -260,8 +256,6 @@ TYPED_TEST(GetNamespaceTest, ExtractsNamespaceCorrectly) { EXPECT_EQ(ns, "my::nested"); } else if constexpr (std::is_same_v) { EXPECT_EQ(ns, "my"); - } else if constexpr (std::is_same_v) { - EXPECT_EQ(ns, ""); } else if constexpr (std::is_same_v) { EXPECT_EQ(ns, ""); } else if constexpr (std::is_same_v>) { From 34a5b0844789bccc76d9b012f085611cd86ee1ed Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 17 Jun 2025 09:44:57 +0200 Subject: [PATCH 118/141] Standardize and refactor test macros: - Replace `DEATH_TEST` with `TEST_NOLINT` and introduce consistent `NOLINT` test macro variants (`ASSERT_DEATH_IF_SUPPORTED_NOLINT`, `TYPED_TEST_NOLINT`, etc.). - Update affected test cases in `task_tests.cpp`, `perf_tests.cpp`, and `util.hpp`. - Enhance `GetNamespaceTest` consistency with variable naming improvements. - Include missing `util.hpp` in performance tests and clean up redundant includes. --- modules/core/performance/tests/perf_tests.cpp | 35 ++++++++++--------- modules/core/performance/tests/test_task.hpp | 1 - modules/core/task/tests/task_tests.cpp | 4 +-- modules/core/util/include/util.hpp | 10 +++++- 4 files changed, 29 insertions(+), 21 deletions(-) diff --git a/modules/core/performance/tests/perf_tests.cpp b/modules/core/performance/tests/perf_tests.cpp index 356d159a1..a814f0934 100644 --- a/modules/core/performance/tests/perf_tests.cpp +++ b/modules/core/performance/tests/perf_tests.cpp @@ -7,6 +7,7 @@ #include "core/performance/include/performance.hpp" #include "core/performance/tests/test_task.hpp" +#include "core/util/include/util.hpp" TEST(perf_tests, check_perf_pipeline) { std::vector in(2000, 1); @@ -99,11 +100,11 @@ TEST_P(GetStringParamNameParamTest, ReturnsExpectedString) { EXPECT_EQ(ppc::core::GetStringParamName(param.input), param.expected_output); } -INSTANTIATE_TEST_SUITE_P(ParamTests, GetStringParamNameParamTest, - ::testing::Values(ParamTestCase{ppc::core::PerfResults::kTaskRun, "task_run"}, - ParamTestCase{ppc::core::PerfResults::kPipeline, "pipeline"}, - ParamTestCase{static_cast(999), - "none"})); +INSTANTIATE_TEST_SUITE_P_NOLINT(ParamTests, GetStringParamNameParamTest, + ::testing::Values(ParamTestCase{ppc::core::PerfResults::kTaskRun, "task_run"}, + ParamTestCase{ppc::core::PerfResults::kPipeline, "pipeline"}, + ParamTestCase{static_cast(999), + "none"})); struct TaskTypeTestCase { ppc::core::TypeOfTask type; @@ -144,7 +145,7 @@ INSTANTIATE_TEST_SUITE_P_NOLINT(AllTypeCases, GetStringTaskTypeTest, TaskTypeTestCase{ppc::core::TypeOfTask::kTBB, "tbb_TBB", "kTBB"}, TaskTypeTestCase{ppc::core::TypeOfTask::kSEQ, "seq_SEQ", "kSEQ"})); -DEATH_TEST(GetStringTaskTypeStandaloneTest, ThrowsIfFileMissing) { +TEST_NOLINT(GetStringTaskTypeStandaloneTest, ThrowsIfFileMissing) { std::string missing_path = "non_existent_settings.json"; EXPECT_THROW_NOLINT(GetStringTaskType(ppc::core::TypeOfTask::kSEQ, missing_path), std::runtime_error); } @@ -159,12 +160,12 @@ TEST(GetStringTaskTypeStandaloneTest, ReturnsUnknownForInvalidEnum) { std::filesystem::remove(path); } -TEST(GetStringTaskTypeEdgeCases, ThrowsIfFileCannotBeOpened) { +TEST_NOLINT(GetStringTaskTypeEdgeCases, ThrowsIfFileCannotBeOpened) { EXPECT_THROW_NOLINT(GetStringTaskType(ppc::core::TypeOfTask::kSEQ, "definitely_missing_file.json"), std::runtime_error); } -TEST(GetStringTaskTypeEdgeCases, ThrowsIfJsonIsMalformed) { +TEST_NOLINT(GetStringTaskTypeEdgeCases, ThrowsIfJsonIsMalformed) { std::string path = std::filesystem::temp_directory_path() / "bad_json.json"; std::ofstream(path) << "{ this is not valid json "; EXPECT_THROW_NOLINT(GetStringTaskType(ppc::core::TypeOfTask::kSEQ, path), nlohmann::json::parse_error); @@ -175,7 +176,7 @@ TEST(GetStringTaskTypeEdgeCases, ThrowsIfJsonValueIsNull) { std::string path = std::filesystem::temp_directory_path() / "null_value.json"; std::ofstream(path) << R"({"tasks": { "seq": null }})"; - EXPECT_THROW(GetStringTaskType(ppc::core::TypeOfTask::kSEQ, path), nlohmann::json::type_error); + EXPECT_THROW_NOLINT(GetStringTaskType(ppc::core::TypeOfTask::kSEQ, path), nlohmann::json::type_error); std::filesystem::remove(path); } @@ -224,9 +225,9 @@ TEST(TaskTest, GetDynamicTypeReturnsCorrectEnum) { EXPECT_EQ(task.GetDynamicTypeOfTask(), ppc::core::TypeOfTask::kOMP); } -DEATH_TEST(TaskTest, DestructorTerminatesIfWrongOrder) { +TEST_NOLINT(TaskTest, DestructorTerminatesIfWrongOrder) { testing::FLAGS_gtest_death_test_style = "threadsafe"; - ASSERT_DEATH_IF_SUPPORTED( + ASSERT_DEATH_IF_SUPPORTED_NOLINT( { DummyTask task; task.Run(); @@ -249,17 +250,17 @@ using TestTypes = ::testing::Types(); +TYPED_TEST_NOLINT(GetNamespaceTest, ExtractsNamespaceCorrectly) { + constexpr std::string_view kNs = ppc::util::GetNamespace(); if constexpr (std::is_same_v) { - EXPECT_EQ(ns, "my::nested"); + EXPECT_EQ(kNs, "my::nested"); } else if constexpr (std::is_same_v) { - EXPECT_EQ(ns, "my"); + EXPECT_EQ(kNs, "my"); } else if constexpr (std::is_same_v) { - EXPECT_EQ(ns, ""); + EXPECT_EQ(kNs, ""); } else if constexpr (std::is_same_v>) { - EXPECT_EQ(ns, "std"); + EXPECT_EQ(kNs, "std"); } else { FAIL() << "Unhandled type in test"; } diff --git a/modules/core/performance/tests/test_task.hpp b/modules/core/performance/tests/test_task.hpp index bc984b697..98b6993eb 100644 --- a/modules/core/performance/tests/test_task.hpp +++ b/modules/core/performance/tests/test_task.hpp @@ -2,7 +2,6 @@ #include #include -#include #include "core/task/include/task.hpp" diff --git a/modules/core/task/tests/task_tests.cpp b/modules/core/task/tests/task_tests.cpp index ec16979af..f8edb12fd 100644 --- a/modules/core/task/tests/task_tests.cpp +++ b/modules/core/task/tests/task_tests.cpp @@ -128,7 +128,7 @@ TEST(task_tests, check_float) { EXPECT_NEAR(test_task.GetOutput(), in.size(), 1e-3); } -DEATH_TEST(task_tests, check_wrong_order_disabled_valgrind) { +TEST_NOLINT(task_tests, check_wrong_order_disabled_valgrind) { auto destroy_function = [] { // Create data std::vector in(20, 1); @@ -143,7 +143,7 @@ DEATH_TEST(task_tests, check_wrong_order_disabled_valgrind) { EXPECT_DEATH_IF_SUPPORTED(destroy_function(), ".*ORDER OF FUNCTIONS IS NOT RIGHT.*"); } -DEATH_TEST(task_tests, check_empty_order_disabled_valgrind) { +TEST_NOLINT(task_tests, check_empty_order_disabled_valgrind) { auto destroy_function = [] { // Create data std::vector in(20, 1); diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index f0704cf6d..0d2b4b4a8 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -30,7 +30,15 @@ /* NOLINTEND */ /* NOLINTBEGIN */ -#define DEATH_TEST(...) TEST(__VA_ARGS__) +#define TEST_NOLINT(...) TEST(__VA_ARGS__) +/* NOLINTEND */ + +/* NOLINTBEGIN */ +#define ASSERT_DEATH_IF_SUPPORTED_NOLINT(...) ASSERT_DEATH_IF_SUPPORTED(__VA_ARGS__) +/* NOLINTEND */ + +/* NOLINTBEGIN */ +#define TYPED_TEST_NOLINT(...) TYPED_TEST(__VA_ARGS__) /* NOLINTEND */ namespace ppc::util { From b01a15651fbcfe00854b5c0af7c86b835a20424c Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 17 Jun 2025 10:21:21 +0200 Subject: [PATCH 119/141] Refactor `perf_tests.cpp`: - Replace enum casts with strongly-typed `enum class` constants. - Introduce `TEST_NOLINT` for improved macro consistency. - Extend includes for task-related and JSON utilities. - Standardize test case names and improve edge case handling. --- modules/core/performance/tests/perf_tests.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/modules/core/performance/tests/perf_tests.cpp b/modules/core/performance/tests/perf_tests.cpp index a814f0934..b573b3b6e 100644 --- a/modules/core/performance/tests/perf_tests.cpp +++ b/modules/core/performance/tests/perf_tests.cpp @@ -2,12 +2,19 @@ #include #include +#include +#include #include +#include +#include +#include #include #include "core/performance/include/performance.hpp" #include "core/performance/tests/test_task.hpp" +#include "core/task/include/task.hpp" #include "core/util/include/util.hpp" +#include "nlohmann/json.hpp" TEST(perf_tests, check_perf_pipeline) { std::vector in(2000, 1); @@ -103,8 +110,7 @@ TEST_P(GetStringParamNameParamTest, ReturnsExpectedString) { INSTANTIATE_TEST_SUITE_P_NOLINT(ParamTests, GetStringParamNameParamTest, ::testing::Values(ParamTestCase{ppc::core::PerfResults::kTaskRun, "task_run"}, ParamTestCase{ppc::core::PerfResults::kPipeline, "pipeline"}, - ParamTestCase{static_cast(999), - "none"})); + ParamTestCase{ppc::core::PerfResults::TypeOfRunning::kNone, "none"})); struct TaskTypeTestCase { ppc::core::TypeOfTask type; @@ -154,7 +160,7 @@ TEST(GetStringTaskTypeStandaloneTest, ReturnsUnknownForInvalidEnum) { std::string path = std::filesystem::temp_directory_path() / "tmp_settings.json"; std::ofstream(path) << R"({"tasks":{"seq":"SEQ"}})"; - auto result = GetStringTaskType(static_cast(999), path); + auto result = GetStringTaskType(ppc::core::TypeOfTask::kUnknown, path); EXPECT_EQ(result, "unknown"); std::filesystem::remove(path); @@ -172,7 +178,7 @@ TEST_NOLINT(GetStringTaskTypeEdgeCases, ThrowsIfJsonIsMalformed) { std::filesystem::remove(path); } -TEST(GetStringTaskTypeEdgeCases, ThrowsIfJsonValueIsNull) { +TEST_NOLINT(GetStringTaskTypeEdgeCases, ThrowsIfJsonValueIsNull) { std::string path = std::filesystem::temp_directory_path() / "null_value.json"; std::ofstream(path) << R"({"tasks": { "seq": null }})"; @@ -184,7 +190,7 @@ TEST(GetStringTaskTypeEdgeCases, ThrowsIfJsonValueIsNull) { TEST(GetStringTaskTypeEdgeCases, ReturnsUnknownIfEnumOutOfRange) { std::string path = std::filesystem::temp_directory_path() / "ok.json"; std::ofstream(path) << R"({"tasks":{"seq":"SEQ"}})"; - auto result = GetStringTaskType(static_cast(255), path); + auto result = GetStringTaskType(ppc::core::TypeOfTask::kUnknown, path); EXPECT_EQ(result, "unknown"); std::filesystem::remove(path); } From aedafb7d722c5818c89b3a6687a9cd0a5724f367 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 17 Jun 2025 10:42:44 +0200 Subject: [PATCH 120/141] Refactor `util.hpp` and `perf_tests.cpp`: - Simplify `NOLINT` macros in `util.hpp` by removing redundant `NOLINTBEGIN` and `NOLINTEND` comments. - Replace `nlohmann::json` with `ppc::util::InitJSONPtr` in `perf_tests.cpp` for consistency. - Remove unused JSON include in `perf_tests.cpp`. --- modules/core/performance/tests/perf_tests.cpp | 19 ++++++------ modules/core/util/include/util.hpp | 29 ++++--------------- 2 files changed, 15 insertions(+), 33 deletions(-) diff --git a/modules/core/performance/tests/perf_tests.cpp b/modules/core/performance/tests/perf_tests.cpp index b573b3b6e..24c443b88 100644 --- a/modules/core/performance/tests/perf_tests.cpp +++ b/modules/core/performance/tests/perf_tests.cpp @@ -14,7 +14,6 @@ #include "core/performance/tests/test_task.hpp" #include "core/task/include/task.hpp" #include "core/util/include/util.hpp" -#include "nlohmann/json.hpp" TEST(perf_tests, check_perf_pipeline) { std::vector in(2000, 1); @@ -124,15 +123,15 @@ class GetStringTaskTypeTest : public ::testing::TestWithParam void SetUp() override { temp_path = std::filesystem::temp_directory_path() / "test_settings.json"; - nlohmann::json j; - j["tasks"]["all"] = "ALL"; - j["tasks"]["stl"] = "STL"; - j["tasks"]["omp"] = "OMP"; - j["tasks"]["mpi"] = "MPI"; - j["tasks"]["tbb"] = "TBB"; - j["tasks"]["seq"] = "SEQ"; - - std::ofstream(temp_path) << j.dump(); + auto j = ppc::util::InitJSONPtr(); + (*j)["tasks"]["all"] = "ALL"; + (*j)["tasks"]["stl"] = "STL"; + (*j)["tasks"]["omp"] = "OMP"; + (*j)["tasks"]["mpi"] = "MPI"; + (*j)["tasks"]["tbb"] = "TBB"; + (*j)["tasks"]["seq"] = "SEQ"; + + std::ofstream(temp_path) << (*j).dump(); } void TearDown() override { std::filesystem::remove(temp_path); } diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index 0d2b4b4a8..0e241b288 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -17,29 +17,12 @@ #pragma warning(pop) #endif -/* NOLINTBEGIN */ -#define ASSERT_ANY_THROW_NOLINT(...) ASSERT_ANY_THROW(__VA_ARGS__) -/* NOLINTEND */ - -/* NOLINTBEGIN */ -#define EXPECT_THROW_NOLINT(...) EXPECT_THROW(__VA_ARGS__) -/* NOLINTEND */ - -/* NOLINTBEGIN */ -#define INSTANTIATE_TEST_SUITE_P_NOLINT(...) INSTANTIATE_TEST_SUITE_P(__VA_ARGS__) -/* NOLINTEND */ - -/* NOLINTBEGIN */ -#define TEST_NOLINT(...) TEST(__VA_ARGS__) -/* NOLINTEND */ - -/* NOLINTBEGIN */ -#define ASSERT_DEATH_IF_SUPPORTED_NOLINT(...) ASSERT_DEATH_IF_SUPPORTED(__VA_ARGS__) -/* NOLINTEND */ - -/* NOLINTBEGIN */ -#define TYPED_TEST_NOLINT(...) TYPED_TEST(__VA_ARGS__) -/* NOLINTEND */ +#define ASSERT_ANY_THROW_NOLINT(...) ASSERT_ANY_THROW(__VA_ARGS__) // NOLINT +#define EXPECT_THROW_NOLINT(...) EXPECT_THROW(__VA_ARGS__) // NOLINT +#define INSTANTIATE_TEST_SUITE_P_NOLINT(...) INSTANTIATE_TEST_SUITE_P(__VA_ARGS__) // NOLINT +#define TEST_NOLINT(...) TEST(__VA_ARGS__) // NOLINT +#define ASSERT_DEATH_IF_SUPPORTED_NOLINT(...) ASSERT_DEATH_IF_SUPPORTED(__VA_ARGS__) // NOLINT +#define TYPED_TEST_NOLINT(...) TYPED_TEST(__VA_ARGS__) // NOLINT namespace ppc::util { From cc19fde8128eceaa51381019b55f3daf187039eb Mon Sep 17 00:00:00 2001 From: anesterov Date: Tue, 17 Jun 2025 10:57:41 +0200 Subject: [PATCH 121/141] Wrap `std::filesystem::path` with `.string()` in tests to ensure consistent string handling. --- modules/core/performance/tests/perf_tests.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/core/performance/tests/perf_tests.cpp b/modules/core/performance/tests/perf_tests.cpp index 24c443b88..686d31a77 100644 --- a/modules/core/performance/tests/perf_tests.cpp +++ b/modules/core/performance/tests/perf_tests.cpp @@ -122,7 +122,7 @@ class GetStringTaskTypeTest : public ::testing::TestWithParam std::string temp_path; void SetUp() override { - temp_path = std::filesystem::temp_directory_path() / "test_settings.json"; + temp_path = (std::filesystem::temp_directory_path() / "test_settings.json").string(); auto j = ppc::util::InitJSONPtr(); (*j)["tasks"]["all"] = "ALL"; (*j)["tasks"]["stl"] = "STL"; @@ -156,7 +156,7 @@ TEST_NOLINT(GetStringTaskTypeStandaloneTest, ThrowsIfFileMissing) { } TEST(GetStringTaskTypeStandaloneTest, ReturnsUnknownForInvalidEnum) { - std::string path = std::filesystem::temp_directory_path() / "tmp_settings.json"; + std::string path = (std::filesystem::temp_directory_path() / "tmp_settings.json").string(); std::ofstream(path) << R"({"tasks":{"seq":"SEQ"}})"; auto result = GetStringTaskType(ppc::core::TypeOfTask::kUnknown, path); @@ -171,14 +171,14 @@ TEST_NOLINT(GetStringTaskTypeEdgeCases, ThrowsIfFileCannotBeOpened) { } TEST_NOLINT(GetStringTaskTypeEdgeCases, ThrowsIfJsonIsMalformed) { - std::string path = std::filesystem::temp_directory_path() / "bad_json.json"; + std::string path = (std::filesystem::temp_directory_path() / "bad_json.json").string(); std::ofstream(path) << "{ this is not valid json "; EXPECT_THROW_NOLINT(GetStringTaskType(ppc::core::TypeOfTask::kSEQ, path), nlohmann::json::parse_error); std::filesystem::remove(path); } TEST_NOLINT(GetStringTaskTypeEdgeCases, ThrowsIfJsonValueIsNull) { - std::string path = std::filesystem::temp_directory_path() / "null_value.json"; + std::string path = (std::filesystem::temp_directory_path() / "null_value.json").string(); std::ofstream(path) << R"({"tasks": { "seq": null }})"; EXPECT_THROW_NOLINT(GetStringTaskType(ppc::core::TypeOfTask::kSEQ, path), nlohmann::json::type_error); @@ -187,7 +187,7 @@ TEST_NOLINT(GetStringTaskTypeEdgeCases, ThrowsIfJsonValueIsNull) { } TEST(GetStringTaskTypeEdgeCases, ReturnsUnknownIfEnumOutOfRange) { - std::string path = std::filesystem::temp_directory_path() / "ok.json"; + std::string path = (std::filesystem::temp_directory_path() / "ok.json").string(); std::ofstream(path) << R"({"tasks":{"seq":"SEQ"}})"; auto result = GetStringTaskType(ppc::core::TypeOfTask::kUnknown, path); EXPECT_EQ(result, "unknown"); From d6beb7a86313fe009a5861df94368388dfd14fc4 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 17 Jun 2025 11:01:37 +0200 Subject: [PATCH 122/141] Refactor `util.hpp` and `perf_tests.cpp`: - Introduce type aliases for `nlohmann::json` exceptions in `util.hpp` for improved readability. - Update test cases in `perf_tests.cpp` to use the new aliases for exception handling consistency. --- modules/core/performance/tests/perf_tests.cpp | 4 ++-- modules/core/util/include/util.hpp | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/core/performance/tests/perf_tests.cpp b/modules/core/performance/tests/perf_tests.cpp index 686d31a77..29fd84d9c 100644 --- a/modules/core/performance/tests/perf_tests.cpp +++ b/modules/core/performance/tests/perf_tests.cpp @@ -173,7 +173,7 @@ TEST_NOLINT(GetStringTaskTypeEdgeCases, ThrowsIfFileCannotBeOpened) { TEST_NOLINT(GetStringTaskTypeEdgeCases, ThrowsIfJsonIsMalformed) { std::string path = (std::filesystem::temp_directory_path() / "bad_json.json").string(); std::ofstream(path) << "{ this is not valid json "; - EXPECT_THROW_NOLINT(GetStringTaskType(ppc::core::TypeOfTask::kSEQ, path), nlohmann::json::parse_error); + EXPECT_THROW_NOLINT(GetStringTaskType(ppc::core::TypeOfTask::kSEQ, path), NlohmannJsonParseError); std::filesystem::remove(path); } @@ -181,7 +181,7 @@ TEST_NOLINT(GetStringTaskTypeEdgeCases, ThrowsIfJsonValueIsNull) { std::string path = (std::filesystem::temp_directory_path() / "null_value.json").string(); std::ofstream(path) << R"({"tasks": { "seq": null }})"; - EXPECT_THROW_NOLINT(GetStringTaskType(ppc::core::TypeOfTask::kSEQ, path), nlohmann::json::type_error); + EXPECT_THROW_NOLINT(GetStringTaskType(ppc::core::TypeOfTask::kSEQ, path), NlohmannJsonTypeError); std::filesystem::remove(path); } diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index 0e241b288..a15b920bc 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -13,6 +13,9 @@ #include // NOLINT(misc-include-cleaner) +using NlohmannJsonParseError = nlohmann::json::parse_error; +using NlohmannJsonTypeError = nlohmann::json::type_error; + #ifdef _MSC_VER #pragma warning(pop) #endif From efa7b16d88942c51cad29bcc7e245147d9ad4853 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 17 Jun 2025 11:32:55 +0200 Subject: [PATCH 123/141] Refactor test macros and update test cases: - Replace `INSTANTIATE_TEST_SUITE_P_NOLINT` with `INSTANTIATE_TEST_SUITE_P_WITH_NAME` across functional and performance test cases. - Add new `INSTANTIATE_TEST_SUITE_P_WITH_NAME` macro in `util.hpp` for improved consistency and clarity. --- modules/core/util/include/util.hpp | 14 ++++++++------ tasks/example_processes/tests/functional/main.cpp | 2 +- tasks/example_processes/tests/performance/main.cpp | 2 +- tasks/example_threads/tests/functional/main.cpp | 2 +- tasks/example_threads/tests/performance/main.cpp | 2 +- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index a15b920bc..6274693ac 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -20,12 +20,14 @@ using NlohmannJsonTypeError = nlohmann::json::type_error; #pragma warning(pop) #endif -#define ASSERT_ANY_THROW_NOLINT(...) ASSERT_ANY_THROW(__VA_ARGS__) // NOLINT -#define EXPECT_THROW_NOLINT(...) EXPECT_THROW(__VA_ARGS__) // NOLINT -#define INSTANTIATE_TEST_SUITE_P_NOLINT(...) INSTANTIATE_TEST_SUITE_P(__VA_ARGS__) // NOLINT -#define TEST_NOLINT(...) TEST(__VA_ARGS__) // NOLINT -#define ASSERT_DEATH_IF_SUPPORTED_NOLINT(...) ASSERT_DEATH_IF_SUPPORTED(__VA_ARGS__) // NOLINT -#define TYPED_TEST_NOLINT(...) TYPED_TEST(__VA_ARGS__) // NOLINT +#define ASSERT_ANY_THROW_NOLINT(stmt) ASSERT_ANY_THROW(stmt) // NOLINT +#define EXPECT_THROW_NOLINT(stmt, error) EXPECT_THROW(stmt, error) // NOLINT +#define TEST_NOLINT(test_suite_name, test_name) TEST(test_suite_name, test_name) // NOLINT +#define ASSERT_DEATH_IF_SUPPORTED_NOLINT(stmt, name) ASSERT_DEATH_IF_SUPPORTED(stmt, name) // NOLINT +#define TYPED_TEST_NOLINT(test_suite_name, test_name) TYPED_TEST(test_suite_name, test_name) // NOLINT +#define INSTANTIATE_TEST_SUITE_P_WITH_NAME(n, t, g, ng) INSTANTIATE_TEST_SUITE_P(n, t, g, ng) // NOLINT +#define INSTANTIATE_TEST_SUITE_P_NOLINT(n, t, g) INSTANTIATE_TEST_SUITE_P(n, t, g) // NOLINT +// INSTANTIATE_TEST_SUITE_P | n, t, g, ng == name, test_case_name, generator, name_generator namespace ppc::util { diff --git a/tasks/example_processes/tests/functional/main.cpp b/tasks/example_processes/tests/functional/main.cpp index 424f6588a..bd97d2b5e 100644 --- a/tasks/example_processes/tests/functional/main.cpp +++ b/tasks/example_processes/tests/functional/main.cpp @@ -72,7 +72,7 @@ const auto kGtestValues = ppc::util::ExpandToValues(kTestTasksList); const auto kPerfTestName = NesterovARunFuncTestsProcesses::PrintFuncTestName; -INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTestsProcesses, kGtestValues, kPerfTestName); +INSTANTIATE_TEST_SUITE_P_WITH_NAME(PicMatrixTests, NesterovARunFuncTestsProcesses, kGtestValues, kPerfTestName); } // namespace diff --git a/tasks/example_processes/tests/performance/main.cpp b/tasks/example_processes/tests/performance/main.cpp index 3c22a742b..5b0fc0a73 100644 --- a/tasks/example_processes/tests/performance/main.cpp +++ b/tasks/example_processes/tests/performance/main.cpp @@ -28,6 +28,6 @@ const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); const auto kPerfTestName = ExampleRunPerfTestProcesses::CustomPerfTestName; -INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, ExampleRunPerfTestProcesses, kGtestValues, kPerfTestName); +INSTANTIATE_TEST_SUITE_P_WITH_NAME(RunModeTests, ExampleRunPerfTestProcesses, kGtestValues, kPerfTestName); } // namespace nesterov_a_test_task_processes diff --git a/tasks/example_threads/tests/functional/main.cpp b/tasks/example_threads/tests/functional/main.cpp index fb5f56365..e379679dd 100644 --- a/tasks/example_threads/tests/functional/main.cpp +++ b/tasks/example_threads/tests/functional/main.cpp @@ -78,7 +78,7 @@ const auto kGtestValues = ppc::util::ExpandToValues(kTestTasksList); const auto kPerfTestName = NesterovARunFuncTestsThreads::PrintFuncTestName; -INSTANTIATE_TEST_SUITE_P_NOLINT(PicMatrixTests, NesterovARunFuncTestsThreads, kGtestValues, kPerfTestName); +INSTANTIATE_TEST_SUITE_P_WITH_NAME(PicMatrixTests, NesterovARunFuncTestsThreads, kGtestValues, kPerfTestName); } // namespace diff --git a/tasks/example_threads/tests/performance/main.cpp b/tasks/example_threads/tests/performance/main.cpp index a982cf4ac..56fd5810d 100644 --- a/tasks/example_threads/tests/performance/main.cpp +++ b/tasks/example_threads/tests/performance/main.cpp @@ -32,6 +32,6 @@ const auto kGtestValues = ppc::util::TupleToGTestValues(kAllPerfTasks); const auto kPerfTestName = ExampleRunPerfTestThreads::CustomPerfTestName; -INSTANTIATE_TEST_SUITE_P_NOLINT(RunModeTests, ExampleRunPerfTestThreads, kGtestValues, kPerfTestName); +INSTANTIATE_TEST_SUITE_P_WITH_NAME(RunModeTests, ExampleRunPerfTestThreads, kGtestValues, kPerfTestName); } // namespace nesterov_a_test_task_threads From 262ab34f6dae50ddd28920576ad544ac6babf5ad Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 17 Jun 2025 11:39:24 +0200 Subject: [PATCH 124/141] Standardize `NOLINT` comments in `util.hpp` for improved consistency. --- modules/core/util/include/util.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/core/util/include/util.hpp b/modules/core/util/include/util.hpp index 6274693ac..7f37abcd4 100644 --- a/modules/core/util/include/util.hpp +++ b/modules/core/util/include/util.hpp @@ -13,8 +13,8 @@ #include // NOLINT(misc-include-cleaner) -using NlohmannJsonParseError = nlohmann::json::parse_error; -using NlohmannJsonTypeError = nlohmann::json::type_error; +using NlohmannJsonParseError = nlohmann::json::parse_error; // NOLINT(misc-include-cleaner) +using NlohmannJsonTypeError = nlohmann::json::type_error; // NOLINT(misc-include-cleaner) #ifdef _MSC_VER #pragma warning(pop) From 922d4c7022eeee554f8fc5b122ccbb12fa5a98ae Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 17 Jun 2025 11:49:08 +0200 Subject: [PATCH 125/141] Remove redundant type check for `std::vector` in `GetNamespaceTest`. --- modules/core/performance/tests/perf_tests.cpp | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/modules/core/performance/tests/perf_tests.cpp b/modules/core/performance/tests/perf_tests.cpp index 29fd84d9c..63aeb79d6 100644 --- a/modules/core/performance/tests/perf_tests.cpp +++ b/modules/core/performance/tests/perf_tests.cpp @@ -1,13 +1,11 @@ #include -#include #include #include #include #include #include #include -#include #include #include "core/performance/include/performance.hpp" @@ -208,18 +206,6 @@ class DummyTask : public ppc::core::Task { bool PostProcessingImpl() override { return true; } }; -class SlowTask : public ppc::core::Task { - public: - using Task::Task; - bool ValidationImpl() override { return true; } - bool PreProcessingImpl() override { return true; } - bool RunImpl() override { return true; } - bool PostProcessingImpl() override { - std::this_thread::sleep_for(std::chrono::seconds(2)); - return true; - } -}; - TEST(TaskTest, GetDynamicTypeReturnsCorrectEnum) { DummyTask task; task.SetTypeOfTask(ppc::core::TypeOfTask::kOMP); @@ -251,7 +237,7 @@ class Another {}; template class GetNamespaceTest : public ::testing::Test {}; -using TestTypes = ::testing::Types>; +using TestTypes = ::testing::Types; TYPED_TEST_SUITE(GetNamespaceTest, TestTypes); @@ -264,8 +250,6 @@ TYPED_TEST_NOLINT(GetNamespaceTest, ExtractsNamespaceCorrectly) { EXPECT_EQ(kNs, "my"); } else if constexpr (std::is_same_v) { EXPECT_EQ(kNs, ""); - } else if constexpr (std::is_same_v>) { - EXPECT_EQ(kNs, "std"); } else { FAIL() << "Unhandled type in test"; } From 62cc20e8b1d37e4c46ab11c0cab03a1c6c61c2f7 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 17 Jun 2025 14:25:04 +0200 Subject: [PATCH 126/141] Add `` include in `perf_tests.cpp` to support timing utilities. --- modules/core/performance/tests/perf_tests.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/core/performance/tests/perf_tests.cpp b/modules/core/performance/tests/perf_tests.cpp index 63aeb79d6..9c775a1f1 100644 --- a/modules/core/performance/tests/perf_tests.cpp +++ b/modules/core/performance/tests/perf_tests.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include From da8b2f97362439faa7c50ea3084e989034ca6dc9 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 17 Jun 2025 15:31:16 +0200 Subject: [PATCH 127/141] Update Valgrind command in `run_tests.py` to refine leak checking - Adjust `--show-leak-kinds` to `definite` for focused leak reporting. --- scripts/run_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/run_tests.py b/scripts/run_tests.py index 6bc6cafad..ac94cd354 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -31,7 +31,7 @@ def __init__(self): self.__ppc_env = None self.work_dir = None - self.valgrind_cmd = "valgrind --error-exitcode=1 --leak-check=full --show-leak-kinds=all" + self.valgrind_cmd = "valgrind --leak-check=full --show-leak-kinds=definite --error-exitcode=1" if platform.system() == "Windows": self.mpi_exec = "mpiexec" From 16e851964cba92ead7279f7b04f4ba26fae02af2 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 17 Jun 2025 15:39:49 +0200 Subject: [PATCH 128/141] Refactor `perf_tests.cpp`: Replace `INSTANTIATE_TEST_SUITE_P_NOLINT` with `INSTANTIATE_TEST_SUITE_P_WITH_NAME` to enhance test naming clarity. --- modules/core/performance/tests/perf_tests.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/core/performance/tests/perf_tests.cpp b/modules/core/performance/tests/perf_tests.cpp index 9c775a1f1..a8aef3c65 100644 --- a/modules/core/performance/tests/perf_tests.cpp +++ b/modules/core/performance/tests/perf_tests.cpp @@ -105,10 +105,12 @@ TEST_P(GetStringParamNameParamTest, ReturnsExpectedString) { EXPECT_EQ(ppc::core::GetStringParamName(param.input), param.expected_output); } -INSTANTIATE_TEST_SUITE_P_NOLINT(ParamTests, GetStringParamNameParamTest, - ::testing::Values(ParamTestCase{ppc::core::PerfResults::kTaskRun, "task_run"}, - ParamTestCase{ppc::core::PerfResults::kPipeline, "pipeline"}, - ParamTestCase{ppc::core::PerfResults::TypeOfRunning::kNone, "none"})); +INSTANTIATE_TEST_SUITE_P_WITH_NAME( + ParamTests, GetStringParamNameParamTest, + ::testing::Values(ParamTestCase{ppc::core::PerfResults::kTaskRun, "task_run"}, + ParamTestCase{ppc::core::PerfResults::kPipeline, "pipeline"}, + ParamTestCase{ppc::core::PerfResults::TypeOfRunning::kNone, "none"}), + [](const ::testing::TestParamInfo& info) { return info.param.expected_output; }); struct TaskTypeTestCase { ppc::core::TypeOfTask type; From 502d2d7c6fc8b61438ca3c04a55c572f4b5f27d9 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 17 Jun 2025 15:47:22 +0200 Subject: [PATCH 129/141] Refine Valgrind command in `run_tests.py` to include `--errors-for-leak-kinds` for enhanced leak reporting. --- scripts/run_tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/run_tests.py b/scripts/run_tests.py index ac94cd354..ac50dd55d 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -31,7 +31,8 @@ def __init__(self): self.__ppc_env = None self.work_dir = None - self.valgrind_cmd = "valgrind --leak-check=full --show-leak-kinds=definite --error-exitcode=1" + self.valgrind_cmd = ("valgrind --leak-check=full --show-leak-kinds=definite " + "--errors-for-leak-kinds=definite --error-exitcode=1") if platform.system() == "Windows": self.mpi_exec = "mpiexec" From c966b971e8c1092d63cf39e2a5069eb084562279 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 17 Jun 2025 16:03:00 +0200 Subject: [PATCH 130/141] Update `run_tests.py` and `perf_tests.cpp`: - Refine Valgrind command to use `--show-leak-kinds=all` for broader leak reporting. - Add `PrintTo` functions in `perf_tests.cpp` to enhance test output readability. --- modules/core/performance/tests/perf_tests.cpp | 9 +++++++++ scripts/run_tests.py | 3 +-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/core/performance/tests/perf_tests.cpp b/modules/core/performance/tests/perf_tests.cpp index a8aef3c65..24b98c673 100644 --- a/modules/core/performance/tests/perf_tests.cpp +++ b/modules/core/performance/tests/perf_tests.cpp @@ -98,6 +98,10 @@ struct ParamTestCase { std::string expected_output; }; +inline void PrintTo(const ParamTestCase& param, std::ostream* os) { + *os << "{ input = " << static_cast(param.input) << ", expected = " << param.expected_output << " }"; +} + class GetStringParamNameParamTest : public ::testing::TestWithParam {}; TEST_P(GetStringParamNameParamTest, ReturnsExpectedString) { @@ -118,6 +122,11 @@ struct TaskTypeTestCase { std::string label; }; +inline void PrintTo(const TaskTypeTestCase& param, std::ostream* os) { + *os << "{ type = " << static_cast(param.type) << ", expected = " << param.expected << ", label = " << param.label + << " }"; +} + class GetStringTaskTypeTest : public ::testing::TestWithParam { protected: std::string temp_path; diff --git a/scripts/run_tests.py b/scripts/run_tests.py index ac50dd55d..6bc6cafad 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -31,8 +31,7 @@ def __init__(self): self.__ppc_env = None self.work_dir = None - self.valgrind_cmd = ("valgrind --leak-check=full --show-leak-kinds=definite " - "--errors-for-leak-kinds=definite --error-exitcode=1") + self.valgrind_cmd = "valgrind --error-exitcode=1 --leak-check=full --show-leak-kinds=all" if platform.system() == "Windows": self.mpi_exec = "mpiexec" From 2544a4e7c0b239622fddf1d39305f36f29fdd1cb Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Tue, 17 Jun 2025 16:32:59 +0200 Subject: [PATCH 131/141] Make `PrintTo` functions `static inline` in `perf_tests.cpp` for better encapsulation. Add missing `` include. --- modules/core/performance/tests/perf_tests.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/modules/core/performance/tests/perf_tests.cpp b/modules/core/performance/tests/perf_tests.cpp index 24b98c673..7ced57997 100644 --- a/modules/core/performance/tests/perf_tests.cpp +++ b/modules/core/performance/tests/perf_tests.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -96,12 +97,11 @@ TEST(perf_tests, check_perf_task_float) { struct ParamTestCase { ppc::core::PerfResults::TypeOfRunning input; std::string expected_output; + friend inline void PrintTo(const ParamTestCase& param, std::ostream* os) { + *os << "{ input = " << static_cast(param.input) << ", expected = " << param.expected_output << " }"; + } }; -inline void PrintTo(const ParamTestCase& param, std::ostream* os) { - *os << "{ input = " << static_cast(param.input) << ", expected = " << param.expected_output << " }"; -} - class GetStringParamNameParamTest : public ::testing::TestWithParam {}; TEST_P(GetStringParamNameParamTest, ReturnsExpectedString) { @@ -120,13 +120,12 @@ struct TaskTypeTestCase { ppc::core::TypeOfTask type; std::string expected; std::string label; + friend inline void PrintTo(const TaskTypeTestCase& param, std::ostream* os) { + *os << "{ type = " << static_cast(param.type) << ", expected = " << param.expected + << ", label = " << param.label << " }"; + } }; -inline void PrintTo(const TaskTypeTestCase& param, std::ostream* os) { - *os << "{ type = " << static_cast(param.type) << ", expected = " << param.expected << ", label = " << param.label - << " }"; -} - class GetStringTaskTypeTest : public ::testing::TestWithParam { protected: std::string temp_path; From bfb23102599c60b0d4decbddb088da7424d15305 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 18 Jun 2025 10:20:29 +0200 Subject: [PATCH 132/141] Remove unnecessary `inline` qualifier from `PrintTo` functions --- modules/core/performance/tests/perf_tests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/core/performance/tests/perf_tests.cpp b/modules/core/performance/tests/perf_tests.cpp index 7ced57997..5226f54f6 100644 --- a/modules/core/performance/tests/perf_tests.cpp +++ b/modules/core/performance/tests/perf_tests.cpp @@ -97,7 +97,7 @@ TEST(perf_tests, check_perf_task_float) { struct ParamTestCase { ppc::core::PerfResults::TypeOfRunning input; std::string expected_output; - friend inline void PrintTo(const ParamTestCase& param, std::ostream* os) { + friend void PrintTo(const ParamTestCase& param, std::ostream* os) { *os << "{ input = " << static_cast(param.input) << ", expected = " << param.expected_output << " }"; } }; @@ -120,7 +120,7 @@ struct TaskTypeTestCase { ppc::core::TypeOfTask type; std::string expected; std::string label; - friend inline void PrintTo(const TaskTypeTestCase& param, std::ostream* os) { + friend void PrintTo(const TaskTypeTestCase& param, std::ostream* os) { *os << "{ type = " << static_cast(param.type) << ", expected = " << param.expected << ", label = " << param.label << " }"; } From 7e4f660f49da7f8e1928f6c92959090b679ddef5 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 18 Jun 2025 11:01:00 +0200 Subject: [PATCH 133/141] Define `FMT_CONSTEVAL` as `inline` in `libenvpp.cmake` for compatibility. --- cmake/libenvpp.cmake | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmake/libenvpp.cmake b/cmake/libenvpp.cmake index 583525cf4..4184d1541 100644 --- a/cmake/libenvpp.cmake +++ b/cmake/libenvpp.cmake @@ -10,7 +10,7 @@ ExternalProject_Add(ppc_libenvpp CONFIGURE_COMMAND "${CMAKE_COMMAND}" -S "${CMAKE_SOURCE_DIR}/3rdparty/libenvpp/" -B "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build/" -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -G${CMAKE_GENERATOR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} - -D CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} -D CMAKE_CXX_STANDARD_REQUIRED=ON + -D CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} -D CMAKE_CXX_STANDARD_REQUIRED=ON -DFMT_CONSTEVAL=inline BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --config ${CMAKE_BUILD_TYPE} --parallel INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/install") @@ -25,4 +25,6 @@ if(MSVC) set(PPC_ENVPP_LIB_NAME libenvpp) else() set(PPC_ENVPP_LIB_NAME envpp) -endif () \ No newline at end of file +endif () + +add_compile_definitions(FMT_CONSTEVAL=inline) From fcc341323e3d39a3807714ef58bae75ea93d24a7 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 18 Jun 2025 11:17:47 +0200 Subject: [PATCH 134/141] Refactor CMake scripts to replace `CONFIGURE_COMMAND` with `CMAKE_ARGS` for better clarity and maintainability. --- cmake/gtest.cmake | 22 +++++++++++++------ cmake/json.cmake | 19 ++++++++++++----- cmake/libenvpp.cmake | 16 +++++++++----- cmake/onetbb.cmake | 50 +++++++++++++++++++++++++++----------------- 4 files changed, 72 insertions(+), 35 deletions(-) diff --git a/cmake/gtest.cmake b/cmake/gtest.cmake index 5e495fd76..d625820f8 100644 --- a/cmake/gtest.cmake +++ b/cmake/gtest.cmake @@ -1,14 +1,24 @@ include_directories(${CMAKE_SOURCE_DIR}/3rdparty/googletest/googletest/include) include(ExternalProject) + ExternalProject_Add(ppc_googletest SOURCE_DIR "${CMAKE_SOURCE_DIR}/3rdparty/googletest" PREFIX "${CMAKE_CURRENT_BINARY_DIR}/ppc_googletest" BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_googletest/build" INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_googletest/install" - CONFIGURE_COMMAND "${CMAKE_COMMAND}" -S "${CMAKE_SOURCE_DIR}/3rdparty/googletest/" -B "${CMAKE_CURRENT_BINARY_DIR}/ppc_googletest/build/" - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -G${CMAKE_GENERATOR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} - -Dgtest_force_shared_crt=ON -DCMAKE_CXX_FLAGS="-w" -DCMAKE_C_FLAGS="-w" - -D CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} -D CMAKE_CXX_STANDARD_REQUIRED=ON + + CMAKE_ARGS + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} + -DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} + -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} + -DCMAKE_CXX_STANDARD_REQUIRED=ON + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_C_FLAGS=-w + -DCMAKE_CXX_FLAGS=-w + -Dgtest_force_shared_crt=ON + BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_googletest/build" --config ${CMAKE_BUILD_TYPE} --parallel - INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_googletest/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_googletest/install") + INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_googletest/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_googletest/install" +) diff --git a/cmake/json.cmake b/cmake/json.cmake index 5da720d90..97b29703b 100644 --- a/cmake/json.cmake +++ b/cmake/json.cmake @@ -1,13 +1,22 @@ include_directories(${CMAKE_SOURCE_DIR}/3rdparty/json/include) + include(ExternalProject) + ExternalProject_Add(ppc_json SOURCE_DIR "${CMAKE_SOURCE_DIR}/3rdparty/json" PREFIX "${CMAKE_CURRENT_BINARY_DIR}/ppc_json" BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/build" INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/install" - CONFIGURE_COMMAND "${CMAKE_COMMAND}" -S "${CMAKE_SOURCE_DIR}/3rdparty/json/" -B "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/build/" - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -G${CMAKE_GENERATOR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} - -D CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} -D CMAKE_CXX_STANDARD_REQUIRED=ON + + CMAKE_ARGS + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} + -DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} + -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} + -DCMAKE_CXX_STANDARD_REQUIRED=ON + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/build" --config ${CMAKE_BUILD_TYPE} --parallel - INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/install") + INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_json/install" +) diff --git a/cmake/libenvpp.cmake b/cmake/libenvpp.cmake index 4184d1541..67793ff2b 100644 --- a/cmake/libenvpp.cmake +++ b/cmake/libenvpp.cmake @@ -7,12 +7,18 @@ ExternalProject_Add(ppc_libenvpp PREFIX "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp" BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/install" - CONFIGURE_COMMAND "${CMAKE_COMMAND}" -S "${CMAKE_SOURCE_DIR}/3rdparty/libenvpp/" -B "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build/" - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -G${CMAKE_GENERATOR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -D CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -D CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} - -D CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} -D CMAKE_CXX_STANDARD_REQUIRED=ON -DFMT_CONSTEVAL=inline + CMAKE_ARGS + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} + -DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} + -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} + -DCMAKE_CXX_STANDARD_REQUIRED=ON + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DFMT_CONSTEVAL=inline BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --config ${CMAKE_BUILD_TYPE} --parallel - INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/install") + INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/install" +) string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_lower) if(cmake_build_type_lower STREQUAL "debug") diff --git a/cmake/onetbb.cmake b/cmake/onetbb.cmake index 3a2d4efa1..aecf7840c 100644 --- a/cmake/onetbb.cmake +++ b/cmake/onetbb.cmake @@ -1,31 +1,43 @@ -# Build Core OneTBB components -include_directories(${CMAKE_SOURCE_DIR}/3rdparty/onetbb/include) - include(ExternalProject) +include_directories("${CMAKE_SOURCE_DIR}/3rdparty/onetbb/include") + if(WIN32) - set(ppc_onetbb_TEST_COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install/bin" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") + set(ppc_onetbb_TEST_COMMAND "${CMAKE_COMMAND}" -E copy_directory + "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install/bin" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" + ) else() set(ppc_onetbb_TEST_COMMAND "") endif() ExternalProject_Add(ppc_onetbb - SOURCE_DIR "${CMAKE_SOURCE_DIR}/3rdparty/onetbb" - PREFIX "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb" - BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" - INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install" - CONFIGURE_COMMAND "${CMAKE_COMMAND}" -S "${CMAKE_SOURCE_DIR}/3rdparty/onetbb/" -B "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build/" - -DCMAKE_CXX_FLAGS="-w" -DCMAKE_C_FLAGS="-w" - -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - -DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} - -G${CMAKE_GENERATOR} -DTBB_TEST=OFF -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -D CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} -D CMAKE_CXX_STANDARD_REQUIRED=ON - BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" --config ${CMAKE_BUILD_TYPE} --parallel - INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install" - TEST_COMMAND ${ppc_onetbb_TEST_COMMAND} + SOURCE_DIR "${CMAKE_SOURCE_DIR}/3rdparty/onetbb" + PREFIX "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb" + BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" + INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install" + + CMAKE_ARGS + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} + -DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} + -DCMAKE_C_FLAGS=-w + -DCMAKE_CXX_FLAGS=-w + -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} + -DCMAKE_CXX_STANDARD_REQUIRED=ON + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DTBB_TEST=OFF + + BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" --config ${CMAKE_BUILD_TYPE} --parallel + INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install" + TEST_COMMAND ${ppc_onetbb_TEST_COMMAND} +) + +install( + DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install/" + DESTINATION "${CMAKE_INSTALL_PREFIX}" ) -install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/ppc_onetbb/install/" - DESTINATION "${CMAKE_INSTALL_PREFIX}") string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_lower) if(cmake_build_type_lower STREQUAL "debug") From 78eb3a018c44a1d370f61c5e4cdfc6bc295639b1 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 18 Jun 2025 11:24:32 +0200 Subject: [PATCH 135/141] Refactor CMake scripts to replace `CONFIGURE_COMMAND` with `CMAKE_ARGS` for better clarity and maintainability. --- cmake/libenvpp.cmake | 6 +++--- cmake/libenvpp_toolchain.cmake | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 cmake/libenvpp_toolchain.cmake diff --git a/cmake/libenvpp.cmake b/cmake/libenvpp.cmake index 67793ff2b..019f6b6c1 100644 --- a/cmake/libenvpp.cmake +++ b/cmake/libenvpp.cmake @@ -15,7 +15,7 @@ ExternalProject_Add(ppc_libenvpp -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED=ON -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -DFMT_CONSTEVAL=inline + -DCMAKE_TOOLCHAIN_FILE=${CMAKE_SOURCE_DIR}/cmake/libenvpp_toolchain.cmake BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --config ${CMAKE_BUILD_TYPE} --parallel INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/install" ) @@ -27,10 +27,10 @@ else() set(PPC_FMT_LIB_NAME fmt) endif() -if(MSVC) +if(WIN32) set(PPC_ENVPP_LIB_NAME libenvpp) else() set(PPC_ENVPP_LIB_NAME envpp) -endif () +endif() add_compile_definitions(FMT_CONSTEVAL=inline) diff --git a/cmake/libenvpp_toolchain.cmake b/cmake/libenvpp_toolchain.cmake new file mode 100644 index 000000000..9a7cae29b --- /dev/null +++ b/cmake/libenvpp_toolchain.cmake @@ -0,0 +1,3 @@ +# libenvpp_toolchain.cmake +set(CMAKE_CXX_FLAGS_INIT "-DFMT_CONSTEVAL=inline") +set(CMAKE_C_FLAGS_INIT "-DFMT_CONSTEVAL=inline") From 8927ddd4b7f244f6d6ebcdabda2719168ad09c5e Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 18 Jun 2025 11:34:20 +0200 Subject: [PATCH 136/141] Set `CMAKE_CXX_STANDARD` to 20 in `libenvpp.cmake` for enforcing C++20 compliance. --- cmake/libenvpp.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/libenvpp.cmake b/cmake/libenvpp.cmake index 019f6b6c1..13c4056f3 100644 --- a/cmake/libenvpp.cmake +++ b/cmake/libenvpp.cmake @@ -16,6 +16,7 @@ ExternalProject_Add(ppc_libenvpp -DCMAKE_CXX_STANDARD_REQUIRED=ON -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_SOURCE_DIR}/cmake/libenvpp_toolchain.cmake + -DCMAKE_CXX_STANDARD=20 BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --config ${CMAKE_BUILD_TYPE} --parallel INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/install" ) From 4136a795378966de6621c9092e25d011e61f9943 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 18 Jun 2025 15:53:31 +0200 Subject: [PATCH 137/141] Add comprehensive Doxygen documentation for task classes, utilities, and performance modules. Configure Doxyfile for extended metadata extraction. --- Doxyfile | 14 ++- docs/user_guide/api.rst | 4 +- .../core/performance/include/performance.hpp | 10 +- modules/core/runners/include/runners.hpp | 14 +++ modules/core/task/include/task.hpp | 100 +++++++++++++++--- modules/core/util/include/func_test_util.hpp | 7 ++ modules/core/util/include/perf_test_util.hpp | 5 + modules/core/util/include/util.hpp | 5 +- 8 files changed, 133 insertions(+), 26 deletions(-) diff --git a/Doxyfile b/Doxyfile index f34d72ede..0b9a33624 100644 --- a/Doxyfile +++ b/Doxyfile @@ -4,9 +4,11 @@ PROJECT_BRIEF = "Parallel Programming Course" # Input INPUT = modules/core/task/include \ - modules/core/task/src \ modules/core/util/include \ - modules/core/util/src + modules/core/util/src \ + modules/core/performance/include \ + modules/core/runners/include \ + modules/core/runners/src FILE_PATTERNS = *.h *.c *.hpp *.cpp RECURSIVE = YES @@ -15,3 +17,11 @@ GENERATE_HTML = NO GENERATE_LATEX = NO GENERATE_XML = YES XML_OUTPUT = xml + +# Docs +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_TEMPLATE_PARAMS = YES +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = NO \ No newline at end of file diff --git a/docs/user_guide/api.rst b/docs/user_guide/api.rst index 6d83a131e..e5b18d4f9 100644 --- a/docs/user_guide/api.rst +++ b/docs/user_guide/api.rst @@ -4,5 +4,5 @@ API Reference .. toctree:: :maxdepth: 1 -.. doxygenindex:: - :project: ParallelProgrammingCourse +.. .. doxygenindex:: +.. :project: ParallelProgrammingCourse diff --git a/modules/core/performance/include/performance.hpp b/modules/core/performance/include/performance.hpp index 32114e6c9..72f1a403c 100644 --- a/modules/core/performance/include/performance.hpp +++ b/modules/core/performance/include/performance.hpp @@ -14,13 +14,16 @@ namespace ppc::core { struct PerfAttr { - // count of task's running + /// @brief Number of times the task is run for performance evaluation. uint64_t num_running = 5; + /// @brief Timer function returning current time in seconds. + /// @cond std::function current_timer = [&] { return -1.0; }; + /// @endcond }; struct PerfResults { - // measurement of task's time (in seconds) + /// @brief Measured execution time in seconds. double time_sec = 0.0; enum TypeOfRunning : uint8_t { kPipeline, kTaskRun, kNone } type_of_running = kNone; constexpr static double kMaxTime = 10.0; @@ -87,7 +90,8 @@ class Perf { throw std::runtime_error(err_msg.str().c_str()); } } - // Get performance result structure of the current task + /// @brief Retrieves the performance test results. + /// @return The latest PerfResults structure. PerfResults GetPerfResults() { return perf_results_; } private: diff --git a/modules/core/runners/include/runners.hpp b/modules/core/runners/include/runners.hpp index bf04ec5f2..c1bfb4d9c 100644 --- a/modules/core/runners/include/runners.hpp +++ b/modules/core/runners/include/runners.hpp @@ -7,25 +7,39 @@ namespace ppc::core { +/// @brief GTest event listener that checks for unread MPI messages after each test. +/// @note Used to detect unexpected inter-process communication leftovers. class UnreadMessagesDetector : public ::testing::EmptyTestEventListener { public: UnreadMessagesDetector() = default; + /// @brief Called by GTest after a test ends. Checks for unread messages. void OnTestEnd(const ::testing::TestInfo& /*test_info*/) override; private: }; +/// @brief GTest event listener that prints additional information on test failures in worker processes. +/// @details Includes MPI rank info in failure output for debugging. class WorkerTestFailurePrinter : public ::testing::EmptyTestEventListener { public: + /// @brief Constructs the listener with a base listener for delegation. + /// @param base A shared pointer to another GTest event listener. explicit WorkerTestFailurePrinter(std::shared_ptr<::testing::TestEventListener> base) : base_(std::move(base)) {} + /// @brief Called after a test ends. Passes call to base listener and prints failures with rank. void OnTestEnd(const ::testing::TestInfo& test_info) override; + /// @brief Called when a test part fails. Prints MPI rank info along with the failure. void OnTestPartResult(const ::testing::TestPartResult& test_part_result) override; private: + /// @brief Prints the MPI rank of the current process to stderr. static void PrintProcessRank(); std::shared_ptr<::testing::TestEventListener> base_; }; +/// @brief Initializes the testing environment (e.g., MPI, logging). +/// @param argc Argument count. +/// @param argv Argument vector. +/// @return Exit code: 0 for success, non-zero for failure. int Init(int argc, char** argv); } // namespace ppc::core diff --git a/modules/core/task/include/task.hpp b/modules/core/task/include/task.hpp index 5d3d48368..512bc9d6c 100644 --- a/modules/core/task/include/task.hpp +++ b/modules/core/task/include/task.hpp @@ -19,9 +19,36 @@ using namespace std::chrono; namespace ppc::core { -enum TypeOfTask : uint8_t { kALL, kMPI, kOMP, kSEQ, kSTL, kTBB, kUnknown }; -enum StatusOfTask : uint8_t { kEnabled, kDisabled }; +/// @brief Represents the type of task (parallelization technology). +/// @details Used to select the implementation type in tests and execution logic. +enum TypeOfTask : uint8_t { + /// Use all available implementations + kALL, + /// MPI (Message Passing Interface) + kMPI, + /// OpenMP (Open Multi-Processing) + kOMP, + /// Sequential implementation + kSEQ, + /// Standard Thread Library (STL threads) + kSTL, + /// Intel Threading Building Blocks (TBB) + kTBB, + /// Unknown task type + kUnknown +}; + +/// @brief Indicates whether a task is enabled or disabled. +enum StatusOfTask : uint8_t { + /// Task is enabled and should be executed + kEnabled, + /// Task is disabled and will be skipped + kDisabled +}; +/// @brief Returns a string representation of the task status. +/// @param status_of_task Task status (enabled or disabled). +/// @return "enabled" if the task is enabled, otherwise "disabled". inline std::string GetStringTaskStatus(StatusOfTask status_of_task) { if (status_of_task == kDisabled) { return "disabled"; @@ -29,6 +56,11 @@ inline std::string GetStringTaskStatus(StatusOfTask status_of_task) { return "enabled"; } +/// @brief Returns a string representation of the task type based on the JSON settings file. +/// @param type_of_task Type of the task. +/// @param settings_file_path Path to the JSON file containing task type strings. +/// @return Formatted string combining the task type and its corresponding value from the file. +/// @throws std::runtime_error If the file cannot be opened. inline std::string GetStringTaskType(TypeOfTask type_of_task, const std::string &settings_file_path) { std::ifstream file(settings_file_path); if (!file.is_open()) { @@ -65,20 +97,24 @@ inline std::string GetStringTaskType(TypeOfTask type_of_task, const std::string enum StateOfTesting : uint8_t { kFunc, kPerf }; -// Memory of inputs and outputs need to be initialized before create an object of -// Task class template +/// @brief Base abstract class representing a generic task with a defined pipeline. +/// @tparam InType Input data type. +/// @tparam OutType Output data type. class Task { public: + /// @brief Constructs a new Task object. explicit Task(StateOfTesting /*state_of_testing*/ = StateOfTesting::kFunc) { functions_order_.clear(); } - // validation of data and validation of task attributes before running + /// @brief Validates input data and task attributes before execution. + /// @return True if validation is successful. virtual bool Validation() final { InternalOrderTest(__builtin_FUNCTION()); return ValidationImpl(); } - // pre-processing of input data + /// @brief Performs preprocessing on the input data. + /// @return True if preprocessing is successful. virtual bool PreProcessing() final { InternalOrderTest(__builtin_FUNCTION()); if (state_of_testing_ == StateOfTesting::kFunc) { @@ -87,13 +123,15 @@ class Task { return PreProcessingImpl(); } - // realization of the current task + /// @brief Executes the main logic of the task. + /// @return True if execution is successful. virtual bool Run() final { InternalOrderTest(__builtin_FUNCTION()); return RunImpl(); } - // post-processing of output data + /// @brief Performs postprocessing on the output data. + /// @return True if postprocessing is successful. virtual bool PostProcessing() final { InternalOrderTest(__builtin_FUNCTION()); if (state_of_testing_ == StateOfTesting::kFunc) { @@ -102,25 +140,36 @@ class Task { return PostProcessingImpl(); } - // get state of testing + /// @brief Returns the current testing mode. + /// @return Reference to the current StateOfTesting. StateOfTesting &GetStateOfTesting() { return state_of_testing_; } - // set a type of task + /// @brief Sets the dynamic task type. + /// @param type_of_task Task type to set. void SetTypeOfTask(TypeOfTask type_of_task) { type_of_task_ = type_of_task; } - // get a dynamic type of task + /// @brief Returns the dynamic task type. + /// @return Current dynamic task type. [[nodiscard]] TypeOfTask GetDynamicTypeOfTask() const { return type_of_task_; } - // get a dynamic type of task + /// @brief Returns the current task status. + /// @return Task status (enabled or disabled). [[nodiscard]] StatusOfTask GetStatusOfTask() const { return status_of_task_; } - // get a static type of task + /// @brief Returns the static task type. + /// @return Static task type (default: kUnknown). static constexpr TypeOfTask GetStaticTypeOfTask() { return TypeOfTask::kUnknown; } + /// @brief Returns a reference to the input data. + /// @return Reference to the task's input data. InType &GetInput() { return input_; } + /// @brief Returns a reference to the output data. + /// @return Reference to the task's output data. OutType &GetOutput() { return output_; } + /// @brief Destructor. Verifies that the pipeline was executed in the correct order. + /// @note Terminates the program if pipeline order is incorrect or incomplete. virtual ~Task() { if (!functions_order_.empty() || !was_worked_) { std::cerr << "ORDER OF FUNCTIONS IS NOT RIGHT! \n Expected - \"Validation\", \"PreProcessing\", \"Run\", " @@ -132,6 +181,8 @@ class Task { } protected: + /// @brief Verifies the correct order of pipeline method calls. + /// @param str Name of the method being called. virtual void InternalOrderTest(const std::string &str) final { functions_order_.push_back(str); if (str == "PostProcessing" && IsFullPipelineStage()) { @@ -141,6 +192,9 @@ class Task { } } + /// @brief Measures execution time between preprocessing and postprocessing steps. + /// @param str Name of the method being timed. + /// @throws std::runtime_error If execution exceeds the allowed time limit. virtual void InternalTimeTest(const std::string &str) final { if (str == "PreProcessing") { tmp_time_point_ = std::chrono::high_resolution_clock::now(); @@ -162,16 +216,20 @@ class Task { } } - // implementation of "Validation" function + /// @brief User-defined validation logic. + /// @return True if validation is successful. virtual bool ValidationImpl() = 0; - // implementation of "PreProcessing" function + /// @brief User-defined preprocessing logic. + /// @return True if preprocessing is successful. virtual bool PreProcessingImpl() = 0; - // implementation of "Run" function + /// @brief User-defined task execution logic. + /// @return True if run is successful. virtual bool RunImpl() = 0; - // implementation of "PostProcessing" function + /// @brief User-defined postprocessing logic. + /// @return True if postprocessing is successful. virtual bool PostProcessingImpl() = 0; private: @@ -198,9 +256,17 @@ class Task { } }; +/// @brief Smart pointer alias for Task. +/// @tparam InType Input data type. +/// @tparam OutType Output data type. template using TaskPtr = std::shared_ptr>; +/// @brief Constructs and returns a shared pointer to a task with the given input. +/// @tparam TaskType Type of the task to create. +/// @tparam InType Type of the input. +/// @param in Input to pass to the task constructor. +/// @return Shared pointer to the newly created task. template std::shared_ptr TaskGetter(InType in) { return std::make_shared(in); diff --git a/modules/core/util/include/func_test_util.hpp b/modules/core/util/include/func_test_util.hpp index 5493e80d0..c36250c3d 100644 --- a/modules/core/util/include/func_test_util.hpp +++ b/modules/core/util/include/func_test_util.hpp @@ -31,9 +31,15 @@ concept HasPrintTestParam = requires(TestType value) { }; template +/// @brief Base class for running functional tests on parallel tasks. +/// @tparam InType Type of input data. +/// @tparam OutType Type of output data. +/// @tparam TestType Type of the test case or parameter. class BaseRunFuncTests : public ::testing::TestWithParam> { public: virtual bool CheckTestOutputData(OutType& output_data) = 0; + /// @brief Provides input data for the task. + /// @return Initialized input data. virtual InType GetTestInputData() = 0; template @@ -79,6 +85,7 @@ class BaseRunFuncTests : public ::testing::TestWithParam& test_param) { task_ = std::get(test_param)(GetTestInputData()); diff --git a/modules/core/util/include/perf_test_util.hpp b/modules/core/util/include/perf_test_util.hpp index 460f739ae..e877b4b82 100644 --- a/modules/core/util/include/perf_test_util.hpp +++ b/modules/core/util/include/perf_test_util.hpp @@ -28,8 +28,12 @@ using PerfTestParam = std::tuple; template +/// @brief Base class for performance testing of parallel tasks. +/// @tparam InType Input data type. +/// @tparam OutType Output data type. class BaseRunPerfTests : public ::testing::TestWithParam> { public: + /// @brief Generates a readable name for the performance test case. static std::string CustomPerfTestName(const ::testing::TestParamInfo>& info) { return ppc::core::GetStringParamName(std::get(info.param)) + "_" + std::get(info.param); @@ -37,6 +41,7 @@ class BaseRunPerfTests : public ::testing::TestWithParam // NOLINT(misc-include-cleaner) +/// @brief JSON namespace used for settings and config parsing. using NlohmannJsonParseError = nlohmann::json::parse_error; // NOLINT(misc-include-cleaner) -using NlohmannJsonTypeError = nlohmann::json::type_error; // NOLINT(misc-include-cleaner) - +/// @brief JSON namespace used for settings and config typing. +using NlohmannJsonTypeError = nlohmann::json::type_error; // NOLINT(misc-include-cleaner) #ifdef _MSC_VER #pragma warning(pop) #endif From 68f6b42d6addea5337bd98e6c19b3094aaed7a59 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 18 Jun 2025 18:42:21 +0200 Subject: [PATCH 138/141] Remove redundant `libenvpp_toolchain.cmake` and inline `FMT_CONSTEVAL` definitions directly in `libenvpp.cmake`. Simplify and clean up CMake configuration. --- cmake/libenvpp.cmake | 12 +++++++----- cmake/libenvpp_toolchain.cmake | 3 --- 2 files changed, 7 insertions(+), 8 deletions(-) delete mode 100644 cmake/libenvpp_toolchain.cmake diff --git a/cmake/libenvpp.cmake b/cmake/libenvpp.cmake index 13c4056f3..dccb5a5d7 100644 --- a/cmake/libenvpp.cmake +++ b/cmake/libenvpp.cmake @@ -1,6 +1,12 @@ include_directories(${CMAKE_SOURCE_DIR}/3rdparty/libenvpp/include) include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/3rdparty/libenvpp/external/fmt/include) +if(WIN32) + set(PPC_FMT_DISABLE_CONSTEVAL "/DFMT_CONSTEVAL=inline") +else() + set(PPC_FMT_DISABLE_CONSTEVAL "-DFMT_CONSTEVAL=inline") +endif() + include(ExternalProject) ExternalProject_Add(ppc_libenvpp SOURCE_DIR "${CMAKE_SOURCE_DIR}/3rdparty/libenvpp" @@ -12,11 +18,9 @@ ExternalProject_Add(ppc_libenvpp -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER} -DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} - -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED=ON -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -DCMAKE_TOOLCHAIN_FILE=${CMAKE_SOURCE_DIR}/cmake/libenvpp_toolchain.cmake - -DCMAKE_CXX_STANDARD=20 + -DCMAKE_CXX_FLAGS=${PPC_FMT_DISABLE_CONSTEVAL} BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --config ${CMAKE_BUILD_TYPE} --parallel INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/install" ) @@ -33,5 +37,3 @@ if(WIN32) else() set(PPC_ENVPP_LIB_NAME envpp) endif() - -add_compile_definitions(FMT_CONSTEVAL=inline) diff --git a/cmake/libenvpp_toolchain.cmake b/cmake/libenvpp_toolchain.cmake deleted file mode 100644 index 9a7cae29b..000000000 --- a/cmake/libenvpp_toolchain.cmake +++ /dev/null @@ -1,3 +0,0 @@ -# libenvpp_toolchain.cmake -set(CMAKE_CXX_FLAGS_INIT "-DFMT_CONSTEVAL=inline") -set(CMAKE_C_FLAGS_INIT "-DFMT_CONSTEVAL=inline") From 3f7caa77472b50ada3eacfed2fb27a0baa1a53a6 Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 18 Jun 2025 18:57:27 +0200 Subject: [PATCH 139/141] Update `libenvpp.cmake` to redefine `PPC_FMT_FLAGS` with exception handling flags for both Windows and non-Windows platforms. --- cmake/libenvpp.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/libenvpp.cmake b/cmake/libenvpp.cmake index dccb5a5d7..f4d73e9b6 100644 --- a/cmake/libenvpp.cmake +++ b/cmake/libenvpp.cmake @@ -2,9 +2,9 @@ include_directories(${CMAKE_SOURCE_DIR}/3rdparty/libenvpp/include) include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/3rdparty/libenvpp/external/fmt/include) if(WIN32) - set(PPC_FMT_DISABLE_CONSTEVAL "/DFMT_CONSTEVAL=inline") + set(PPC_FMT_FLAGS "/EHsc /DFMT_CONSTEVAL=inline") else() - set(PPC_FMT_DISABLE_CONSTEVAL "-DFMT_CONSTEVAL=inline") + set(PPC_FMT_FLAGS "-fexceptions -DFMT_CONSTEVAL=inline") endif() include(ExternalProject) @@ -20,7 +20,7 @@ ExternalProject_Add(ppc_libenvpp -DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER} -DCMAKE_CXX_STANDARD_REQUIRED=ON -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -DCMAKE_CXX_FLAGS=${PPC_FMT_DISABLE_CONSTEVAL} + -DCMAKE_CXX_FLAGS=${PPC_FMT_FLAGS} BUILD_COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --config ${CMAKE_BUILD_TYPE} --parallel INSTALL_COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/build" --prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_libenvpp/install" ) From ccaf5244be42be9dc2a5c728250ac4c7c97dd73e Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 18 Jun 2025 19:43:19 +0200 Subject: [PATCH 140/141] Add unit tests for `GetNamespace` function to verify namespace extraction behavior --- modules/core/util/tests/util.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/modules/core/util/tests/util.cpp b/modules/core/util/tests/util.cpp index 929272926..7daae1c60 100644 --- a/modules/core/util/tests/util.cpp +++ b/modules/core/util/tests/util.cpp @@ -25,3 +25,24 @@ TEST(util_tests, threads_control_check_openmp_disabled_valgrind) { // Check Result ASSERT_EQ(ppc_num_threads, omp_num_threads); } + +namespace test_ns { +struct TypeInNamespace {}; +} // namespace test_ns + +struct PlainType {}; + +TEST(GetNamespaceTest, ReturnsExpectedNamespace) { + constexpr auto kNs = ppc::util::GetNamespace(); + EXPECT_EQ(kNs, "test_ns"); +} + +TEST(GetNamespaceTest, ReturnsEmptyIfNoNamespace_PrimitiveType) { + constexpr auto kNs = ppc::util::GetNamespace(); + EXPECT_EQ(kNs, ""); +} + +TEST(GetNamespaceTest, ReturnsEmptyIfNoNamespace_PlainStruct) { + constexpr auto kNs = ppc::util::GetNamespace(); + EXPECT_EQ(kNs, ""); +} From 34875931c762d21b8b81d839f3e8b445709494bf Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Wed, 18 Jun 2025 21:20:14 +0200 Subject: [PATCH 141/141] Add additional unit tests for `GetNamespace` to cover varied namespace extraction scenarios --- modules/core/util/tests/util.cpp | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/modules/core/util/tests/util.cpp b/modules/core/util/tests/util.cpp index 7daae1c60..04efbc289 100644 --- a/modules/core/util/tests/util.cpp +++ b/modules/core/util/tests/util.cpp @@ -46,3 +46,36 @@ TEST(GetNamespaceTest, ReturnsEmptyIfNoNamespace_PlainStruct) { constexpr auto kNs = ppc::util::GetNamespace(); EXPECT_EQ(kNs, ""); } + +namespace test_ns { +struct Nested {}; +} // namespace test_ns + +TEST(GetNamespaceTest, ReturnsNamespaceCorrectly) { + constexpr auto kNs = ppc::util::GetNamespace(); + EXPECT_EQ(kNs, "test_ns"); +} + +struct NoNamespaceType {}; + +TEST(GetNamespaceTest, NoNamespaceInType) { + constexpr auto kNs = ppc::util::GetNamespace(); + EXPECT_EQ(kNs, ""); +} + +template +struct NotATemplate {}; + +TEST(GetNamespaceTest, NoKeyInPrettyFunction) { + constexpr auto kNs = ppc::util::GetNamespace>(); + EXPECT_EQ(kNs, ""); +} + +namespace crazy { +struct VeryLongTypeNameWithOnlyLettersAndUnderscores {}; +} // namespace crazy + +TEST(GetNamespaceTest, NoTerminatorCharactersInPrettyFunction) { + constexpr auto kNs = ppc::util::GetNamespace(); + EXPECT_EQ(kNs, "crazy"); +}