@@ -82,17 +82,23 @@ set(PLSSVM_BASE_SOURCES
8282 ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/backends/SYCL/kernel_invocation_types.cpp
8383 ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/backends/stdpar/implementation_types.cpp
8484 ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/backends/execution_range.cpp
85+ ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/data_set/min_max_scaler.cpp
8586 ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/detail/cmd/parser_predict.cpp
8687 ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/detail/cmd/parser_scale.cpp
8788 ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/detail/cmd/parser_train.cpp
8889 ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/detail/io/file_reader.cpp
8990 ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/detail/data_distribution.cpp
9091 ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/detail/memory_size.cpp
9192 ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/detail/sha256.cpp
92- ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/detail/string_conversion.cpp
9393 ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/detail/string_utility.cpp
9494 ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/detail/utility.cpp
9595 ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/exceptions/exceptions.cpp
96+ ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/exceptions/source_location.cpp
97+ ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/mpi/detail/information.cpp
98+ ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/mpi/detail/utility.cpp
99+ ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/mpi/detail/version .cpp
100+ ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/mpi/communicator.cpp
101+ ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/mpi/environment .cpp
96102 ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/svm/csvm.cpp
97103 ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/version /version .cpp
98104 ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/version /git_metadata/git_metadata.cpp
@@ -233,6 +239,38 @@ else ()
233239 message (WARNING "Couldn't find OpenMP. Note that in a multi-GPU setting this will result in serialized kernel calls across all GPUs!" )
234240endif ()
235241
242+ ########################################################################################################################
243+ # check for MPI (optional) ##
244+ ########################################################################################################################
245+ # check for MPI
246+ set (PLSSVM_ENABLE_MPI AUTO CACHE STRING "Enable distributed memory support via MPI" )
247+ set_property (CACHE PLSSVM_ENABLE_MPI PROPERTY STRINGS AUTO ON OFF )
248+ if (PLSSVM_ENABLE_MPI MATCHES "AUTO" OR PLSSVM_ENABLE_MPI)
249+ list (APPEND CMAKE_MESSAGE_INDENT "MPI: " )
250+ message (CHECK_START "Checking for MPI" )
251+
252+ # try finding MPI
253+ find_package (MPI)
254+
255+ if (MPI_FOUND)
256+ # MPI found
257+ message (CHECK_PASS "found " )
258+
259+ message (STATUS "Found MPI ${MPI_CXX_VERSION} for distributed memory support." )
260+ set (PLSSVM_FOUND_MPI ON )
261+ target_link_libraries (${PLSSVM_BASE_LIBRARY_NAME} PUBLIC MPI::MPI_CXX)
262+ target_compile_definitions (${PLSSVM_BASE_LIBRARY_NAME} PUBLIC PLSSVM_HAS_MPI_ENABLED)
263+ else ()
264+ # MPI not found
265+ message (CHECK_FAIL "not found" )
266+ if (PLSSVM_ENABLE_MPI MATCHES "ON" )
267+ message (SEND_ERROR "Cannot find requested MPI!" )
268+ endif ()
269+ endif ()
270+
271+ list (POP_BACK CMAKE_MESSAGE_INDENT)
272+ endif ()
273+
236274########################################################################################################################
237275# create executables #
238276########################################################################################################################
@@ -260,6 +298,7 @@ list(
260298########################################################################################################################
261299# coverage analysis only possible with the Coverage CMAKE_BUILD_TYPE
262300if (uppercase_CMAKE_BUILD_TYPE MATCHES COVERAGE)
301+ list (APPEND CMAKE_MESSAGE_INDENT "coverage: " )
263302 # must be linux
264303 if (WIN32 OR APPLE )
265304 message (FATAL_ERROR "Only Linux is supported for the coverage analysis." )
@@ -268,31 +307,61 @@ if (uppercase_CMAKE_BUILD_TYPE MATCHES COVERAGE)
268307 if (NOT CMAKE_CXX_COMPILER_ID MATCHES "GNU" )
269308 message (FATAL_ERROR "Only GCC is supported for the coverage analysis." )
270309 endif ()
310+ message (STATUS "Enable code coverage analysis using lcov and genhtml." )
311+
271312 # tests must be available for a coverage analysis
272313 message (STATUS "Enabling tests since they are necessary for the coverage analysis." )
273314 set (PLSSVM_ENABLE_TESTING ON CACHE BOOL "" FORCE)
315+ # disable fast-math like it should be in the normal tests
316+ message (STATUS "Disabling fast-math for the tests." )
317+ set (PLSSVM_ENABLE_FAST_MATH OFF CACHE BOOL "" FORCE)
274318 # assertions must be available for a coverage analysis
275319 message (STATUS "Enabling assertions since they are necessary for the coverage analysis." )
276320 set (PLSSVM_ENABLE_ASSERTS ON CACHE BOOL "" FORCE)
321+ # LTO must be disabled for a coverage analysis
322+ message (STATUS "Disabling LTO since it may interfere with the coverage analysis." )
323+ set (PLSSVM_ENABLE_LTO OFF CACHE BOOL "" FORCE)
324+
325+ # also enable code coverage for nvcc
326+ set (CMAKE_CUDA_FLAGS "-Xcompiler '-O0 -g --coverage -lgcov'" )
327+
328+ # check that the necessary executables are available
329+ find_program (PLSSVM_LCOV lcov REQUIRED)
330+ find_program (PLSSVM_GENHTML genhtml REQUIRED)
331+ find_program (PLSSVM_CPPFILT c++filt)
332+ if (PLSSVM_CPPFILT)
333+ set (PLSSVM_DEMANGLE_USING_CPPFILT --demangle-cpp)
334+ endif ()
277335
278- message (STATUS "Enable code coverage analysis using lcov." )
279-
280- # Create the coverage target. Run coverage tests with 'make coverage'
336+ # Create the coverage target. Run coverage tests with 'ctest --build . --target coverage'
337+ set (PLSSVM_COVERAGE_REPORT_OUTPUT_DIRECTORY "coverage_report" )
281338 add_custom_target (
282339 coverage
283- COMMAND lcov --zerocounters --directory .
284- COMMAND lcov --capture -d . --initial --output -file test_base.info
285- COMMAND mkdir -p coverage
286- COMMAND ${CMAKE_MAKE_PROGRAM} test || true
287- COMMAND lcov --capture -d . --output -file test_test.info
288- COMMAND lcov --add-tracefile test_base.info --add-tracefile test_test.info -o test_total.info
289- COMMAND lcov --remove test_total.info '/usr/*' '*/build /*' '*/tests/*' '*/_deps/*' -o test_clean.info
290- COMMAND genhtml test_clean.info --output -directory coverage --title "PLSSVM Test Coverage" --show-details --legend
291- BYPRODUCTS ${CMAKE_BINARY_DIR} /test_base.info
292- ${CMAKE_BINARY_DIR} /test_test.info
293- ${CMAKE_BINARY_DIR} /test_total.info
294- ${CMAKE_BINARY_DIR} /test_clean.info
295- ${CMAKE_BINARY_DIR} /coverage
340+ COMMENT "Running tests and generating coverage report..."
341+ # Cleanup previous coverage data
342+ COMMAND ${PLSSVM_LCOV} --directory . --zerocounters
343+ COMMAND ${CMAKE_COMMAND} -E remove -f coverage.info coverage_init.info coverage_tests.info "${PLSSVM_COVERAGE_REPORT_OUTPUT_DIRECTORY} "
344+ # Capture initial zero coverage baseline (useful for untouched files)
345+ COMMAND ${PLSSVM_LCOV} --directory . --capture --initial --rc geninfo_unexecuted_blocks=1 --include '*/PLSSVM/src/*' --include '*/PLSSVM/include /*'
346+ --output -file coverage_init.info
347+ # Be sure the output directory exists
348+ COMMAND mkdir -p "${PLSSVM_COVERAGE_REPORT_OUTPUT_DIRECTORY} "
349+ # Run tests
350+ COMMAND ${CMAKE_CTEST_COMMAND} --parallel 8 || true
351+ # Capture coverage info
352+ COMMAND ${PLSSVM_LCOV} --directory . --capture --rc geninfo_unexecuted_blocks=1 --include '*/PLSSVM/src/*' --include '*/PLSSVM/include /*' --output -file
353+ coverage_tests.info
354+ # Combine coverage files (in case of multiple test runs)
355+ COMMAND ${PLSSVM_LCOV} --add-tracefile coverage_init.info --add-tracefile coverage_tests.info --output -file coverage.info
356+ # Generate HTML report
357+ COMMAND ${PLSSVM_GENHTML} coverage.info --output -directory "${PLSSVM_COVERAGE_REPORT_OUTPUT_DIRECTORY} " --title "PLSSVM Test Coverage" --show-details
358+ --legend --frames ${PLSSVM_DEMANGLE_USING_CPPFILT}
359+ # Summary message
360+ COMMAND ${CMAKE_COMMAND} -E echo "Coverage report generated in: ${CMAKE_BINARY_DIR} /${PLSSVM_COVERAGE_REPORT_OUTPUT_DIRECTORY} "
361+ # Specify byproducts for CMake
362+ BYPRODUCTS "${CMAKE_BINARY_DIR} /coverage_init.info" "${CMAKE_BINARY_DIR} /coverage_tests.info" "${CMAKE_BINARY_DIR} /coverage.info"
363+ "${CMAKE_BINARY_DIR} /${PLSSVM_COVERAGE_REPORT_OUTPUT_DIRECTORY} "
364+ # Set the working directory
296365 WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
297366 )
298367
@@ -307,8 +376,10 @@ if (uppercase_CMAKE_BUILD_TYPE MATCHES COVERAGE)
307376 DEPENDS clean
308377 COMMENT "remove all coverage files"
309378 COMMAND ${CMAKE_MAKE_PROGRAM} clean
379+ COMMAND ${CMAKE_COMMAND} -E remove -f coverage.info coverage_init.info coverage_tests.info ${PLSSVM_COVERAGE_REPORT_OUTPUT_DIRECTORY}
310380 COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_SOURCE_DIR} /cmake/delete_coverage_files.cmake" TARGET clean_coverage
311381 )
382+ list (POP_BACK CMAKE_MESSAGE_INDENT)
312383endif ()
313384
314385########################################################################################################################
@@ -544,7 +615,7 @@ endif ()
544615# check for Link Time Optimization #
545616########################################################################################################################
546617# enable Link Time Optimization (LTO)
547- option (PLSSVM_ENABLE_LTO "Enable Link Time Optimizations." ON )
618+ option (PLSSVM_ENABLE_LTO "Enable Link Time Optimizations." OFF )
548619if (PLSSVM_ENABLE_LTO)
549620 include (CheckIPOSupported)
550621 check_ipo_supported(RESULT PLSSVM_LTO_SUPPORTED LANGUAGES CXX)
@@ -590,15 +661,19 @@ else ()
590661 target_include_directories (${PLSSVM_BASE_LIBRARY_NAME} PUBLIC $<BUILD_INTERFACE:${cxxopts_SOURCE_DIR} /include > $<INSTALL_INTERFACE:include >)
591662endif ()
592663
593- # try finding fast_float
594- set (PLSSVM_fast_float_VERSION v6.1.3)
595- find_package (fast_float QUIET )
664+ # ~~~
665+ # try finding fast_float note: We have to wrap fast_float into a small wrapper library to ensure that fast-math is never enabled.
666+ # Otherwise, the fast_float usage of std::numeric_limits<>::infinity() results in UB...
667+ # ~~~
668+ set (PLSSVM_FAST_FLOAT_WRAPPER_LIBRARY_NAME plssvm-fast_float-wrapper)
669+ add_library (${PLSSVM_FAST_FLOAT_WRAPPER_LIBRARY_NAME} SHARED ${CMAKE_CURRENT_SOURCE_DIR} /src/plssvm/detail/fast_float_wrapper.cpp)
670+ set (PLSSVM_fast_float_VERSION v8.0.2)
671+ find_package (fast_float 8.0.0 QUIET )
596672if (fast_float_FOUND)
597673 message (STATUS "Found package fast_float." )
598- target_include_directories (${PLSSVM_BASE_LIBRARY_NAME } PUBLIC ${fast_float_INCLUDE_DIR} )
674+ target_include_directories (${PLSSVM_FAST_FLOAT_WRAPPER_LIBRARY_NAME } PUBLIC ${fast_float_INCLUDE_DIR} )
599675else ()
600676 message (STATUS "Couldn't find package fast_float. Building version ${PLSSVM_fast_float_VERSION} from source." )
601- target_compile_definitions (${PLSSVM_BASE_LIBRARY_NAME} PRIVATE PLSSVM_fast_float_VERSION="${PLSSVM_fast_float_VERSION} " )
602677 # set options for fast_float
603678 set (FASTFLOAT_TEST OFF CACHE INTERNAL "" FORCE)
604679 set (FASTFLOAT_SANITIZE OFF CACHE INTERNAL "" FORCE)
@@ -610,9 +685,26 @@ else ()
610685 QUIET
611686 )
612687 FetchContent_MakeAvailable(fast_float)
613- add_dependencies (${PLSSVM_BASE_LIBRARY_NAME} fast_float)
614- target_include_directories (${PLSSVM_BASE_LIBRARY_NAME} PUBLIC $<BUILD_INTERFACE:${fast_float_SOURCE_DIR} /include > $<INSTALL_INTERFACE:include >)
688+ add_dependencies (${PLSSVM_FAST_FLOAT_WRAPPER_LIBRARY_NAME} fast_float)
689+ target_include_directories (
690+ ${PLSSVM_FAST_FLOAT_WRAPPER_LIBRARY_NAME} PUBLIC $<BUILD_INTERFACE:${fast_float_SOURCE_DIR} /include > $<INSTALL_INTERFACE:include >
691+ )
615692endif ()
693+ # ensure that fast-math is ALWAYS of
694+ target_compile_options (
695+ ${PLSSVM_FAST_FLOAT_WRAPPER_LIBRARY_NAME} PRIVATE $<$<COMPILE_LANG_AND_ID:CXX,GNU,Clang,IntelLLVM>:-fno-fast-math>
696+ $<$<COMPILE_LANG_AND_ID:CXX,MSVC >:/fp:precise>
697+ )
698+ target_include_directories (
699+ ${PLSSVM_FAST_FLOAT_WRAPPER_LIBRARY_NAME} PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR} /include > $<INSTALL_INTERFACE:include >
700+ )
701+ target_compile_features (${PLSSVM_FAST_FLOAT_WRAPPER_LIBRARY_NAME} PUBLIC cxx_std_17)
702+ if (PLSSVM_ENABLE_STL_DEBUG_MODE)
703+ target_compile_definitions (${PLSSVM_FAST_FLOAT_WRAPPER_LIBRARY_NAME} PUBLIC ${PLSSVM_STL_DEBUG_MODE_FLAGS} )
704+ endif ()
705+ # link wrapper library against base library
706+ target_link_libraries (${PLSSVM_BASE_LIBRARY_NAME} PUBLIC ${PLSSVM_FAST_FLOAT_WRAPPER_LIBRARY_NAME} )
707+ list (APPEND PLSSVM_TARGETS_TO_INSTALL "${PLSSVM_FAST_FLOAT_WRAPPER_LIBRARY_NAME} " )
616708
617709# try finding igor
618710set (PLSSVM_igor_VERSION a5224c60d266974d3f407191583fe266cbe1c93d)
@@ -881,7 +973,7 @@ write_basic_package_version_file(
881973 COMPATIBILITY SameMajorVersion
882974)
883975
884- # generate configuration file
976+ # generate configuration files
885977configure_package_config_file(
886978 "${CMAKE_CURRENT_SOURCE_DIR} /cmake/plssvm/plssvmConfig.cmake.in" "${PROJECT_BINARY_DIR} /plssvmConfig.cmake"
887979 INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR} /plssvm/cmake
@@ -890,6 +982,15 @@ configure_package_config_file(
890982 "${CMAKE_CURRENT_SOURCE_DIR} /cmake/plssvm/plssvmHIPTargets.cmake.in" "${PROJECT_BINARY_DIR} /plssvmHIPTargets.cmake"
891983 INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR} /plssvm/cmake
892984)
985+ configure_package_config_file(
986+ "${CMAKE_CURRENT_SOURCE_DIR} /cmake/plssvm/plssvmAdaptiveCppTargets.cmake.in" "${PROJECT_BINARY_DIR} /plssvmAdaptiveCppTargets.cmake"
987+ INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR} /plssvm/cmake
988+ )
989+ string (REPLACE "\" " "\\\" " PLSSVM_ESCAPED_CXX_FLAGS "${CMAKE_CXX_FLAGS} " ) # necessary to correctly escape quotes
990+ configure_package_config_file(
991+ "${CMAKE_CURRENT_SOURCE_DIR} /cmake/plssvm/plssvmstdparTargets.cmake.in" "${PROJECT_BINARY_DIR} /plssvmstdparTargets.cmake"
992+ INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR} /plssvm/cmake
993+ )
893994
894995# create and copy install-targets file
895996install (
@@ -908,9 +1009,9 @@ install(
9081009 "${CMAKE_CURRENT_SOURCE_DIR} /cmake/plssvm/plssvmOpenCLTargets.cmake"
9091010 "${CMAKE_CURRENT_SOURCE_DIR} /cmake/plssvm/plssvmOpenMPTargets.cmake"
9101011 "${CMAKE_CURRENT_SOURCE_DIR} /cmake/plssvm/plssvmHPXTargets.cmake"
911- "${CMAKE_CURRENT_SOURCE_DIR} /cmake/plssvm /plssvmAdaptiveCppTargets.cmake"
1012+ "${PROJECT_BINARY_DIR} /plssvmAdaptiveCppTargets.cmake"
9121013 "${CMAKE_CURRENT_SOURCE_DIR} /cmake/plssvm/plssvmDPCPPTargets.cmake"
9131014 "${CMAKE_CURRENT_SOURCE_DIR} /cmake/plssvm/plssvmKokkosTargets.cmake"
914- "${CMAKE_CURRENT_SOURCE_DIR} /cmake/plssvm /plssvmstdparTargets.cmake"
1015+ "${PROJECT_BINARY_DIR} /plssvmstdparTargets.cmake"
9151016 DESTINATION ${CMAKE_INSTALL_DATAROOTDIR} /plssvm/cmake
9161017)
0 commit comments