You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

338 lines
12 KiB

#
# Part of the cppduals Project
#
# (c)2019 Michael Tesch. tesch1@gmail.com
#
# See https://gitlab.com/tesch1/cppduals/blob/master/LICENSE.txt for
# license information.
#
# This Source Code Form is subject to the terms of the Mozilla
# Public License v. 2.0. If a copy of the MPL was not distributed
# with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
cmake_minimum_required (VERSION 3.14)
if (WIN32)
add_definitions (-D_USE_MATH_DEFINES)
endif ()
include_directories ("${CMAKE_SOURCE_DIR}")
include_directories ("${DEPS_ROOT}/include")
#include_directories ("${MPFR_INCLUDES}")
#
# Correctness & Coverage
#
message ("OSX_ARCHITECTURES: ${CMAKE_SYSTEM_PROCESSOR}")
set (OSX_ARCHITECTURES "arm64;x86_64")
if (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)")
set (X86 TRUE)
else ()
set (X86 FALSE)
endif ()
# Set optimization flags only if coverage is not enabled
if (NOT CPPDUALS_CODE_COVERAGE)
if (X86)
if (NOT MSVC)
set (OPT_FLAGS "-O3;-march=native")
else ()
set (OPT_FLAGS "/arch:AVX2")
endif ()
else ()
set (OPT_FLAGS "-O3")
endif ()
else()
if (X86)
if (NOT MSVC)
set (OPT_FLAGS "-mavx2")
else ()
set (OPT_FLAGS "/arch:AVX2")
endif ()
else ()
set (OPT_FLAGS "")
endif ()
endif ()
set (OPT_FLAGS "${OPT_FLAGS};-DCPPDUALS_VECTORIZE_CDUAL")
set (ALL_TESTS
test_dual test_cdual test_funcs test_eigen test_packets
test_vectorize test_solve test_expm test_1 test_fmt
example
)
set (ALL_TEST_BINS )
foreach (TEST_ ${ALL_TESTS})
foreach (PHASE 1 2 3 4 5)
# check if file has phase defined
file (READ ${TEST_}.cpp TMPTXT)
string (FIND "${TMPTXT}" "PHASE_${PHASE}" hasphase)
if ((${hasphase} EQUAL -1) AND NOT (${PHASE} EQUAL 1))
continue ()
endif ()
set (TEST ${TEST_}_${PHASE})
message ("Adding test ${TEST}")
set (ALL_TEST_BINS ${ALL_TEST_BINS} ${TEST})
add_executable (${TEST} ${TEST_}.cpp)
set (PHASE_FLAGS ${OPT_FLAGS} -DPHASE_${PHASE})
string (REPLACE ";" ", " L2 "${OPT_FLAGS};${CMAKE_CXX_FLAGS}")
target_compile_options (${TEST} PUBLIC ${PHASE_FLAGS})
target_compile_definitions (${TEST} PRIVATE "OPT_FLAGS=${L2}")
# Link with coverage config first to ensure flags are used
target_link_libraries (${TEST}
cppduals_coverage_config # Link coverage first
gtest_main
eigen
expokit
)
gtest_discover_tests (${TEST} TEST_LIST ${TEST}_targets)
set_tests_properties (${${TEST}_targets} PROPERTIES TIMEOUT 10)
endforeach (PHASE)
endforeach (TEST_)
# special for fmt
target_link_libraries (test_fmt_1 fmt::fmt)
if (CPPDUALS_BENCHMARK)
#
# Benchmarks
#
if (Boost_FOUND AND NO)
add_definitions (-DHAVE_BOOST=1)
include_directories ("${Boost_INCLUDE_DIRS}")
include_directories ("${PIRANHA_INCLUDE_DIR}")
include_directories ("${AUDI_INCLUDE_DIR}")
endif (Boost_FOUND AND NO)
if (NOT APPLE AND NOT BLA_VENDOR)
if (NOT BLA_STATIC)
# default to static
set (BLA_STATIC OFF)
endif (NOT BLA_STATIC)
set (BLA_VENDOR OpenBLAS)
endif ()
find_package (BLAS REQUIRED)
#find_package (LAPACK REQUIRED)
add_definitions (-DHAVE_BLAS)
#add_definitions (-DEIGEN_USE_BLAS)
if (APPLE)
add_definitions (-DACCELERATE_NEW_LAPACK -DACCELERATE_LAPACK_ILP64)
endif ()
# find lapacke.h cblas.h
set (CBLAS_HINTS ${BLAS_DIR} ${LAPACK_DIR} /usr /usr/local /opt /opt/local)
set (CBLAS_PATHS
/usr
/usr/local
/opt
/opt/local
/usr/local/opt
/System/Library/Frameworks
${BLAS_LIBRARIES}
)
# Finds the include directories for lapacke.h
find_path (LAPACKE_INCLUDE_DIRS
REQUIRED
NAMES lapacke.h clapack.h
HINTS ${CBLAS_HINTS}
PATH_SUFFIXES
include inc include/x86_64 include/x64
openblas/include openblas
Frameworks/vecLib.framework/Headers
PATHS ${CBLAS_PATHS}
DOC "LAPACK(E) include header lapacke.h/clapack.h")
mark_as_advanced (LAPACKE_INCLUDE_DIRS)
if (LAPACKE_INCLUDE_DIRS)
include_directories (${LAPACKE_INCLUDE_DIRS})
else ()
add_definitions (-DEIGEN_LAPACKE)
endif (LAPACKE_INCLUDE_DIRS)
# Finds the include directories for cblas*.h
find_path (CBLAS_INCLUDE_DIRS
REQUIRED
NAMES cblas.h cblas_openblas.h cblas-openblas.h
HINTS ${CBLAS_HINTS}
PATH_SUFFIXES
include inc include/x86_64 include/x64
openblas/include openblas
Frameworks/vecLib.framework/Headers
PATHS ${CBLAS_PATHS}
DOC "BLAS include header cblas.h")
mark_as_advanced (CBLAS_INCLUDE_DIRS)
include_directories (${CBLAS_INCLUDE_DIRS})
foreach (cblas in cblas.h cblas_openblas.h cblas-openblas.h)
if (EXISTS "${CBLAS_INCLUDE_DIRS}/${cblas}")
add_definitions (-DCBLAS_HEADER="${cblas}")
break()
endif (EXISTS "${CBLAS_INCLUDE_DIRS}/${cblas}")
endforeach (cblas)
message ("Found BLAS : ${BLAS_LIBRARIES}")
message ("Found cBLAS : ${CBLAS_INCLUDE_DIRS}")
message ("Found lapacke : ${LAPACKE_INCLUDE_DIRS}")
set (BMK_FLAGS "")
if (NOT MSVC)
#set (BMK_FLAGS "-O3;-mavx")
#set (BMK_FLAGS "-O3;-march=native;-fopenmp")
if (X86)
set (BMK_FLAGS "-msse3;-fopenmp")
set (BMK_FLAGS "-msse3")
set (BMK_FLAGS "-march=native;-funroll-loops")
set (BMK_FLAGS "-msse3;-mavx2;-mfma")
else ()
set (BMK_FLAGS "-march=native")
endif ()
#set (BMK_FLAGS "-O3;${BMK_FLAGS}")
#set (BMK_FLAGS "${BMK_FLAGS};-save-temps;-fverbose-asm")
else ()
set (BMK_FLAGS "/arch:IA32")
set (BMK_FLAGS "/arch:SSE")
set (BMK_FLAGS "/arch:SSE2")
set (BMK_FLAGS "/arch:AVX2")
endif ()
#set (BMK_FLAGS "${BMK_FLAGS};-DEIGEN_DONT_VECTORIZE")
#set (BMK_FLAGS "${BMK_FLAGS};-DCPPDUALS_DONT_VECTORIZE")
#set (BMK_FLAGS "${BMK_FLAGS};-DCPPDUALS_DONT_VECTORIZE_CDUAL")
foreach (VECTORIZE YES NO)
foreach (BENCH bench_dual bench_eigen bench_exp bench_gemm bench_example bench_fmt)
if (NOT VECTORIZE)
set (BENCHE ${BENCH})
else ()
set (BENCHE ${BENCH}_novec)
endif ()
add_executable (${BENCHE} ${BENCH}.cpp)
target_compile_options (${BENCHE} PUBLIC ${BMK_FLAGS})
if (NOT VECTORIZE)
target_compile_options (${BENCHE} PUBLIC "-DEIGEN_DONT_VECTORIZE")
endif()
#set_target_properties (${BENCH} PROPERTIES LINK_FLAGS -fopenmp)
#target_link_options (${BENCH} PUBLIC ${BMK_FLAGS})
string (REPLACE ";" ", " L2 "${BMK_FLAGS} ${CMAKE_CXX_FLAGS}")
target_compile_definitions (${BENCHE} PRIVATE "BMK_FLAGS=${L2}")
target_link_libraries (${BENCHE} benchmark::benchmark ${BLAS_LIBRARIES} eigen expokit)
endforeach ()
endforeach ()
target_link_libraries (bench_fmt fmt::fmt)
target_link_libraries (bench_fmt_novec fmt::fmt)
endif (CPPDUALS_BENCHMARK)
add_executable (sandbox sandbox.cpp)
#target_compile_options (sandbox PUBLIC ${BMK_FLAGS})
target_compile_options (sandbox PUBLIC -DCPPDUALS_VECTORIZE_CDUAL)
if (MSVC)
if (X86)
target_compile_options (sandbox PUBLIC /arch:AVX2)
endif ()
else ()
if (X86)
target_compile_options (sandbox PUBLIC -O1 -msse3 -mavx2 -mfma)
else ()
target_compile_options (sandbox PUBLIC -O1 ) # -mfpu=neon
endif ()
endif ()
set_target_properties (sandbox PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
target_link_libraries (sandbox PUBLIC cppduals_coverage_config eigen expokit)
#
# Generate coverage reports
#
if (CPPDUALS_CODE_COVERAGE)
# Find required tools
get_filename_component(CMAKE_CXX_COMPILER_DIR "${CMAKE_CXX_COMPILER}" DIRECTORY)
set(GENHTML_PATH ${CMAKE_CXX_COMPILER_DIR}/genhtml)
if(NOT EXISTS ${GENHTML_PATH})
find_program(GENHTML_PATH genhtml REQUIRED)
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# Clang
# often in the same directory as clang - search there too
get_filename_component(CMAKE_CXX_COMPILER_DIR "${CMAKE_CXX_COMPILER}" DIRECTORY)
set(LLVM_COV_PATH ${CMAKE_CXX_COMPILER_DIR}/llvm-cov)
set(LLVM_PROFDATA_PATH ${CMAKE_CXX_COMPILER_DIR}/llvm-profdata)
if(NOT EXISTS ${LLVM_COV_PATH})
find_program(LLVM_COV_PATH llvm-cov REQUIRED)
endif()
if(NOT EXISTS ${LLVM_PROFDATA_PATH})
find_program(LLVM_PROFDATA_PATH llvm-profdata REQUIRED)
endif()
add_custom_target(cov
DEPENDS ${ALL_TEST_BINS}
COMMAND ${CMAKE_COMMAND} -E remove_directory coverage/profraw
COMMAND ${CMAKE_COMMAND} -E make_directory coverage/profraw
COMMAND ${CMAKE_COMMAND} --build . --target test "LLVM_PROFILE_FILE=coverage/profraw/%p.profraw"
COMMAND ${LLVM_PROFDATA_PATH} merge -sparse coverage/profraw/*.profraw -o coverage/coverage.profdata
COMMAND ${LLVM_COV_PATH} show
-instr-profile=coverage/coverage.profdata
-format=html -output-dir=coverage/html
-show-line-counts-or-regions
-show-instantiation-summary
${ALL_TEST_BINS}
COMMAND ${LLVM_COV_PATH} report
-instr-profile=coverage/coverage.profdata
${ALL_TEST_BINS}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
# GCC
set(LCOV_PATH ${CMAKE_CXX_COMPILER_DIR}/lcov)
if(NOT EXISTS ${LCOV_PATH})
find_program(LCOV_PATH lcov REQUIRED)
endif()
# Extract GCC version number and use matching gcov version
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -dumpversion
OUTPUT_VARIABLE GCC_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
set(GCOV_PATH ${CMAKE_CXX_COMPILER_DIR}/gcov-${GCC_VERSION})
if(NOT EXISTS ${GCOV_PATH})
find_program(GCOV_PATH gcov-${GCC_VERSION} REQUIRED)
endif()
add_custom_target(cov
DEPENDS ${ALL_TEST_BINS}
COMMAND ${CMAKE_COMMAND} -E make_directory coverage
COMMAND ${LCOV_PATH} --directory . --zerocounters
# Add initial capture before running tests
COMMAND ${LCOV_PATH} --directory . --capture --initial --gcov-tool ${GCOV_PATH} --output-file coverage/coverage.base --ignore-errors inconsistent
# Run tests and capture coverage data
COMMAND ctest --output-on-failure
COMMAND ${LCOV_PATH} --directory . --capture --gcov-tool ${GCOV_PATH} --output-file coverage/coverage.info --ignore-errors inconsistent
# Combine baseline and test coverage data
COMMAND ${LCOV_PATH} --add-tracefile coverage/coverage.base --add-tracefile coverage/coverage.info --gcov-tool ${GCOV_PATH} --output-file coverage/coverage.total
# Only look at the coverage of the tests and duals library
COMMAND ${LCOV_PATH} --extract coverage/coverage.total '*/tests/*' '*/duals/*' --gcov-tool ${GCOV_PATH} --output-file coverage/coverage.info
# Remove unwanted paths
#COMMAND ${LCOV_PATH} --remove coverage/coverage.total '/usr/*' --gcov-tool ${GCOV_PATH} --output-file coverage/coverage.info
#COMMAND ${LCOV_PATH} --remove coverage/coverage.info '*/thirdparty/*' --gcov-tool ${GCOV_PATH} --output-file coverage/coverage.info
#COMMAND ${LCOV_PATH} --remove coverage/coverage.info '*/googletest/*' --gcov-tool ${GCOV_PATH} --output-file coverage/coverage.info
# Add --ignore-errors empty to prevent failure on empty coverage data
COMMAND ${LCOV_PATH} --list coverage/coverage.info --ignore-errors empty --gcov-tool ${GCOV_PATH}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
else()
message(FATAL_ERROR "No coverage tool found for ${CMAKE_CXX_COMPILER_ID}")
endif()
add_custom_target(cov-html
DEPENDS cov
COMMAND ${CMAKE_COMMAND} -E remove_directory coverage/html
COMMAND ${GENHTML_PATH} --ignore-errors source coverage/coverage.info --legend --title "cppduals coverage"
--output-directory=coverage/html
COMMAND ${CMAKE_COMMAND} -E echo "Coverage report generated at coverage/html/index.html"
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
endif ()