From 13906abf05b6c6ffcd922126b0289889201fc3b0 Mon Sep 17 00:00:00 2001 From: supersega Date: Sun, 4 Feb 2024 00:11:10 +0200 Subject: [PATCH] fix perfect forwarding in coroutines --- CMakeLists.txt | 6 ++++++ nld/autocont/arc_length_continuation.hpp | 4 ++-- nld/autocont/arc_length_raw.hpp | 5 ++++- nld/autocont/arc_length_representation.hpp | 2 +- nld/systems/ode.hpp | 10 +++++++-- nld/systems/periodic.hpp | 4 ++-- run.sh | 24 ++++++++++++++++++++-- 7 files changed, 45 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b822a5c..69c86e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,12 @@ find_package(GSL REQUIRED) add_subdirectory(autodiff) add_subdirectory(nld) +if (ENABLE_ASAN) + message(STATUS "Enabling AddressSanitizer") + add_compile_options(-fsanitize=address) + add_link_options(-fsanitize=ad:dress) +endif () + if (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) add_subdirectory(examples) enable_testing() diff --git a/nld/autocont/arc_length_continuation.hpp b/nld/autocont/arc_length_continuation.hpp index 94b30e7..085a2eb 100644 --- a/nld/autocont/arc_length_continuation.hpp +++ b/nld/autocont/arc_length_continuation.hpp @@ -41,8 +41,8 @@ namespace nld { template auto arc_length(F &&function, nld::continuation_parameters parameters, V unknowns, T tangential, M map) { - return nld::internal::arc_length_raw(std::forward(function), parameters, - unknowns, tangential, map); + return nld::internal::arc_length_raw( + std::forward(function), parameters, unknowns, tangential, map); } /// @brief Solves continuation problem for nonlinear function using arc length diff --git a/nld/autocont/arc_length_raw.hpp b/nld/autocont/arc_length_raw.hpp index 9f7680d..09a4459 100644 --- a/nld/autocont/arc_length_raw.hpp +++ b/nld/autocont/arc_length_raw.hpp @@ -20,8 +20,11 @@ namespace nld::internal { /// @param tangential Initial guess vector which has structure (u, lambda) /// @param map Function to map solution f: (V, R) -> MappedType. /// @return Generator which yields solution on iteration. +/// @note This takes F as a value, because coroutines can't handle +/// references properly, for more details see: +/// https://toby-allsopp.github.io/2017/04/22/coroutines-reference-params.html template -auto arc_length_raw(F &&function, nld::continuation_parameters parameters, +auto arc_length_raw(F function, nld::continuation_parameters parameters, V unknowns, T tangential, M map) noexcept -> cppcoro::generator(), std::declval()))> { auto [newton_parameters, tail, min_step, max_step, dir] = parameters; diff --git a/nld/autocont/arc_length_representation.hpp b/nld/autocont/arc_length_representation.hpp index 0fa916d..b2c81c4 100644 --- a/nld/autocont/arc_length_representation.hpp +++ b/nld/autocont/arc_length_representation.hpp @@ -89,7 +89,7 @@ struct arc_length_representation final { auto value = v.head(dim - 1); - auto keller = [*this](auto &val) { return arc_length_equation(val); }; + auto keller = [this](auto &val) { return arc_length_equation(val); }; auto dkeller = autodiff::forward::gradient(keller, nld::wrt(at), nld::at(at), v(dim - 1)); diff --git a/nld/systems/ode.hpp b/nld/systems/ode.hpp index 7eaa679..acd48cb 100644 --- a/nld/systems/ode.hpp +++ b/nld/systems/ode.hpp @@ -53,7 +53,7 @@ struct non_autonomous final { using vector_t = decltype(concepts::non_autonomous::call_fn()); /// @brief Make non autonomous system. - explicit non_autonomous(Fn f) : function(f) {} + explicit non_autonomous(Fn &&f) : function(std::forward(f)) {} /// @brief Operator to wrap function for earthier usage. /// @param y State variables for ODE. @@ -92,6 +92,9 @@ struct non_autonomous final { Fn function; ///< Underlying function represented dynamic system. }; +template +non_autonomous(Fn &&) -> non_autonomous; + template struct is_non_autonomous : std::false_type {}; @@ -136,7 +139,7 @@ struct autonomous final { using vector_t = decltype(concepts::autonomous::call_fn()); /// @brief Make autonomous system. - explicit autonomous(Fn f) : function(f) {} + explicit autonomous(Fn &&f) : function(std::forward(f)) {} /// @brief Operator to wrap function for earthier usage. /// @param y State variables for ODE. @@ -176,6 +179,9 @@ struct autonomous final { Fn function; ///< Underlying function represented dynamic system. }; +template +autonomous(Fn &&) -> autonomous; + template struct is_autonomous : std::false_type {}; diff --git a/nld/systems/periodic.hpp b/nld/systems/periodic.hpp index 22dad82..d174529 100644 --- a/nld/systems/periodic.hpp +++ b/nld/systems/periodic.hpp @@ -171,8 +171,8 @@ auto integration_arguments( /// \f$\dot{q} = \theta(q, t, \lambda)\f$. /// @param parameters parameters of ODE integration template -auto periodic(Ds dynamic_system, P parameters) { - return internal::periodic(std::move(dynamic_system), +auto periodic(Ds &&dynamic_system, P parameters) { + return internal::periodic(std::forward(dynamic_system), std::move(parameters)); } diff --git a/run.sh b/run.sh index 83ab3ae..7f7755a 100644 --- a/run.sh +++ b/run.sh @@ -1,3 +1,23 @@ -/usr/local/bin/cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo -DCMAKE_TOOLCHAIN_FILE:STRING=/Volumes/Data/dev/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_C_COMPILER:FILEPATH=/Volumes/Data/clang/clang+llvm-12.0.0-x86_64-apple-darwin/bin/clang -DCMAKE_CXX_COMPILER:FILEPATH=/Volumes/Data/clang/clang+llvm-12.0.0-x86_64-apple-darwin/bin/clang++ -S/Volumes/Data/dev/nldcpp -B/Volumes/Data/dev/nldcpp/build -G "Unix Makefiles" +#!bin/zsh + +cmake=/usr/local/bin/cmake +clang=/Volumes/Data/clang/clang+llvm-12.0.0-x86_64-apple-darwin/bin/clang +clangpp=/Volumes/Data/clang/clang+llvm-12.0.0-x86_64-apple-darwin/bin/clang++ +vcpkg=/Volumes/Data/dev/vcpkg/scripts/buildsystems/vcpkg.cmake +build_dir=build +build_type=ReleaseWithDebInfo +enable_asan=FALSE + +$cmake \ + --no-warn-unused-cli \ + -DCMAKE_BUILD_TYPE:STRING=$build_type \ + -DCMAKE_TOOLCHAIN_FILE:STRING=$vcpkg \ + -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE \ + -DCMAKE_C_COMPILER:FILEPATH=$clang \ + -DCMAKE_CXX_COMPILER:FILEPATH=$clangpp \ + -DENABLE_ASAN:BOOL=$enable_asan \ + -B $build_dir \ + -G "Unix Makefiles" + +$cmake --build $build_dir --config $build_type --target all -/usr/local/bin/cmake --build /Volumes/Data/dev/nldcpp/build --config RelWithDebInfo --target all -j 10 --