Loading .gitlab-ci.yml +3 −3 Original line number Diff line number Diff line Loading @@ -43,7 +43,7 @@ cover: stage: cover script: - dnf install -y gcc-c++ make cmake git doxygen lcov graphviz - cmake -Bbuild-cov -H. -DCPPDUALS_TESTING=ON -DCODE_COVERAGE=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo - cmake -Bbuild-cov -H. -DCPPDUALS_TESTING=ON -DCPPDUALS_CODE_COVERAGE=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo - cmake --build build-cov --target cov - cmake --build build-cov --target cov-html coverage: "/Total:|\\w*\\d+\\.\\d+/" Loading @@ -58,10 +58,10 @@ pages: script: - dnf install -y gcc-c++ make cmake git doxygen lcov graphviz - cmake -Bbuild-cov -H. -DCODE_COVERAGE=ON -DCPPDUALS_TESTING=ON - cmake --build build-cov --target cppduals_docs - cmake --build build-cov --target cov-html - mv build-cov/docs public/ - cmake --build build-cov --target cppduals_docs - mv build-cov/coverage public/ - mv build-cov/docs public/ coverage: "/Total:|\\w*\\d+\\.\\d+/" artifacts: paths: Loading CMakeLists.txt +19 −19 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ # cmake_minimum_required (VERSION 3.14) project (cppduals VERSION 0.6.0 VERSION 0.6.1 LANGUAGES C CXX ) include (GNUInstallDirs) Loading Loading @@ -46,7 +46,6 @@ set_property (CACHE CMAKE_CXX_STANDARD PROPERTY STRINGS 20) option (CPPDUALS_TESTING "Enable testing" OFF) option (CPPDUALS_BENCHMARK "Enable benchmarking" OFF) option (CPPDUALS_EIGEN_LATEST "Eigen latest" OFF) option (CPPDUALS_USE_LIBCXX "When testing use flags for libc++" OFF) set (EIGEN3_INCLUDE_DIRS "" CACHE PATH "Path to Eigen includes" ) Loading Loading @@ -113,7 +112,6 @@ if (CPPDUALS_TESTING) "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" "-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}" "-DCPPDUALS_BENCHMARK=${CPPDUALS_BENCHMARK}" "-DCPPDUALS_EIGEN_LATEST=${CPPDUALS_EIGEN_LATEST}" "-DCPPDUALS_USE_LIBCXX=${CPPDUALS_USE_LIBCXX}" "${PROJECT_SOURCE_DIR}/thirdparty" RESULT_VARIABLE DEPS_CONFIG_RESULT Loading Loading @@ -148,8 +146,12 @@ endif () # Code Coverage Configuration # add_library (cppduals_coverage_config INTERFACE) option (CODE_COVERAGE "Enable coverage reporting" OFF) if (CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") option (CPPDUALS_CODE_COVERAGE "Enable coverage reporting" OFF) if (CPPDUALS_CODE_COVERAGE AND NOT CPPDUALS_TESTING) message(FATAL_ERROR "CPPDUALS_CODE_COVERAGE requires CPPDUALS_TESTING to be enabled") endif() if (CPPDUALS_CODE_COVERAGE) if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") message(STATUS "Enabling coverage reporting") # Add required flags (GCC & LLVM/Clang) target_compile_options (cppduals_coverage_config INTERFACE Loading @@ -159,14 +161,12 @@ if (CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") -fprofile-arcs -ftest-coverage ) if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") target_link_options (cppduals_coverage_config INTERFACE --coverage ) else() target_link_options (cppduals_coverage_config INTERFACE --coverage ) # error out if coverage is enabled but compiler is not supported message(FATAL_ERROR "Coverage reporting is disabled for unknown compilers.") endif () endif () Loading Makefile +15 −49 Original line number Diff line number Diff line SHELL=bash TARGET=cppduals CMAKE_OPTIONS=-DCPPDUALS_TESTING=ON -DCPPDUALS_BENCHMARK=ON -DCPPDUALS_EIGEN_LATEST=OFF CMAKE_OPTIONS=-DCPPDUALS_TESTING=ON -DCPPDUALS_BENCHMARK=ON CMAKE=cmake DEFAULT_TARGET=package GCC?=gcc-14 Loading @@ -13,24 +13,17 @@ export CMAKE_BUILD_PARALLEL_LEVEL all: [ `uname` != Darwin ] || $(MAKE) clang clangr cc ccr osx osxr ios iosr [ `uname` != Linux ] || $(MAKE) cc ccr [ ! -d ~/.android ] || $(MAKE) android [ ! -f ~/.emscripten ] || $(MAKE) em help: @echo "Make targets for :" $(TARGET) @echo " clang - build debug package using clang compiler" @echo " clangr - build release package using clang compiler" @echo " test - " @echo " test-clang - " @echo " cov - build test coverage report" @echo " osx - build debug package using XCode command-line" @echo " osxr - build release package using XCode command-line" @echo " cc - build debug package using cc/gcc compiler" @echo " ccr - build release package using cc/gcc compiler" @echo " and - build android using gradle in ./Android" @echo " em-sdl2 - build debug package using cc/gcc compiler" @echo " em ^ alias" @echo " em-sdl2r - build release package using cc/gcc compiler" @echo " emr ^ alias" @echo " " @echo " distclean - remove ALL build directories from the above targets" # @echo " tags - " Loading @@ -41,13 +34,15 @@ Build-clang/Makefile Build-clang/compile_commands.json: -G'Unix Makefiles' \ $(CMAKE_OPTIONS) \ -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCMAKE_EXPORT_COMPILE_COMMANDS=1 \ -DCPPDUALS_TESTING=ON \ -DCPPDUALS_CODE_COVERAGE=ON Build-clangr/Makefile: CC=$(CLANG) CXX=$(CLANGXX) $(CMAKE) . -BBuild-clangr \ -G'Unix Makefiles' \ $(CMAKE_OPTIONS) \ -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_BUILD_TYPE=RelWithDebInfo \ -DCMAKE_EXPORT_COMPILE_COMMANDS=1 Build-cc/Makefile: Loading @@ -56,7 +51,8 @@ Build-cc/Makefile: $(CMAKE_OPTIONS) \ -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_EXPORT_COMPILE_COMMANDS=1 \ -DCPPDUALS_TESTING=ON -DCODE_COVERAGE=ON -DCPPDUALS_TESTING=ON \ -DCPPDUALS_CODE_COVERAGE=ON Build-ccr/Makefile: CC=$(GCC) CXX=$(GXX) $(CMAKE) . -BBuild-ccr \ Loading Loading @@ -85,8 +81,12 @@ test: ccr clangr CTEST_OUTPUT_ON_FAILURE=y $(CMAKE) --build Build-clangr --target test cov: cc CMAKE_BUILD_PARALLEL_LEVEL=8 $(CMAKE) --build Build-cc --target test $(CMAKE) --build Build-cc --target cov-html CMAKE_BUILD_PARALLEL_LEVEL=8 $(CMAKE) --build Build-cc --target cov-html echo "coverage report is in Build-cc/coverage/index.html" cov-clang: clang CMAKE_BUILD_PARALLEL_LEVEL=8 $(CMAKE) --build Build-clang --target cov-html @echo "coverage report is in Build-clang/coverage/html/index.html" Build-osx/cppduals.xcodeproj: $(CMAKE) . -BBuild-osx -GXcode $(CMAKE_OPTIONS) Loading @@ -97,42 +97,8 @@ osx: Build-osx/cppduals.xcodeproj osxr: Build-osx/cppduals.xcodeproj $(CMAKE) --build Build-osx --config Release --target $(DEFAULT_TARGET) Frameworks.iOS/SDL2.framework/SDL2: echo "Running ./scripts/Build_SDL2_framework.sh ios" ./scripts/Build_SDL2_framework.sh ios and: cd Android && ./gradlew build Build-emsc/Makefile: source ${HOME}/local/emsdk/emsdk_env.sh ; \ emcmake $(CMAKE) . -BBuild-emsc -DBUILD_SDL2=OFF -DBUILD_FREETYPE=OFF \ $(CMAKE_OPTIONS) # -DCMAKE_TOOLCHAIN_FILE=$${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake Build-emscr/Makefile: source ${HOME}/local/emsdk/emsdk_env.sh ; \ emcmake $(CMAKE) . -BBuild-emscr -DBUILD_SDL2=OFF \ -DBUILD_FREETYPE=OFF $(CMAKE_OPTIONS) -DCMAKE_BUILD_TYPE=Release em-sdl2: Build-emsc/Makefile cd Build-emsc && $(MAKE) cppduals em-sdl2r: Build-emscr/Makefile cd Build-emscr && $(MAKE) cppduals em-glfw: Build-emscgl/Makefile cd Build-emscgl && $(MAKE) cppduals em: em-sdl2 emrun: em-sdl2 source ${HOME}/local/emsdk/emsdk_env.sh && cd Build-emsc/ && emrun --serve_after_close cppduals.html emr: em-sdl2r distclean: rm -rf Build-* Android/app/.cxx/ rm -rf Build-* tags: cd Build-ccr && $(MAKE) tags duals/dual +23 −25 Original line number Diff line number Diff line Loading @@ -578,7 +578,7 @@ public: : _real(x.rpart()), _dual(x.dpart()) {} /// Cast to a complex<dual<>> with real part equal to *this. operator std::complex<dual<T>>() { return std::complex<dual<T>>(*this); } operator std::complex<dual<T>>() { return std::complex<dual<T>>(*this, (T)0); } /// Explicit cast to an arithmetic type retains the rpart() template <class X, Loading Loading @@ -850,7 +850,7 @@ namespace detail { template<class T> dual<T> fmin_impl(const dual<T> & x, const dual<T> & y); template<class T> dual<T> frexp_impl(const dual<T> & x, int* exp); template<class T> dual<T> ldexp_impl(const dual<T> & x, int exp); template<class T> T trunc_impl(const dual<T> & x); template<class T> dual<T> trunc_impl(const dual<T> & x); template<class T> dual<T> floor_impl(const dual<T> & x); template<class T> dual<T> ceil_impl(const dual<T> & x); template<class T> dual<T> round_impl(const dual<T> & x); Loading Loading @@ -920,7 +920,7 @@ template<class T> dual<T> fmin(const dual<T> & x, const dual<T> & y) { return de template<class T> dual<T> frexp(const dual<T> & x, int* exp) { return detail::frexp_impl(x, exp); } template<class T> dual<T> ldexp(const dual<T> & x, int exp) { return detail::ldexp_impl(x, exp); } //template<class T> dual<T> trunc(const dual<T> & x) { return detail::trunc_impl(x); } template<class T> T trunc(const dual<T> & x) { return detail::trunc_impl(x); } template<class T> dual<T> trunc(const dual<T> & x) { return detail::trunc_impl(x); } template<class T> dual<T> floor(const dual<T> & x) { return detail::floor_impl(x); } template<class T> dual<T> ceil(const dual<T> & x) { return detail::ceil_impl(x); } template<class T> dual<T> round(const dual<T> & x) { return detail::round_impl(x); } Loading @@ -933,8 +933,8 @@ template<class T> bool isnan(const dual<T> & x) { return detail::isnan_impl(x); template<class T> bool signbit(const dual<T> & x) { return detail::signbit_impl(x); } template<class T> dual<T> copysign(const dual<T> & x, const dual<T> & y) { return detail::copysign_impl(x, y); } template<class T> dual<T> random(const dual<T> & low, const dual<T> & high) { return detail::random_impl(low, high); } template<class T> dual<T> random2(const dual<T> & low, const dual<T> & high) { return detail::random2_impl(low, high); } //template<class T> dual<T> random(const dual<T> & low, const dual<T> & high) { return detail::random_impl(low, high); } //template<class T> dual<T> random2(const dual<T> & low, const dual<T> & high) { return detail::random2_impl(low, high); } namespace utils { template <typename T> int sgn(T val) { Loading Loading @@ -1129,7 +1129,13 @@ template<class T> dual<T> log2_impl(const dual<T> & x) { } template<class T> duals::dual<T> logb_impl(const duals::dual<T> & x) { return duals::log2(x); using std::log; using std::pow; using std::abs; using std::floor; T v = floor(log(abs(x.rpart())) / log(std::numeric_limits<T>::radix)); return duals::dual<T>(v, x.rpart() - pow(2,v) ? (T)0 : std::numeric_limits<T>::infinity()); } // dual<T> ^ U implementation Loading Loading @@ -1440,46 +1446,38 @@ template<class T> dual<T> lgamma_impl(const dual<T> & x) { return dual<T>(v, x.dpart() * w); } } template<class T> dual<T> abs_impl(const dual<T> & x) { using std::abs; return dual<T>(abs(x.rpart()), x.dpart() * utils::sgn(x.rpart())); } template<class T> dual<T> fabs_impl(const dual<T> & x) { using std::fabs; return dual<T>(fabs(x.rpart()), x.dpart() * utils::sgn(x.rpart())); } template<class T> duals::dual<T> fmax_impl(const duals::dual<T> & x, const duals::dual<T> & y) { return x.rpart() > y.rpart() ? x : y; } template<class T> duals::dual<T> fmin_impl(const duals::dual<T> & x, const duals::dual<T> & y) { return x.rpart() <= y.rpart() ? x : y; } template<class T> T (frexp_impl)(const duals::dual<T> & arg, int* exp ) { return (frexp)(arg.rpart(), exp); } template<class T> duals::dual<T> (ldexp_impl)(const duals::dual<T> & arg, int exp ) { return arg * std::pow((T)2,exp); } template<class T> T trunc_impl(const duals::dual<T> & d) { using std::trunc; return (trunc)(d.rpart()); } template<class T> duals::dual<T> frexp_impl(const duals::dual<T> & arg, int* exp ) { using std::frexp; return frexp(arg.rpart(), exp); } template<class T> duals::dual<T> ldexp_impl(const duals::dual<T> & arg, int exp ) { return arg * std::pow((T)2,exp); } template<class T> duals::dual<T> trunc_impl(const duals::dual<T> & d) { using std::trunc; return trunc(d.rpart()); } template<class T> dual<T> floor_impl(const dual<T> & x) { using std::floor; return dual<T>(floor(x.rpart()), x.dpart() * utils::sgn(x.rpart()-floor(x.rpart()))); } template<class T> duals::dual<T> (ceil_impl)(const duals::dual<T> & d) { using std::ceil; return (ceil)(d.rpart()); } template<class T> T (round_impl)(const duals::dual<T> & d) { using std::round; return (round)(d.rpart()); } template<class T> int fpclassify_impl(const duals::dual<T> & d) { using std::fpclassify; return (fpclassify)(d.rpart()); } template<class T> bool isfinite_impl(const duals::dual<T> & d) { using std::isfinite; return (isfinite)(d.rpart()); } template<class T> bool isnormal_impl(const duals::dual<T> & d) { using std::isnormal; return (isnormal)(d.rpart()); } template<class T> bool isinf_impl(const duals::dual<T> & d) { using std::isinf; return (isinf)(d.rpart()); } template<class T> bool isnan_impl(const duals::dual<T> & d) { using std::isnan; return (isnan)(d.rpart()); } template<class T> bool signbit_impl(const duals::dual<T> & d) { using std::signbit; return (signbit)(d.rpart()); } template<class T> duals::dual<T> ceil_impl(const duals::dual<T> & d) { using std::ceil; return ceil(d.rpart()); } template<class T> duals::dual<T> round_impl(const duals::dual<T> & d) { using std::round; return round(d.rpart()); } template<class T> int fpclassify_impl(const duals::dual<T> & d) { using std::fpclassify; return fpclassify(d.rpart()); } template<class T> bool isfinite_impl(const duals::dual<T> & d) { using std::isfinite; return isfinite(d.rpart()); } template<class T> bool isnormal_impl(const duals::dual<T> & d) { using std::isnormal; return isnormal(d.rpart()); } template<class T> bool isinf_impl(const duals::dual<T> & d) { using std::isinf; return isinf(d.rpart()); } template<class T> bool isnan_impl(const duals::dual<T> & d) { using std::isnan; return isnan(d.rpart()); } template<class T> bool signbit_impl(const duals::dual<T> & d) { using std::signbit; return signbit(d.rpart()); } template<class T> duals::dual<T> copysign_impl(const duals::dual<T> & x, const duals::dual<T> & y) { using std::copysign; T r = copysign(x.rpart(), y.rpart()); Loading tests/CMakeLists.txt +103 −59 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ else () endif () # Set optimization flags only if coverage is not enabled if (NOT CODE_COVERAGE) if (NOT CPPDUALS_CODE_COVERAGE) if (X86) if (NOT MSVC) set (OPT_FLAGS "-O3;-march=native") Loading @@ -41,9 +41,17 @@ if (NOT CODE_COVERAGE) 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") Loading Loading @@ -86,14 +94,12 @@ foreach (TEST_ ${ALL_TESTS}) endforeach (TEST_) # special for fmt target_compile_features (test_fmt_1 PUBLIC cxx_std_14) 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}") Loading Loading @@ -165,37 +171,34 @@ if (CPPDUALS_BENCHMARK) break() endif (EXISTS "${CBLAS_INCLUDE_DIRS}/${cblas}") endforeach (cblas) if (APPLE) add_definitions(-DACCELERATE_NEW_LAPACK) endif () message ("Found BLAS : ${BLAS_LIBRARIES}") message ("Found cBLAS : ${CBLAS_INCLUDE_DIRS}") message ("Found lapacke : ${LAPACKE_INCLUDE_DIRS}") set (OPT_FLAGS "") set (BMK_FLAGS "") if (NOT MSVC) #set (OPT_FLAGS "-O3;-mavx") #set (OPT_FLAGS "-O3;-march=native;-fopenmp") #set (BMK_FLAGS "-O3;-mavx") #set (BMK_FLAGS "-O3;-march=native;-fopenmp") if (X86) set (OPT_FLAGS "-msse3;-fopenmp") set (OPT_FLAGS "-msse3") set (OPT_FLAGS "-march=native;-funroll-loops") set (OPT_FLAGS "-msse3;-mavx2;-mfma") set (BMK_FLAGS "-msse3;-fopenmp") set (BMK_FLAGS "-msse3") set (BMK_FLAGS "-march=native;-funroll-loops") set (BMK_FLAGS "-msse3;-mavx2;-mfma") else () set (OPT_FLAGS "-march=native") set (BMK_FLAGS "-march=native") endif () #set (OPT_FLAGS "-O3;${OPT_FLAGS}") #set (OPT_FLAGS "${OPT_FLAGS};-save-temps;-fverbose-asm") #set (BMK_FLAGS "-O3;${BMK_FLAGS}") #set (BMK_FLAGS "${BMK_FLAGS};-save-temps;-fverbose-asm") else () set (OPT_FLAGS "/arch:IA32") set (OPT_FLAGS "/arch:SSE") set (OPT_FLAGS "/arch:SSE2") set (OPT_FLAGS "/arch:AVX2") set (BMK_FLAGS "/arch:IA32") set (BMK_FLAGS "/arch:SSE") set (BMK_FLAGS "/arch:SSE2") set (BMK_FLAGS "/arch:AVX2") endif () #set (OPT_FLAGS "${OPT_FLAGS};-DEIGEN_DONT_VECTORIZE") #set (OPT_FLAGS "${OPT_FLAGS};-DCPPDUALS_DONT_VECTORIZE") #set (OPT_FLAGS "${OPT_FLAGS};-DCPPDUALS_DONT_VECTORIZE_CDUAL") #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) Loading @@ -205,14 +208,14 @@ if (CPPDUALS_BENCHMARK) set (BENCHE ${BENCH}_novec) endif () add_executable (${BENCHE} ${BENCH}.cpp) target_compile_options (${BENCHE} PUBLIC ${OPT_FLAGS}) 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 ${OPT_FLAGS}) string (REPLACE ";" ", " L2 "${OPT_FLAGS} ${CMAKE_CXX_FLAGS}") target_compile_definitions (${BENCHE} PRIVATE "OPT_FLAGS=${L2}") #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 () Loading @@ -223,7 +226,7 @@ if (CPPDUALS_BENCHMARK) endif (CPPDUALS_BENCHMARK) add_executable (sandbox sandbox.cpp) #target_compile_options (sandbox PUBLIC ${OPT_FLAGS}) #target_compile_options (sandbox PUBLIC ${BMK_FLAGS}) target_compile_options (sandbox PUBLIC -DCPPDUALS_VECTORIZE_CDUAL) if (MSVC) if (X86) Loading @@ -243,44 +246,84 @@ target_link_libraries (sandbox PUBLIC cppduals_coverage_config eigen expokit) # # Generate coverage reports # if (CODE_COVERAGE) if (CPPDUALS_CODE_COVERAGE) # Find required tools find_program(LLVM_COV_PATH llvm-cov) find_program(LLVM_PROFDATA_PATH llvm-profdata) find_program(LCOV_PATH lcov) find_program(GENHTML_PATH genhtml) 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") if(LLVM_COV_PATH AND LLVM_PROFDATA_PATH) # 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 make_directory coverage COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target test COMMAND ${LLVM_PROFDATA_PATH} merge -sparse default.profraw -o default.profdata COMMAND ${LLVM_COV_PATH} export -format=lcov -instr-profile=default.profdata ${ALL_TEST_BINS} > coverage/coverage.info COMMAND ${LCOV_PATH} --remove coverage/coverage.info '/usr/*' --output-file coverage/coverage.info COMMAND ${LCOV_PATH} --remove coverage/coverage.info '*/thirdparty/*' --output-file coverage/coverage.info COMMAND ${LCOV_PATH} --remove coverage/coverage.info '*/googletest/*' --output-file coverage/coverage.info COMMAND ${LCOV_PATH} --list coverage/coverage.info 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} ) else() message(WARNING "llvm-cov and/or llvm-profdata not found! Coverage disabled.") return() 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() else() # 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 ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target test COMMAND ${LCOV_PATH} --directory ${CMAKE_BINARY_DIR} --zerocounters COMMAND ${LCOV_PATH} --directory ${CMAKE_BINARY_DIR} --capture --output-file coverage/coverage.info COMMAND ${LCOV_PATH} --remove coverage/coverage.info '/usr/*' --output-file coverage/coverage.info COMMAND ${LCOV_PATH} --remove coverage/coverage.info '*/thirdparty/*' --output-file coverage/coverage.info COMMAND ${LCOV_PATH} --remove coverage/coverage.info '*/googletest/*' --output-file coverage/coverage.info COMMAND ${LCOV_PATH} --list coverage/coverage.info 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 Loading @@ -291,4 +334,5 @@ if (CODE_COVERAGE) COMMAND ${CMAKE_COMMAND} -E echo "Coverage report generated at coverage/html/index.html" WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) endif () Loading
.gitlab-ci.yml +3 −3 Original line number Diff line number Diff line Loading @@ -43,7 +43,7 @@ cover: stage: cover script: - dnf install -y gcc-c++ make cmake git doxygen lcov graphviz - cmake -Bbuild-cov -H. -DCPPDUALS_TESTING=ON -DCODE_COVERAGE=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo - cmake -Bbuild-cov -H. -DCPPDUALS_TESTING=ON -DCPPDUALS_CODE_COVERAGE=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo - cmake --build build-cov --target cov - cmake --build build-cov --target cov-html coverage: "/Total:|\\w*\\d+\\.\\d+/" Loading @@ -58,10 +58,10 @@ pages: script: - dnf install -y gcc-c++ make cmake git doxygen lcov graphviz - cmake -Bbuild-cov -H. -DCODE_COVERAGE=ON -DCPPDUALS_TESTING=ON - cmake --build build-cov --target cppduals_docs - cmake --build build-cov --target cov-html - mv build-cov/docs public/ - cmake --build build-cov --target cppduals_docs - mv build-cov/coverage public/ - mv build-cov/docs public/ coverage: "/Total:|\\w*\\d+\\.\\d+/" artifacts: paths: Loading
CMakeLists.txt +19 −19 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ # cmake_minimum_required (VERSION 3.14) project (cppduals VERSION 0.6.0 VERSION 0.6.1 LANGUAGES C CXX ) include (GNUInstallDirs) Loading Loading @@ -46,7 +46,6 @@ set_property (CACHE CMAKE_CXX_STANDARD PROPERTY STRINGS 20) option (CPPDUALS_TESTING "Enable testing" OFF) option (CPPDUALS_BENCHMARK "Enable benchmarking" OFF) option (CPPDUALS_EIGEN_LATEST "Eigen latest" OFF) option (CPPDUALS_USE_LIBCXX "When testing use flags for libc++" OFF) set (EIGEN3_INCLUDE_DIRS "" CACHE PATH "Path to Eigen includes" ) Loading Loading @@ -113,7 +112,6 @@ if (CPPDUALS_TESTING) "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" "-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}" "-DCPPDUALS_BENCHMARK=${CPPDUALS_BENCHMARK}" "-DCPPDUALS_EIGEN_LATEST=${CPPDUALS_EIGEN_LATEST}" "-DCPPDUALS_USE_LIBCXX=${CPPDUALS_USE_LIBCXX}" "${PROJECT_SOURCE_DIR}/thirdparty" RESULT_VARIABLE DEPS_CONFIG_RESULT Loading Loading @@ -148,8 +146,12 @@ endif () # Code Coverage Configuration # add_library (cppduals_coverage_config INTERFACE) option (CODE_COVERAGE "Enable coverage reporting" OFF) if (CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") option (CPPDUALS_CODE_COVERAGE "Enable coverage reporting" OFF) if (CPPDUALS_CODE_COVERAGE AND NOT CPPDUALS_TESTING) message(FATAL_ERROR "CPPDUALS_CODE_COVERAGE requires CPPDUALS_TESTING to be enabled") endif() if (CPPDUALS_CODE_COVERAGE) if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") message(STATUS "Enabling coverage reporting") # Add required flags (GCC & LLVM/Clang) target_compile_options (cppduals_coverage_config INTERFACE Loading @@ -159,14 +161,12 @@ if (CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") -fprofile-arcs -ftest-coverage ) if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") target_link_options (cppduals_coverage_config INTERFACE --coverage ) else() target_link_options (cppduals_coverage_config INTERFACE --coverage ) # error out if coverage is enabled but compiler is not supported message(FATAL_ERROR "Coverage reporting is disabled for unknown compilers.") endif () endif () Loading
Makefile +15 −49 Original line number Diff line number Diff line SHELL=bash TARGET=cppduals CMAKE_OPTIONS=-DCPPDUALS_TESTING=ON -DCPPDUALS_BENCHMARK=ON -DCPPDUALS_EIGEN_LATEST=OFF CMAKE_OPTIONS=-DCPPDUALS_TESTING=ON -DCPPDUALS_BENCHMARK=ON CMAKE=cmake DEFAULT_TARGET=package GCC?=gcc-14 Loading @@ -13,24 +13,17 @@ export CMAKE_BUILD_PARALLEL_LEVEL all: [ `uname` != Darwin ] || $(MAKE) clang clangr cc ccr osx osxr ios iosr [ `uname` != Linux ] || $(MAKE) cc ccr [ ! -d ~/.android ] || $(MAKE) android [ ! -f ~/.emscripten ] || $(MAKE) em help: @echo "Make targets for :" $(TARGET) @echo " clang - build debug package using clang compiler" @echo " clangr - build release package using clang compiler" @echo " test - " @echo " test-clang - " @echo " cov - build test coverage report" @echo " osx - build debug package using XCode command-line" @echo " osxr - build release package using XCode command-line" @echo " cc - build debug package using cc/gcc compiler" @echo " ccr - build release package using cc/gcc compiler" @echo " and - build android using gradle in ./Android" @echo " em-sdl2 - build debug package using cc/gcc compiler" @echo " em ^ alias" @echo " em-sdl2r - build release package using cc/gcc compiler" @echo " emr ^ alias" @echo " " @echo " distclean - remove ALL build directories from the above targets" # @echo " tags - " Loading @@ -41,13 +34,15 @@ Build-clang/Makefile Build-clang/compile_commands.json: -G'Unix Makefiles' \ $(CMAKE_OPTIONS) \ -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCMAKE_EXPORT_COMPILE_COMMANDS=1 \ -DCPPDUALS_TESTING=ON \ -DCPPDUALS_CODE_COVERAGE=ON Build-clangr/Makefile: CC=$(CLANG) CXX=$(CLANGXX) $(CMAKE) . -BBuild-clangr \ -G'Unix Makefiles' \ $(CMAKE_OPTIONS) \ -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_BUILD_TYPE=RelWithDebInfo \ -DCMAKE_EXPORT_COMPILE_COMMANDS=1 Build-cc/Makefile: Loading @@ -56,7 +51,8 @@ Build-cc/Makefile: $(CMAKE_OPTIONS) \ -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_EXPORT_COMPILE_COMMANDS=1 \ -DCPPDUALS_TESTING=ON -DCODE_COVERAGE=ON -DCPPDUALS_TESTING=ON \ -DCPPDUALS_CODE_COVERAGE=ON Build-ccr/Makefile: CC=$(GCC) CXX=$(GXX) $(CMAKE) . -BBuild-ccr \ Loading Loading @@ -85,8 +81,12 @@ test: ccr clangr CTEST_OUTPUT_ON_FAILURE=y $(CMAKE) --build Build-clangr --target test cov: cc CMAKE_BUILD_PARALLEL_LEVEL=8 $(CMAKE) --build Build-cc --target test $(CMAKE) --build Build-cc --target cov-html CMAKE_BUILD_PARALLEL_LEVEL=8 $(CMAKE) --build Build-cc --target cov-html echo "coverage report is in Build-cc/coverage/index.html" cov-clang: clang CMAKE_BUILD_PARALLEL_LEVEL=8 $(CMAKE) --build Build-clang --target cov-html @echo "coverage report is in Build-clang/coverage/html/index.html" Build-osx/cppduals.xcodeproj: $(CMAKE) . -BBuild-osx -GXcode $(CMAKE_OPTIONS) Loading @@ -97,42 +97,8 @@ osx: Build-osx/cppduals.xcodeproj osxr: Build-osx/cppduals.xcodeproj $(CMAKE) --build Build-osx --config Release --target $(DEFAULT_TARGET) Frameworks.iOS/SDL2.framework/SDL2: echo "Running ./scripts/Build_SDL2_framework.sh ios" ./scripts/Build_SDL2_framework.sh ios and: cd Android && ./gradlew build Build-emsc/Makefile: source ${HOME}/local/emsdk/emsdk_env.sh ; \ emcmake $(CMAKE) . -BBuild-emsc -DBUILD_SDL2=OFF -DBUILD_FREETYPE=OFF \ $(CMAKE_OPTIONS) # -DCMAKE_TOOLCHAIN_FILE=$${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake Build-emscr/Makefile: source ${HOME}/local/emsdk/emsdk_env.sh ; \ emcmake $(CMAKE) . -BBuild-emscr -DBUILD_SDL2=OFF \ -DBUILD_FREETYPE=OFF $(CMAKE_OPTIONS) -DCMAKE_BUILD_TYPE=Release em-sdl2: Build-emsc/Makefile cd Build-emsc && $(MAKE) cppduals em-sdl2r: Build-emscr/Makefile cd Build-emscr && $(MAKE) cppduals em-glfw: Build-emscgl/Makefile cd Build-emscgl && $(MAKE) cppduals em: em-sdl2 emrun: em-sdl2 source ${HOME}/local/emsdk/emsdk_env.sh && cd Build-emsc/ && emrun --serve_after_close cppduals.html emr: em-sdl2r distclean: rm -rf Build-* Android/app/.cxx/ rm -rf Build-* tags: cd Build-ccr && $(MAKE) tags
duals/dual +23 −25 Original line number Diff line number Diff line Loading @@ -578,7 +578,7 @@ public: : _real(x.rpart()), _dual(x.dpart()) {} /// Cast to a complex<dual<>> with real part equal to *this. operator std::complex<dual<T>>() { return std::complex<dual<T>>(*this); } operator std::complex<dual<T>>() { return std::complex<dual<T>>(*this, (T)0); } /// Explicit cast to an arithmetic type retains the rpart() template <class X, Loading Loading @@ -850,7 +850,7 @@ namespace detail { template<class T> dual<T> fmin_impl(const dual<T> & x, const dual<T> & y); template<class T> dual<T> frexp_impl(const dual<T> & x, int* exp); template<class T> dual<T> ldexp_impl(const dual<T> & x, int exp); template<class T> T trunc_impl(const dual<T> & x); template<class T> dual<T> trunc_impl(const dual<T> & x); template<class T> dual<T> floor_impl(const dual<T> & x); template<class T> dual<T> ceil_impl(const dual<T> & x); template<class T> dual<T> round_impl(const dual<T> & x); Loading Loading @@ -920,7 +920,7 @@ template<class T> dual<T> fmin(const dual<T> & x, const dual<T> & y) { return de template<class T> dual<T> frexp(const dual<T> & x, int* exp) { return detail::frexp_impl(x, exp); } template<class T> dual<T> ldexp(const dual<T> & x, int exp) { return detail::ldexp_impl(x, exp); } //template<class T> dual<T> trunc(const dual<T> & x) { return detail::trunc_impl(x); } template<class T> T trunc(const dual<T> & x) { return detail::trunc_impl(x); } template<class T> dual<T> trunc(const dual<T> & x) { return detail::trunc_impl(x); } template<class T> dual<T> floor(const dual<T> & x) { return detail::floor_impl(x); } template<class T> dual<T> ceil(const dual<T> & x) { return detail::ceil_impl(x); } template<class T> dual<T> round(const dual<T> & x) { return detail::round_impl(x); } Loading @@ -933,8 +933,8 @@ template<class T> bool isnan(const dual<T> & x) { return detail::isnan_impl(x); template<class T> bool signbit(const dual<T> & x) { return detail::signbit_impl(x); } template<class T> dual<T> copysign(const dual<T> & x, const dual<T> & y) { return detail::copysign_impl(x, y); } template<class T> dual<T> random(const dual<T> & low, const dual<T> & high) { return detail::random_impl(low, high); } template<class T> dual<T> random2(const dual<T> & low, const dual<T> & high) { return detail::random2_impl(low, high); } //template<class T> dual<T> random(const dual<T> & low, const dual<T> & high) { return detail::random_impl(low, high); } //template<class T> dual<T> random2(const dual<T> & low, const dual<T> & high) { return detail::random2_impl(low, high); } namespace utils { template <typename T> int sgn(T val) { Loading Loading @@ -1129,7 +1129,13 @@ template<class T> dual<T> log2_impl(const dual<T> & x) { } template<class T> duals::dual<T> logb_impl(const duals::dual<T> & x) { return duals::log2(x); using std::log; using std::pow; using std::abs; using std::floor; T v = floor(log(abs(x.rpart())) / log(std::numeric_limits<T>::radix)); return duals::dual<T>(v, x.rpart() - pow(2,v) ? (T)0 : std::numeric_limits<T>::infinity()); } // dual<T> ^ U implementation Loading Loading @@ -1440,46 +1446,38 @@ template<class T> dual<T> lgamma_impl(const dual<T> & x) { return dual<T>(v, x.dpart() * w); } } template<class T> dual<T> abs_impl(const dual<T> & x) { using std::abs; return dual<T>(abs(x.rpart()), x.dpart() * utils::sgn(x.rpart())); } template<class T> dual<T> fabs_impl(const dual<T> & x) { using std::fabs; return dual<T>(fabs(x.rpart()), x.dpart() * utils::sgn(x.rpart())); } template<class T> duals::dual<T> fmax_impl(const duals::dual<T> & x, const duals::dual<T> & y) { return x.rpart() > y.rpart() ? x : y; } template<class T> duals::dual<T> fmin_impl(const duals::dual<T> & x, const duals::dual<T> & y) { return x.rpart() <= y.rpart() ? x : y; } template<class T> T (frexp_impl)(const duals::dual<T> & arg, int* exp ) { return (frexp)(arg.rpart(), exp); } template<class T> duals::dual<T> (ldexp_impl)(const duals::dual<T> & arg, int exp ) { return arg * std::pow((T)2,exp); } template<class T> T trunc_impl(const duals::dual<T> & d) { using std::trunc; return (trunc)(d.rpart()); } template<class T> duals::dual<T> frexp_impl(const duals::dual<T> & arg, int* exp ) { using std::frexp; return frexp(arg.rpart(), exp); } template<class T> duals::dual<T> ldexp_impl(const duals::dual<T> & arg, int exp ) { return arg * std::pow((T)2,exp); } template<class T> duals::dual<T> trunc_impl(const duals::dual<T> & d) { using std::trunc; return trunc(d.rpart()); } template<class T> dual<T> floor_impl(const dual<T> & x) { using std::floor; return dual<T>(floor(x.rpart()), x.dpart() * utils::sgn(x.rpart()-floor(x.rpart()))); } template<class T> duals::dual<T> (ceil_impl)(const duals::dual<T> & d) { using std::ceil; return (ceil)(d.rpart()); } template<class T> T (round_impl)(const duals::dual<T> & d) { using std::round; return (round)(d.rpart()); } template<class T> int fpclassify_impl(const duals::dual<T> & d) { using std::fpclassify; return (fpclassify)(d.rpart()); } template<class T> bool isfinite_impl(const duals::dual<T> & d) { using std::isfinite; return (isfinite)(d.rpart()); } template<class T> bool isnormal_impl(const duals::dual<T> & d) { using std::isnormal; return (isnormal)(d.rpart()); } template<class T> bool isinf_impl(const duals::dual<T> & d) { using std::isinf; return (isinf)(d.rpart()); } template<class T> bool isnan_impl(const duals::dual<T> & d) { using std::isnan; return (isnan)(d.rpart()); } template<class T> bool signbit_impl(const duals::dual<T> & d) { using std::signbit; return (signbit)(d.rpart()); } template<class T> duals::dual<T> ceil_impl(const duals::dual<T> & d) { using std::ceil; return ceil(d.rpart()); } template<class T> duals::dual<T> round_impl(const duals::dual<T> & d) { using std::round; return round(d.rpart()); } template<class T> int fpclassify_impl(const duals::dual<T> & d) { using std::fpclassify; return fpclassify(d.rpart()); } template<class T> bool isfinite_impl(const duals::dual<T> & d) { using std::isfinite; return isfinite(d.rpart()); } template<class T> bool isnormal_impl(const duals::dual<T> & d) { using std::isnormal; return isnormal(d.rpart()); } template<class T> bool isinf_impl(const duals::dual<T> & d) { using std::isinf; return isinf(d.rpart()); } template<class T> bool isnan_impl(const duals::dual<T> & d) { using std::isnan; return isnan(d.rpart()); } template<class T> bool signbit_impl(const duals::dual<T> & d) { using std::signbit; return signbit(d.rpart()); } template<class T> duals::dual<T> copysign_impl(const duals::dual<T> & x, const duals::dual<T> & y) { using std::copysign; T r = copysign(x.rpart(), y.rpart()); Loading
tests/CMakeLists.txt +103 −59 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ else () endif () # Set optimization flags only if coverage is not enabled if (NOT CODE_COVERAGE) if (NOT CPPDUALS_CODE_COVERAGE) if (X86) if (NOT MSVC) set (OPT_FLAGS "-O3;-march=native") Loading @@ -41,9 +41,17 @@ if (NOT CODE_COVERAGE) 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") Loading Loading @@ -86,14 +94,12 @@ foreach (TEST_ ${ALL_TESTS}) endforeach (TEST_) # special for fmt target_compile_features (test_fmt_1 PUBLIC cxx_std_14) 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}") Loading Loading @@ -165,37 +171,34 @@ if (CPPDUALS_BENCHMARK) break() endif (EXISTS "${CBLAS_INCLUDE_DIRS}/${cblas}") endforeach (cblas) if (APPLE) add_definitions(-DACCELERATE_NEW_LAPACK) endif () message ("Found BLAS : ${BLAS_LIBRARIES}") message ("Found cBLAS : ${CBLAS_INCLUDE_DIRS}") message ("Found lapacke : ${LAPACKE_INCLUDE_DIRS}") set (OPT_FLAGS "") set (BMK_FLAGS "") if (NOT MSVC) #set (OPT_FLAGS "-O3;-mavx") #set (OPT_FLAGS "-O3;-march=native;-fopenmp") #set (BMK_FLAGS "-O3;-mavx") #set (BMK_FLAGS "-O3;-march=native;-fopenmp") if (X86) set (OPT_FLAGS "-msse3;-fopenmp") set (OPT_FLAGS "-msse3") set (OPT_FLAGS "-march=native;-funroll-loops") set (OPT_FLAGS "-msse3;-mavx2;-mfma") set (BMK_FLAGS "-msse3;-fopenmp") set (BMK_FLAGS "-msse3") set (BMK_FLAGS "-march=native;-funroll-loops") set (BMK_FLAGS "-msse3;-mavx2;-mfma") else () set (OPT_FLAGS "-march=native") set (BMK_FLAGS "-march=native") endif () #set (OPT_FLAGS "-O3;${OPT_FLAGS}") #set (OPT_FLAGS "${OPT_FLAGS};-save-temps;-fverbose-asm") #set (BMK_FLAGS "-O3;${BMK_FLAGS}") #set (BMK_FLAGS "${BMK_FLAGS};-save-temps;-fverbose-asm") else () set (OPT_FLAGS "/arch:IA32") set (OPT_FLAGS "/arch:SSE") set (OPT_FLAGS "/arch:SSE2") set (OPT_FLAGS "/arch:AVX2") set (BMK_FLAGS "/arch:IA32") set (BMK_FLAGS "/arch:SSE") set (BMK_FLAGS "/arch:SSE2") set (BMK_FLAGS "/arch:AVX2") endif () #set (OPT_FLAGS "${OPT_FLAGS};-DEIGEN_DONT_VECTORIZE") #set (OPT_FLAGS "${OPT_FLAGS};-DCPPDUALS_DONT_VECTORIZE") #set (OPT_FLAGS "${OPT_FLAGS};-DCPPDUALS_DONT_VECTORIZE_CDUAL") #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) Loading @@ -205,14 +208,14 @@ if (CPPDUALS_BENCHMARK) set (BENCHE ${BENCH}_novec) endif () add_executable (${BENCHE} ${BENCH}.cpp) target_compile_options (${BENCHE} PUBLIC ${OPT_FLAGS}) 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 ${OPT_FLAGS}) string (REPLACE ";" ", " L2 "${OPT_FLAGS} ${CMAKE_CXX_FLAGS}") target_compile_definitions (${BENCHE} PRIVATE "OPT_FLAGS=${L2}") #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 () Loading @@ -223,7 +226,7 @@ if (CPPDUALS_BENCHMARK) endif (CPPDUALS_BENCHMARK) add_executable (sandbox sandbox.cpp) #target_compile_options (sandbox PUBLIC ${OPT_FLAGS}) #target_compile_options (sandbox PUBLIC ${BMK_FLAGS}) target_compile_options (sandbox PUBLIC -DCPPDUALS_VECTORIZE_CDUAL) if (MSVC) if (X86) Loading @@ -243,44 +246,84 @@ target_link_libraries (sandbox PUBLIC cppduals_coverage_config eigen expokit) # # Generate coverage reports # if (CODE_COVERAGE) if (CPPDUALS_CODE_COVERAGE) # Find required tools find_program(LLVM_COV_PATH llvm-cov) find_program(LLVM_PROFDATA_PATH llvm-profdata) find_program(LCOV_PATH lcov) find_program(GENHTML_PATH genhtml) 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") if(LLVM_COV_PATH AND LLVM_PROFDATA_PATH) # 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 make_directory coverage COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target test COMMAND ${LLVM_PROFDATA_PATH} merge -sparse default.profraw -o default.profdata COMMAND ${LLVM_COV_PATH} export -format=lcov -instr-profile=default.profdata ${ALL_TEST_BINS} > coverage/coverage.info COMMAND ${LCOV_PATH} --remove coverage/coverage.info '/usr/*' --output-file coverage/coverage.info COMMAND ${LCOV_PATH} --remove coverage/coverage.info '*/thirdparty/*' --output-file coverage/coverage.info COMMAND ${LCOV_PATH} --remove coverage/coverage.info '*/googletest/*' --output-file coverage/coverage.info COMMAND ${LCOV_PATH} --list coverage/coverage.info 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} ) else() message(WARNING "llvm-cov and/or llvm-profdata not found! Coverage disabled.") return() 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() else() # 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 ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target test COMMAND ${LCOV_PATH} --directory ${CMAKE_BINARY_DIR} --zerocounters COMMAND ${LCOV_PATH} --directory ${CMAKE_BINARY_DIR} --capture --output-file coverage/coverage.info COMMAND ${LCOV_PATH} --remove coverage/coverage.info '/usr/*' --output-file coverage/coverage.info COMMAND ${LCOV_PATH} --remove coverage/coverage.info '*/thirdparty/*' --output-file coverage/coverage.info COMMAND ${LCOV_PATH} --remove coverage/coverage.info '*/googletest/*' --output-file coverage/coverage.info COMMAND ${LCOV_PATH} --list coverage/coverage.info 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 Loading @@ -291,4 +334,5 @@ if (CODE_COVERAGE) COMMAND ${CMAKE_COMMAND} -E echo "Coverage report generated at coverage/html/index.html" WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) endif ()