diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c3986b7e..a6182b4af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -281,7 +281,6 @@ set(HEYOKA_SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/math/acosh.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/math/atanh.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/math/erf.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/src/math/tpoly.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/math/sum.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/math/prod.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/math/constants.cpp" diff --git a/include/heyoka/detail/llvm_helpers.hpp b/include/heyoka/detail/llvm_helpers.hpp index fef1bd6fd..025eaa064 100644 --- a/include/heyoka/detail/llvm_helpers.hpp +++ b/include/heyoka/detail/llvm_helpers.hpp @@ -111,8 +111,6 @@ HEYOKA_DLL_PUBLIC void llvm_switch_u32(llvm_state &, llvm::Value *, const std::f HEYOKA_DLL_PUBLIC std::string llvm_type_name(llvm::Type *); -HEYOKA_DLL_PUBLIC bool compare_function_signature(llvm::Function *, llvm::Type *, const std::vector &); - void llvm_append_block(llvm::Function *, llvm::BasicBlock *); // Math helpers. diff --git a/include/heyoka/detail/taylor_common.hpp b/include/heyoka/detail/taylor_common.hpp index 0adce1839..f84a879f3 100644 --- a/include/heyoka/detail/taylor_common.hpp +++ b/include/heyoka/detail/taylor_common.hpp @@ -132,17 +132,6 @@ inline llvm::Function *taylor_c_diff_func_numpar(llvm_state &s, llvm::Type *fp_t // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // LCOV_EXCL_START - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument(fmt::format( - "Inconsistent function signature for the Taylor derivative of {}() in compact mode detected", name)); - } - // LCOV_EXCL_STOP } return f; diff --git a/include/heyoka/llvm_state.hpp b/include/heyoka/llvm_state.hpp index ba6ed869f..51f00dfa9 100644 --- a/include/heyoka/llvm_state.hpp +++ b/include/heyoka/llvm_state.hpp @@ -215,6 +215,7 @@ class HEYOKA_DLL_PUBLIC llvm_state HEYOKA_DLL_LOCAL void ctor_setup_math_flags(); // Low-level implementation details for compilation. + HEYOKA_DLL_LOCAL void optimise(); HEYOKA_DLL_LOCAL void compile_impl(); HEYOKA_DLL_LOCAL void add_obj_trigger(); @@ -262,8 +263,6 @@ class HEYOKA_DLL_PUBLIC llvm_state void verify_function(const std::string &); void verify_function(llvm::Function *); - void optimise(); - [[nodiscard]] bool is_compiled() const; void compile(); diff --git a/include/heyoka/math.hpp b/include/heyoka/math.hpp index e7440cf28..4960866bc 100644 --- a/include/heyoka/math.hpp +++ b/include/heyoka/math.hpp @@ -33,6 +33,5 @@ #include #include #include -#include #endif diff --git a/include/heyoka/math/tpoly.hpp b/include/heyoka/math/tpoly.hpp deleted file mode 100644 index 9fd0e7b21..000000000 --- a/include/heyoka/math/tpoly.hpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2020, 2021, 2022, 2023 Francesco Biscani (bluescarni@gmail.com), Dario Izzo (dario.izzo@gmail.com) -// -// This file is part of the heyoka library. -// -// 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/. - -#ifndef HEYOKA_MATH_TPOLY_HPP -#define HEYOKA_MATH_TPOLY_HPP - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -HEYOKA_BEGIN_NAMESPACE - -namespace detail -{ - -class HEYOKA_DLL_PUBLIC tpoly_impl : public func_base -{ - friend class boost::serialization::access; - template - void serialize(Archive &ar, unsigned) - { - ar &boost::serialization::base_object(*this); - ar &m_b_idx; - ar &m_e_idx; - } - -public: - // NOTE: we will cache the begin/end indices - // for convenience. - std::uint32_t m_b_idx, m_e_idx; - - tpoly_impl(); - explicit tpoly_impl(expression, expression); - - void to_stream(std::ostringstream &) const; - - llvm::Value *taylor_diff(llvm_state &, llvm::Type *, const std::vector &, - const std::vector &, llvm::Value *, llvm::Value *, std::uint32_t, - std::uint32_t, std::uint32_t, std::uint32_t, bool) const; - - llvm::Function *taylor_c_diff_func(llvm_state &, llvm::Type *, std::uint32_t, std::uint32_t, bool) const; - - [[nodiscard]] bool is_time_dependent() const; -}; - -} // namespace detail - -HEYOKA_DLL_PUBLIC expression tpoly(expression, expression); - -HEYOKA_END_NAMESPACE - -HEYOKA_S11N_FUNC_EXPORT_KEY(heyoka::detail::tpoly_impl) - -#endif diff --git a/src/detail/div.cpp b/src/detail/div.cpp index ac28078fa..375b34d9d 100644 --- a/src/detail/div.cpp +++ b/src/detail/div.cpp @@ -278,17 +278,6 @@ llvm::Function *taylor_c_diff_func_div_impl(llvm_state &s, llvm::Type *fp_t, con // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // LCOV_EXCL_START - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of division in compact mode detected"); - } - // LCOV_EXCL_STOP } return f; @@ -383,17 +372,6 @@ llvm::Function *taylor_c_diff_func_div_impl(llvm_state &s, llvm::Type *fp_t, con // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // LCOV_EXCL_START - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of division in compact mode detected"); - } - // LCOV_EXCL_STOP } return f; @@ -463,17 +441,6 @@ llvm::Function *taylor_c_diff_func_div_impl(llvm_state &s, llvm::Type *fp_t, con // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // LCOV_EXCL_START - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of division in compact mode detected"); - } - // LCOV_EXCL_STOP } return f; diff --git a/src/detail/llvm_helpers.cpp b/src/detail/llvm_helpers.cpp index 0c017ebf9..9e47b78c0 100644 --- a/src/detail/llvm_helpers.cpp +++ b/src/detail/llvm_helpers.cpp @@ -1460,38 +1460,6 @@ std::string llvm_type_name(llvm::Type *t) return std::move(ostr.str()); } -// This function will return true if: -// -// - the return type of f is ret, and -// - the argument types of f are the same as in 'args'. -// -// Otherwise, the function will return false. -bool compare_function_signature(llvm::Function *f, llvm::Type *ret, const std::vector &args) -{ - assert(f != nullptr); - assert(ret != nullptr); - - if (ret != f->getReturnType()) { - // Mismatched return types. - return false; - } - - auto *it = f->arg_begin(); - for (auto *arg_type : args) { - if (it == f->arg_end() || it->getType() != arg_type) { - // f has fewer arguments than args, or the current - // arguments' types do not match. - return false; - } - ++it; - } - - // In order for the signatures to match, - // we must be at the end of f's arguments list - // (otherwise f has more arguments than args). - return it == f->arg_end(); -} - // Create an LLVM if statement in the form: // if (cond) { // then_f(); @@ -2418,14 +2386,6 @@ llvm::Function *llvm_add_csc(llvm_state &s, llvm::Type *scal_t, std::uint32_t n, // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // LCOV_EXCL_START - // The function was created before. Check if the signatures match. - if (!compare_function_signature(f, builder.getVoidTy(), fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the sign changes counter function detected"); - } - // LCOV_EXCL_STOP } return f; @@ -3098,11 +3058,6 @@ llvm::Function *llvm_add_inv_kep_E(llvm_state &s, llvm::Type *fp_t, std::uint32_ // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - if (!compare_function_signature(f, tp, fargs)) { - throw std::invalid_argument("Inconsistent function signature for the inverse Kepler equation detected"); - } } return f; diff --git a/src/detail/sub.cpp b/src/detail/sub.cpp index d7442e729..483d24fa4 100644 --- a/src/detail/sub.cpp +++ b/src/detail/sub.cpp @@ -277,17 +277,6 @@ llvm::Function *taylor_c_diff_func_sub_impl(llvm_state &s, llvm::Type *fp_t, con // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // LCOV_EXCL_START - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of subtraction in compact mode detected"); - } - // LCOV_EXCL_STOP } return f; @@ -361,17 +350,6 @@ llvm::Function *taylor_c_diff_func_sub_impl(llvm_state &s, llvm::Type *fp_t, con // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // LCOV_EXCL_START - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of subtraction in compact mode detected"); - } - // LCOV_EXCL_STOP } return f; @@ -429,17 +407,6 @@ llvm::Function *taylor_c_diff_func_sub_impl(llvm_state &s, llvm::Type *fp_t, con // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // LCOV_EXCL_START - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of subtraction in compact mode detected"); - } - // LCOV_EXCL_STOP } return f; diff --git a/src/detail/sum_sq.cpp b/src/detail/sum_sq.cpp index 14ef92ba7..635ed5dac 100644 --- a/src/detail/sum_sq.cpp +++ b/src/detail/sum_sq.cpp @@ -512,17 +512,6 @@ llvm::Function *sum_sq_taylor_c_diff_func_impl(llvm_state &s, llvm::Type *fp_t, // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - // LCOV_EXCL_START - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of sum_sq() in compact mode detected"); - // LCOV_EXCL_STOP - } } return f; diff --git a/src/func.cpp b/src/func.cpp index 5b6643fa5..985339bef 100644 --- a/src/func.cpp +++ b/src/func.cpp @@ -992,17 +992,6 @@ llvm::Function *llvm_c_eval_func_helper(const std::string &name, // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // LCOV_EXCL_START - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument(fmt::format( - "Inconsistent function signature for the evaluation of {}() in compact mode detected", name)); - } - // LCOV_EXCL_STOP } return f; diff --git a/src/math/acos.cpp b/src/math/acos.cpp index 5b7e494d6..7c16b29c4 100644 --- a/src/math/acos.cpp +++ b/src/math/acos.cpp @@ -392,16 +392,6 @@ llvm::Function *taylor_c_diff_func_acos_impl(llvm_state &s, llvm::Type *fp_t, co // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of the inverse cosine " - "in compact mode detected"); - } } return f; diff --git a/src/math/acosh.cpp b/src/math/acosh.cpp index e01af37c8..bfec9ae46 100644 --- a/src/math/acosh.cpp +++ b/src/math/acosh.cpp @@ -383,16 +383,6 @@ llvm::Function *taylor_c_diff_func_acosh_impl(llvm_state &s, llvm::Type *fp_t, c // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of the inverse hyperbolic cosine " - "in compact mode detected"); - } } return f; diff --git a/src/math/asin.cpp b/src/math/asin.cpp index a29f6edce..4df1d62da 100644 --- a/src/math/asin.cpp +++ b/src/math/asin.cpp @@ -390,15 +390,6 @@ llvm::Function *taylor_c_diff_func_asin_impl(llvm_state &s, llvm::Type *fp_t, co // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument("Inconsistent function signature for the Taylor derivative of the inverse sine " - "in compact mode detected"); - } } return f; diff --git a/src/math/asinh.cpp b/src/math/asinh.cpp index 55fca2e22..940f4c5cc 100644 --- a/src/math/asinh.cpp +++ b/src/math/asinh.cpp @@ -383,16 +383,6 @@ llvm::Function *taylor_c_diff_func_asinh_impl(llvm_state &s, llvm::Type *fp_t, c // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of the inverse hyperbolic sine " - "in compact mode detected"); - } } return f; diff --git a/src/math/atan.cpp b/src/math/atan.cpp index 4660d900c..dbf5f0bb8 100644 --- a/src/math/atan.cpp +++ b/src/math/atan.cpp @@ -391,16 +391,6 @@ llvm::Function *taylor_c_diff_func_atan_impl(llvm_state &s, llvm::Type *fp_t, co // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of the inverse tangent " - "in compact mode detected"); - } } return f; diff --git a/src/math/atan2.cpp b/src/math/atan2.cpp index 48145c350..b9407d606 100644 --- a/src/math/atan2.cpp +++ b/src/math/atan2.cpp @@ -525,18 +525,7 @@ llvm::Function *taylor_c_diff_func_atan2_impl(llvm_state &s, llvm::Type *fp_t, c // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - // LCOV_EXCL_START - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signatures for the Taylor derivative of atan2() in compact mode detected"); - } } - // LCOV_EXCL_STOP return f; } @@ -643,18 +632,7 @@ llvm::Function *taylor_c_diff_func_atan2_impl(llvm_state &s, llvm::Type *fp_t, c // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - // LCOV_EXCL_START - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signatures for the Taylor derivative of atan2() in compact mode detected"); - } } - // LCOV_EXCL_STOP return f; } @@ -771,18 +749,7 @@ llvm::Function *taylor_c_diff_func_atan2_impl(llvm_state &s, llvm::Type *fp_t, c // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - // LCOV_EXCL_START - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signatures for the Taylor derivative of atan2() in compact mode detected"); - } } - // LCOV_EXCL_STOP return f; } diff --git a/src/math/atanh.cpp b/src/math/atanh.cpp index 9f919345c..3b3726c15 100644 --- a/src/math/atanh.cpp +++ b/src/math/atanh.cpp @@ -389,16 +389,6 @@ llvm::Function *taylor_c_diff_func_atanh_impl(llvm_state &s, llvm::Type *fp_t, c // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of the inverse hyperbolic tangent " - "in compact mode detected"); - } } return f; diff --git a/src/math/constants.cpp b/src/math/constants.cpp index 406775b6c..ade36da3d 100644 --- a/src/math/constants.cpp +++ b/src/math/constants.cpp @@ -328,17 +328,6 @@ llvm::Function *constant::taylor_c_diff_func(llvm_state &s, llvm::Type *fp_t, st // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // LCOV_EXCL_START - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!detail::compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of a constant in compact mode detected"); - } - // LCOV_EXCL_STOP } return f; diff --git a/src/math/cos.cpp b/src/math/cos.cpp index f54be2389..12c4313ea 100644 --- a/src/math/cos.cpp +++ b/src/math/cos.cpp @@ -365,15 +365,6 @@ llvm::Function *taylor_c_diff_func_cos_impl(llvm_state &s, llvm::Type *fp_t, con // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of the cosine in compact mode detected"); - } } return f; diff --git a/src/math/cosh.cpp b/src/math/cosh.cpp index 45a2dc708..7d02aef49 100644 --- a/src/math/cosh.cpp +++ b/src/math/cosh.cpp @@ -317,15 +317,6 @@ llvm::Function *taylor_c_diff_func_cosh_impl(llvm_state &s, llvm::Type *fp_t, co // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument("Inconsistent function signature for the Taylor derivative of the hyperbolic " - "cosine in compact mode detected"); - } } return f; diff --git a/src/math/erf.cpp b/src/math/erf.cpp index 1d50a66dc..c5f04b4af 100644 --- a/src/math/erf.cpp +++ b/src/math/erf.cpp @@ -389,16 +389,6 @@ llvm::Function *taylor_c_diff_func_erf_impl(llvm_state &s, llvm::Type *fp_t, con // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of the error function " - "in compact mode detected"); - } } return f; diff --git a/src/math/exp.cpp b/src/math/exp.cpp index 76a155baa..fbf73cd99 100644 --- a/src/math/exp.cpp +++ b/src/math/exp.cpp @@ -343,15 +343,6 @@ llvm::Function *taylor_c_diff_func_exp_impl(llvm_state &s, llvm::Type *fp_t, con // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument("Inconsistent function signature for the Taylor derivative of the exponential " - "in compact mode detected"); - } } return f; diff --git a/src/math/kepE.cpp b/src/math/kepE.cpp index 5deb6732a..02bcd2cc7 100644 --- a/src/math/kepE.cpp +++ b/src/math/kepE.cpp @@ -576,15 +576,6 @@ llvm::Function *taylor_c_diff_func_kepE_impl(llvm_state &s, llvm::Type *fp_t, co // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signatures for the Taylor derivative of kepE() in compact mode detected"); - } } return f; @@ -694,15 +685,6 @@ llvm::Function *taylor_c_diff_func_kepE_impl(llvm_state &s, llvm::Type *fp_t, co // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signatures for the Taylor derivative of kepE() in compact mode detected"); - } } return f; @@ -819,15 +801,6 @@ llvm::Function *taylor_c_diff_func_kepE_impl(llvm_state &s, llvm::Type *fp_t, co // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signatures for the Taylor derivative of kepE() in compact mode detected"); - } } return f; diff --git a/src/math/log.cpp b/src/math/log.cpp index d33cff78b..73f19eeb7 100644 --- a/src/math/log.cpp +++ b/src/math/log.cpp @@ -363,15 +363,6 @@ llvm::Function *taylor_c_diff_func_log_impl(llvm_state &s, llvm::Type *fp_t, con // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of the logarithm in compact mode detected"); - } } return f; diff --git a/src/math/pow.cpp b/src/math/pow.cpp index 0a117d6b3..f8b6706ba 100644 --- a/src/math/pow.cpp +++ b/src/math/pow.cpp @@ -801,18 +801,7 @@ llvm::Function *taylor_c_diff_func_square_impl(llvm_state &s, llvm::Type *fp_t, // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - // LCOV_EXCL_START - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument("Inconsistent function signature for the Taylor derivative of square() " - "in compact mode detected"); - } } - // LCOV_EXCL_STOP return f; } @@ -928,18 +917,7 @@ llvm::Function *taylor_c_diff_func_sqrt_impl(llvm_state &s, llvm::Type *fp_t, co // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - // LCOV_EXCL_START - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument("Inconsistent function signature for the Taylor derivative of the square root " - "in compact mode detected"); - } } - // LCOV_EXCL_STOP return f; } @@ -1060,18 +1038,7 @@ llvm::Function *taylor_c_diff_func_pow_impl(llvm_state &s, llvm::Type *fp_t, con // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - // LCOV_EXCL_START - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signatures for the Taylor derivative of pow() in compact mode detected"); - } } - // LCOV_EXCL_STOP return f; } diff --git a/src/math/prod.cpp b/src/math/prod.cpp index 2f9dc636c..8fce8033b 100644 --- a/src/math/prod.cpp +++ b/src/math/prod.cpp @@ -557,17 +557,6 @@ llvm::Function *prod_taylor_c_diff_func_impl(llvm_state &s, llvm::Type *fp_t, co // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // LCOV_EXCL_START - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of prod() in compact mode detected"); - } - // LCOV_EXCL_STOP } return f; @@ -623,18 +612,6 @@ llvm::Function *taylor_c_diff_func_neg_impl(llvm_state &s, llvm::Type *fp_t, con // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - - } else { - // LCOV_EXCL_START - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument("Inconsistent function signature for the Taylor derivative of the negation " - "in compact mode detected"); - } - // LCOV_EXCL_STOP } return f; @@ -700,17 +677,6 @@ llvm::Function *prod_taylor_c_diff_func_impl(llvm_state &s, llvm::Type *fp_t, co // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // LCOV_EXCL_START - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of prod() in compact mode detected"); - } - // LCOV_EXCL_STOP } return f; @@ -775,17 +741,6 @@ llvm::Function *prod_taylor_c_diff_func_impl(llvm_state &s, llvm::Type *fp_t, co // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // LCOV_EXCL_START - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of prod() in compact mode detected"); - } - // LCOV_EXCL_STOP } return f; diff --git a/src/math/sigmoid.cpp b/src/math/sigmoid.cpp index ee726cc08..2809ff36b 100644 --- a/src/math/sigmoid.cpp +++ b/src/math/sigmoid.cpp @@ -412,15 +412,6 @@ llvm::Function *taylor_c_diff_func_sigmoid_impl(llvm_state &s, llvm::Type *fp_t, // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of the sigmpid in compact mode detected"); - } } return f; diff --git a/src/math/sin.cpp b/src/math/sin.cpp index 80993f50a..42b54c2cb 100644 --- a/src/math/sin.cpp +++ b/src/math/sin.cpp @@ -365,15 +365,6 @@ llvm::Function *taylor_c_diff_func_sin_impl(llvm_state &s, llvm::Type *fp_t, con // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of the sine in compact mode detected"); - } } return f; diff --git a/src/math/sinh.cpp b/src/math/sinh.cpp index a527c16ef..70b27aa92 100644 --- a/src/math/sinh.cpp +++ b/src/math/sinh.cpp @@ -318,15 +318,6 @@ llvm::Function *taylor_c_diff_func_sinh_impl(llvm_state &s, llvm::Type *fp_t, co // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument("Inconsistent function signature for the Taylor derivative of the hyperbolic " - "sine in compact mode detected"); - } } return f; diff --git a/src/math/sum.cpp b/src/math/sum.cpp index d582542ab..07a5d7c03 100644 --- a/src/math/sum.cpp +++ b/src/math/sum.cpp @@ -401,17 +401,6 @@ llvm::Function *sum_taylor_c_diff_func_impl(llvm_state &s, llvm::Type *fp_t, con // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - // LCOV_EXCL_START - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of sum() in compact mode detected"); - // LCOV_EXCL_STOP - } } return f; diff --git a/src/math/tan.cpp b/src/math/tan.cpp index ccde33618..bfb6fa12c 100644 --- a/src/math/tan.cpp +++ b/src/math/tan.cpp @@ -365,15 +365,6 @@ llvm::Function *taylor_c_diff_func_tan_impl(llvm_state &s, llvm::Type *fp_t, con // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of the tangent in compact mode detected"); - } } return f; diff --git a/src/math/tanh.cpp b/src/math/tanh.cpp index 3a6414b25..5a76f604a 100644 --- a/src/math/tanh.cpp +++ b/src/math/tanh.cpp @@ -320,15 +320,6 @@ llvm::Function *taylor_c_diff_func_tanh_impl(llvm_state &s, llvm::Type *fp_t, co // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument("Inconsistent function signature for the Taylor derivative of the hyperbolic " - "tangent in compact mode detected"); - } } return f; diff --git a/src/math/time.cpp b/src/math/time.cpp index 14138c009..8445e3618 100644 --- a/src/math/time.cpp +++ b/src/math/time.cpp @@ -122,17 +122,6 @@ llvm::Function *time_impl::llvm_c_eval_func(llvm_state &s, llvm::Type *fp_t, std // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // LCOV_EXCL_START - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument(fmt::format( - "Inconsistent function signature for the evaluation of {}() in compact mode detected", "time")); - } - // LCOV_EXCL_STOP } return f; @@ -251,17 +240,6 @@ llvm::Function *taylor_c_diff_time_impl(llvm_state &s, llvm::Type *fp_t, std::ui // Restore the original insertion block. builder.SetInsertPoint(orig_bb); - } else { - // LCOV_EXCL_START - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of time() in compact mode detected"); - } - // LCOV_EXCL_STOP } return f; diff --git a/src/math/tpoly.cpp b/src/math/tpoly.cpp deleted file mode 100644 index af5ce71d5..000000000 --- a/src/math/tpoly.cpp +++ /dev/null @@ -1,313 +0,0 @@ -// Copyright 2020, 2021, 2022, 2023 Francesco Biscani (bluescarni@gmail.com), Dario Izzo (dario.izzo@gmail.com) -// -// This file is part of the heyoka library. -// -// 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/. - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(HEYOKA_HAVE_REAL128) - -#include - -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -HEYOKA_BEGIN_NAMESPACE - -namespace detail -{ - -tpoly_impl::tpoly_impl() : tpoly_impl(par[0], par[1]) {} - -tpoly_impl::tpoly_impl(expression b, expression e) - : func_base("tpoly", std::vector{std::move(b), std::move(e)}) -{ - if (!std::holds_alternative(args()[0].value())) { - throw std::invalid_argument("Cannot construct a time polynomial from a non-param argument"); - } - m_b_idx = std::get(args()[0].value()).idx(); - - if (!std::holds_alternative(args()[1].value())) { - throw std::invalid_argument("Cannot construct a time polynomial from a non-param argument"); - } - m_e_idx = std::get(args()[1].value()).idx(); - - if (m_e_idx <= m_b_idx) { - throw std::invalid_argument(fmt::format("Cannot construct a time polynomial from param indices {} and {}: the " - "first index is not less than the second", - m_b_idx, m_e_idx)); - } -} - -void tpoly_impl::to_stream(std::ostringstream &oss) const -{ - oss << fmt::format("tpoly({}, {})", m_b_idx, m_e_idx); -} - -namespace -{ - -llvm::Value *taylor_diff_tpoly_impl(llvm_state &s, llvm::Type *fp_t, const tpoly_impl &tp, - // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) - llvm::Value *par_ptr, llvm::Value *time_ptr, std::uint32_t order, - std::uint32_t batch_size) -{ - assert(tp.m_e_idx > tp.m_b_idx); - assert(std::holds_alternative(tp.args()[0].value())); - assert(std::holds_alternative(tp.args()[1].value())); - - const auto n = (tp.m_e_idx - tp.m_b_idx) - 1u; - - auto &builder = s.builder(); - - // Null retval if the diff order is larger than the - // polynomial order. - if (order > n) { - return vector_splat(builder, llvm_codegen(s, fp_t, number{0.}), batch_size); - } - - // Load the time value. - auto *tm = ext_load_vector_from_memory(s, fp_t, time_ptr, batch_size); - - // Init the return value with the highest-order coefficient (scaled by the corresponding - // binomial coefficient). - assert(tp.m_e_idx > 0u); - auto bc = binomial(number_like(s, fp_t, static_cast(n)), number_like(s, fp_t, static_cast(order))); - auto *ret = taylor_codegen_numparam(s, fp_t, param{tp.m_e_idx - 1u}, par_ptr, batch_size); - ret = llvm_fmul(s, ret, vector_splat(builder, llvm_codegen(s, fp_t, bc), batch_size)); - - // Horner evaluation of polynomial derivative. - for (std::uint32_t i_ = 1; i_ <= n - order; ++i_) { - // NOTE: need to invert i because Horner's method - // proceeds backwards. - const auto i = n - order - i_; - - // Compute the binomial coefficient. - bc = binomial(number_like(s, fp_t, static_cast(i + order)), - number_like(s, fp_t, static_cast(order))); - - // Load the poly coefficient from the par array and multiply it by bc. - auto *cf = taylor_codegen_numparam(s, fp_t, param{tp.m_b_idx + i + order}, par_ptr, batch_size); - cf = llvm_fmul(s, cf, vector_splat(builder, llvm_codegen(s, fp_t, bc), batch_size)); - - // Horner iteration. - ret = llvm_fadd(s, cf, llvm_fmul(s, ret, tm)); - } - - return ret; -} - -} // namespace - -llvm::Value *tpoly_impl::taylor_diff(llvm_state &s, llvm::Type *fp_t, const std::vector &, - const std::vector &, llvm::Value *par_ptr, llvm::Value *time_ptr, - std::uint32_t, std::uint32_t order, std::uint32_t, std::uint32_t batch_size, - bool) const -{ - return taylor_diff_tpoly_impl(s, fp_t, *this, par_ptr, time_ptr, order, batch_size); -} - -namespace -{ - -llvm::Function *taylor_c_diff_tpoly_impl(llvm_state &s, llvm::Type *scal_t, const tpoly_impl &tp, std::uint32_t n_uvars, - std::uint32_t batch_size) -{ - assert(tp.m_e_idx > tp.m_b_idx); - assert(std::holds_alternative(tp.args()[0].value())); - assert(std::holds_alternative(tp.args()[1].value())); - - // Make the poly degree a compile-time (JIT) constant. - const auto n_const = (tp.m_e_idx - tp.m_b_idx) - 1u; - - auto &md = s.module(); - auto &builder = s.builder(); - auto &context = s.context(); - - // Fetch the vector floating-point type. - auto *val_t = make_vector_type(scal_t, batch_size); - - // Fetch the external type corresponding to scal_t. - auto *ext_scal_t = llvm_ext_type(scal_t); - - // Fetch the function name and arguments. - // NOTE: we mangle on the poly degree as well, so that we will be - // generating a different function for each polynomial degree. - const auto na_pair - = taylor_c_diff_func_name_args(context, scal_t, fmt::format("tpoly_{}", n_const), n_uvars, batch_size, - {std::get(tp.args()[0].value()), std::get(tp.args()[1].value())}); - const auto &fname = na_pair.first; - const auto &fargs = na_pair.second; - - // Try to see if we already created the function. - auto *f = md.getFunction(fname); - - if (f == nullptr) { - // The function was not created before, do it now. - - // Fetch the current insertion block. - auto *orig_bb = builder.GetInsertBlock(); - - // Helper to fetch the (i, j) binomial coefficient from - // a precomputed global array. The returned value is already - // splatted. - auto get_bc = [&, bc_ptr = llvm_add_bc_array(s, scal_t, n_const)](llvm::Value *i, llvm::Value *j) { - auto *idx = builder.CreateMul(i, builder.getInt32(n_const + 1u)); - idx = builder.CreateAdd(idx, j); - - auto *val = builder.CreateLoad(scal_t, builder.CreateInBoundsGEP(scal_t, bc_ptr, idx)); - - return vector_splat(builder, val, batch_size); - }; - - // The return type is val_t. - auto *ft = llvm::FunctionType::get(val_t, fargs, false); - // Create the function - f = llvm::Function::Create(ft, llvm::Function::InternalLinkage, fname, &md); - assert(f != nullptr); - - // Fetch the necessary function arguments. - auto *ord = f->args().begin(); - auto *par_ptr = f->args().begin() + 3; - auto *t_ptr = f->args().begin() + 4; - auto *b_idx = f->args().begin() + 5; - auto *e_idx = f->args().begin() + 6; - - // Create a new basic block to start insertion into. - builder.SetInsertPoint(llvm::BasicBlock::Create(context, "entry", f)); - - // Create the return value. - auto *retval = builder.CreateAlloca(val_t); - - // Cache the order of the polynomial. - auto *n = builder.getInt32(n_const); - - // Null retval if the diff order is larger than the - // polynomial order. - // NOTE: unsigned comparison. - llvm_if_then_else( - s, builder.CreateICmpUGT(ord, n), - [&]() { - builder.CreateStore(vector_splat(builder, llvm_codegen(s, scal_t, number{0.}), batch_size), retval); - }, - [&]() { - // Load the time value. - auto *tm = ext_load_vector_from_memory(s, scal_t, t_ptr, batch_size); - - // Init the return value with the highest-order coefficient (scaled by the corresponding - // binomial coefficient). - auto *bc = get_bc(n, ord); - auto *cf = ext_load_vector_from_memory( - s, scal_t, - builder.CreateInBoundsGEP( - ext_scal_t, par_ptr, - builder.CreateMul(builder.getInt32(batch_size), builder.CreateSub(e_idx, builder.getInt32(1)))), - batch_size); - cf = llvm_fmul(s, cf, bc); - builder.CreateStore(cf, retval); - - // Horner evaluation of polynomial derivative. - llvm_loop_u32(s, builder.getInt32(1), builder.CreateAdd(builder.CreateSub(n, ord), builder.getInt32(1)), - [&](llvm::Value *i_) { - // NOTE: need to invert i because Horner's method - // proceeds backwards. - auto *i = builder.CreateSub(builder.CreateSub(n, ord), i_); - - // Get the binomial coefficient. - bc = get_bc(builder.CreateAdd(i, ord), ord); - - // Load the poly coefficient from the par array and multiply it by bc. - auto *cf_idx = builder.CreateMul(builder.CreateAdd(builder.CreateAdd(b_idx, i), ord), - builder.getInt32(batch_size)); - cf = ext_load_vector_from_memory( - s, scal_t, builder.CreateInBoundsGEP(ext_scal_t, par_ptr, cf_idx), batch_size); - cf = llvm_fmul(s, cf, bc); - - // Horner iteration. - auto *new_val = llvm_fadd(s, cf, llvm_fmul(s, builder.CreateLoad(val_t, retval), tm)); - - // Update retval. - builder.CreateStore(new_val, retval); - }); - }); - - // Return the result. - builder.CreateRet(builder.CreateLoad(val_t, retval)); - - // Verify. - s.verify_function(f); - - // Restore the original insertion block. - builder.SetInsertPoint(orig_bb); - } else { - // LCOV_EXCL_START - // The function was created before. Check if the signatures match. - // NOTE: there could be a mismatch if the derivative function was created - // and then optimised - optimisation might remove arguments which are compile-time - // constants. - if (!compare_function_signature(f, val_t, fargs)) { - throw std::invalid_argument( - "Inconsistent function signature for the Taylor derivative of tpoly() in compact mode detected"); - } - // LCOV_EXCL_STOP - } - - return f; -} - -} // namespace - -llvm::Function *tpoly_impl::taylor_c_diff_func(llvm_state &s, llvm::Type *fp_t, std::uint32_t n_uvars, - std::uint32_t batch_size, bool) const -{ - return taylor_c_diff_tpoly_impl(s, fp_t, *this, n_uvars, batch_size); -} - -// NOLINTNEXTLINE(readability-convert-member-functions-to-static) -bool tpoly_impl::is_time_dependent() const -{ - return true; -} - -} // namespace detail - -expression tpoly(expression b, expression e) -{ - return expression{func{detail::tpoly_impl{std::move(b), std::move(e)}}}; -} - -HEYOKA_END_NAMESPACE - -HEYOKA_S11N_FUNC_EXPORT_IMPLEMENT(heyoka::detail::tpoly_impl) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 1c512f18a..a08e2ebb1 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -74,7 +74,6 @@ ADD_HEYOKA_TESTCASE(taylor_acosh) ADD_HEYOKA_TESTCASE(taylor_atanh) ADD_HEYOKA_TESTCASE(taylor_neg) ADD_HEYOKA_TESTCASE(taylor_kepE) -ADD_HEYOKA_TESTCASE(taylor_tpoly) ADD_HEYOKA_TESTCASE(taylor_constants) ADD_HEYOKA_TESTCASE(taylor_sum) ADD_HEYOKA_TESTCASE(taylor_sum_sq) @@ -112,7 +111,6 @@ ADD_HEYOKA_TESTCASE(sinh) ADD_HEYOKA_TESTCASE(tan) ADD_HEYOKA_TESTCASE(tanh) ADD_HEYOKA_TESTCASE(kepE) -ADD_HEYOKA_TESTCASE(tpoly) ADD_HEYOKA_TESTCASE(sum) ADD_HEYOKA_TESTCASE(sum_sq) ADD_HEYOKA_TESTCASE(prod) diff --git a/test/taylor_time_f_mp.cpp b/test/taylor_time_f_mp.cpp index 18cff6caa..3d99f0bb3 100644 --- a/test/taylor_time_f_mp.cpp +++ b/test/taylor_time_f_mp.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include "catch.hpp" @@ -59,42 +58,3 @@ TEST_CASE("time") } } } - -TEST_CASE("tpoly") -{ - using fp_t = mppp::real; - - auto x = "x"_var, y = "y"_var; - - for (auto opt_level : {0u, 3u}) { - for (auto cm : {false, true}) { - for (auto ha : {false, true}) { - for (auto prec : {30, 123}) { - { - llvm_state s{kw::opt_level = opt_level}; - - taylor_add_jet(s, "jet", {tpoly(par[0], par[2]), x + y}, 2, 1, ha, cm, {}, false, prec); - - s.compile(); - - auto jptr = reinterpret_cast(s.jit_lookup("jet")); - - std::vector jet{fp_t{2, prec}, fp_t{3, prec}}; - auto tm = fp_t{3, prec}; - std::vector pars{fp_t{.2, prec}, fp_t{.3, prec}, fp_t{.4, prec}}; - jet.resize(6, fp_t{0, prec}); - - jptr(jet.data(), pars.data(), &tm); - - REQUIRE(jet[0] == 2); - REQUIRE(jet[1] == 3); - REQUIRE(jet[2] == pars[0] + tm * pars[1]); - REQUIRE(jet[3] == approximately(fp_t{5, prec})); - REQUIRE(jet[4] == fp_t(.5, prec) * pars[1]); - REQUIRE(jet[5] == approximately(fp_t{1, prec} / fp_t{2, prec} * (jet[2] + jet[3]))); - } - } - } - } - } -} diff --git a/test/taylor_tpoly.cpp b/test/taylor_tpoly.cpp deleted file mode 100644 index 86cc25bac..000000000 --- a/test/taylor_tpoly.cpp +++ /dev/null @@ -1,572 +0,0 @@ -// Copyright 2020, 2021, 2022, 2023 Francesco Biscani (bluescarni@gmail.com), Dario Izzo (dario.izzo@gmail.com) -// -// This file is part of the heyoka library. -// -// 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/. - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(HEYOKA_HAVE_REAL128) - -#include - -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "catch.hpp" -#include "test_utils.hpp" - -static std::mt19937 rng; - -using namespace heyoka; -using namespace heyoka_test; -namespace hy = heyoka; - -const auto fp_types = std::tuple{}; - -template -void compare_batch_scalar(std::initializer_list sys, unsigned opt_level, bool high_accuracy, bool compact_mode) -{ - for (auto batch_size : {2u, 4u, 8u, 5u}) { - llvm_state s{kw::opt_level = opt_level}; - - taylor_add_jet(s, "jet_batch", sys, 3, batch_size, high_accuracy, compact_mode); - taylor_add_jet(s, "jet_scalar", sys, 3, 1, high_accuracy, compact_mode); - - s.compile(); - - auto jptr_batch = reinterpret_cast(s.jit_lookup("jet_batch")); - auto jptr_scalar = reinterpret_cast(s.jit_lookup("jet_scalar")); - - std::vector jet_batch, time_batch, pars_scalar, pars_batch; - jet_batch.resize(8 * batch_size); - time_batch.resize(batch_size); - pars_scalar.resize(3); - pars_batch.resize(3 * batch_size); - std::uniform_real_distribution dist(.1f, 20.f); - std::generate(jet_batch.begin(), jet_batch.end(), [&dist]() { return T{dist(rng)}; }); - std::generate(time_batch.begin(), time_batch.end(), [&dist]() { return T{dist(rng)}; }); - std::generate(pars_batch.begin(), pars_batch.end(), [&dist]() { return T{dist(rng)}; }); - - std::vector jet_scalar; - T time_scalar(0); - jet_scalar.resize(8); - - jptr_batch(jet_batch.data(), pars_batch.data(), time_batch.data()); - - for (auto batch_idx = 0u; batch_idx < batch_size; ++batch_idx) { - // Assign the initial values of x and y. - for (auto i = 0u; i < 2u; ++i) { - jet_scalar[i] = jet_batch[i * batch_size + batch_idx]; - } - - // Assign the time. - time_scalar = time_batch[batch_idx]; - - // Assign the poly cfs. - pars_scalar[0] = pars_batch[batch_idx]; - pars_scalar[1] = pars_batch[batch_size + batch_idx]; - pars_scalar[2] = pars_batch[2u * batch_size + batch_idx]; - - jptr_scalar(jet_scalar.data(), pars_scalar.data(), &time_scalar); - - for (auto i = 2u; i < 8u; ++i) { - REQUIRE(jet_scalar[i] == approximately(jet_batch[i * batch_size + batch_idx])); - } - } - } -} - -TEST_CASE("is_time_dependent") -{ - REQUIRE(std::get(tpoly(par[0], par[1]).value()).is_time_dependent()); -} - -TEST_CASE("ode test") -{ - auto x = "x"_var; - - auto eq = 6. * hy::time * cos(tpoly(par[0], par[3])) - - tpoly(par[3], par[6]) * sin(tpoly(par[0], par[3])) * tpoly(par[6], par[8]); - - auto pars = std::vector{-1, 2, 1, 1, 0, 3, 2, 2}; - - taylor_adaptive ta({prime(x) = eq}, {std::cos(-1.)}, kw::pars = std::move(pars)); - - const auto tf = 10.; - auto oc = std::get<0>(ta.propagate_until(tf)); - - REQUIRE(oc == taylor_outcome::time_limit); - REQUIRE(ta.get_state()[0] == approximately((1 + 3 * tf * tf) * std::cos(-1 + 2 * tf + tf * tf), 1000.)); -} - -TEST_CASE("mangle test") -{ - llvm_state s{kw::opt_level = 3u}; - - auto x = "x"_var, y = "y"_var; - - taylor_add_jet(s, "jet", {tpoly(par[0], par[1]), x + y + tpoly(par[0], par[3]) + tpoly(par[3], par[6])}, 10, - 1, false, true); - - std::cout << s.get_ir() << '\n'; -} - -TEST_CASE("stream output") -{ - std::ostringstream oss; - oss << tpoly(par[3], par[6]); - - REQUIRE(oss.str() == "tpoly(3, 6)"); -} - -TEST_CASE("taylor tpoly") -{ - auto tester = [](auto fp_x, unsigned opt_level, bool high_accuracy, bool compact_mode) { - using fp_t = decltype(fp_x); - - using Catch::Matchers::Message; - - auto x = "x"_var, y = "y"_var; - - { - llvm_state s{kw::opt_level = opt_level}; - - taylor_add_jet(s, "jet", {tpoly(par[0], par[1]), x + y}, 1, 1, high_accuracy, compact_mode); - - s.compile(); - - auto jptr = reinterpret_cast(s.jit_lookup("jet")); - - std::vector jet{fp_t{2}, fp_t{3}}; - jet.resize(4); - std::vector pars{42}; - fp_t t(4); - - jptr(jet.data(), pars.data(), &t); - - REQUIRE(jet[0] == 2); - REQUIRE(jet[1] == 3); - REQUIRE(jet[2] == 42); - REQUIRE(jet[3] == 5); - } - - { - llvm_state s{kw::opt_level = opt_level}; - - taylor_add_jet(s, "jet", {tpoly(par[0], par[2]), x + y}, 1, 1, high_accuracy, compact_mode); - - s.compile(); - - auto jptr = reinterpret_cast(s.jit_lookup("jet")); - - std::vector jet{fp_t{2}, fp_t{3}}; - jet.resize(4); - std::vector pars{42, -1}; - fp_t t(4); - - jptr(jet.data(), pars.data(), &t); - - REQUIRE(jet[0] == 2); - REQUIRE(jet[1] == 3); - REQUIRE(jet[2] == 38); - REQUIRE(jet[3] == 5); - } - - { - llvm_state s{kw::opt_level = opt_level}; - - taylor_add_jet(s, "jet", {tpoly(par[0], par[3]), x + y}, 1, 1, high_accuracy, compact_mode); - - s.compile(); - - auto jptr = reinterpret_cast(s.jit_lookup("jet")); - - std::vector jet{fp_t{2}, fp_t{3}}; - jet.resize(4); - std::vector pars{42, -1, 2}; - fp_t t(4); - - jptr(jet.data(), pars.data(), &t); - - REQUIRE(jet[0] == 2); - REQUIRE(jet[1] == 3); - REQUIRE(jet[2] == 42 - t + 2 * t * t); - REQUIRE(jet[3] == 5); - } - - { - llvm_state s{kw::opt_level = opt_level}; - - taylor_add_jet(s, "jet", {tpoly(par[0], par[1]), x + y}, 1, 2, high_accuracy, compact_mode); - - s.compile(); - - auto jptr = reinterpret_cast(s.jit_lookup("jet")); - - std::vector jet{fp_t{2}, fp_t{-2}, fp_t{3}, fp_t{-3}}; - jet.resize(8); - - std::vector t{fp_t{-5}, fp_t{6}}; - - std::vector pars{42, 43}; - - jptr(jet.data(), pars.data(), t.data()); - - REQUIRE(jet[0] == 2); - REQUIRE(jet[1] == -2); - - REQUIRE(jet[2] == 3); - REQUIRE(jet[3] == -3); - - REQUIRE(jet[4] == 42); - REQUIRE(jet[5] == 43); - - REQUIRE(jet[6] == 5); - REQUIRE(jet[7] == -5); - } - - { - llvm_state s{kw::opt_level = opt_level}; - - taylor_add_jet(s, "jet", {tpoly(par[0], par[2]), x + y}, 1, 2, high_accuracy, compact_mode); - - s.compile(); - - auto jptr = reinterpret_cast(s.jit_lookup("jet")); - - std::vector jet{fp_t{2}, fp_t{-2}, fp_t{3}, fp_t{-3}}; - jet.resize(8); - - std::vector t{fp_t{-5}, fp_t{6}}; - - std::vector pars{42, 43, -1, -2}; - - jptr(jet.data(), pars.data(), t.data()); - - REQUIRE(jet[0] == 2); - REQUIRE(jet[1] == -2); - - REQUIRE(jet[2] == 3); - REQUIRE(jet[3] == -3); - - REQUIRE(jet[4] == pars[0] + pars[2] * t[0]); - REQUIRE(jet[5] == pars[1] + pars[3] * t[1]); - - REQUIRE(jet[6] == 5); - REQUIRE(jet[7] == -5); - } - - { - llvm_state s{kw::opt_level = opt_level}; - - taylor_add_jet(s, "jet", {tpoly(par[0], par[3]), x + y}, 1, 2, high_accuracy, compact_mode); - - s.compile(); - - auto jptr = reinterpret_cast(s.jit_lookup("jet")); - - std::vector jet{fp_t{2}, fp_t{-2}, fp_t{3}, fp_t{-3}}; - jet.resize(8); - - std::vector t{fp_t{-5}, fp_t{6}}; - - std::vector pars{42, 43, -1, -2, 1, 0}; - - jptr(jet.data(), pars.data(), t.data()); - - REQUIRE(jet[0] == 2); - REQUIRE(jet[1] == -2); - - REQUIRE(jet[2] == 3); - REQUIRE(jet[3] == -3); - - REQUIRE(jet[4] == pars[0] + pars[2] * t[0] + pars[4] * t[0] * t[0]); - REQUIRE(jet[5] == pars[1] + pars[3] * t[1] + pars[5] * t[1] * t[1]); - - REQUIRE(jet[6] == 5); - REQUIRE(jet[7] == -5); - } - - { - llvm_state s{kw::opt_level = opt_level}; - - taylor_add_jet(s, "jet", {tpoly(par[0], par[1]), x + y}, 2, 1, high_accuracy, compact_mode); - - s.compile(); - - auto jptr = reinterpret_cast(s.jit_lookup("jet")); - - std::vector jet{fp_t{2}, fp_t{3}}; - jet.resize(6); - - fp_t t(-4); - - std::vector pars{42}; - - jptr(jet.data(), pars.data(), &t); - - REQUIRE(jet[0] == 2); - REQUIRE(jet[1] == 3); - REQUIRE(jet[2] == pars[0]); - REQUIRE(jet[3] == 5); - REQUIRE(jet[4] == 0); - REQUIRE(jet[5] == approximately(fp_t{1} / 2 * (jet[3] + jet[2]))); - } - - { - llvm_state s{kw::opt_level = opt_level}; - - taylor_add_jet(s, "jet", {tpoly(par[0], par[2]), x + y}, 2, 1, high_accuracy, compact_mode); - - s.compile(); - - auto jptr = reinterpret_cast(s.jit_lookup("jet")); - - std::vector jet{fp_t{2}, fp_t{3}}; - jet.resize(6); - - fp_t t(-4); - - std::vector pars{42, -1}; - - jptr(jet.data(), pars.data(), &t); - - REQUIRE(jet[0] == 2); - REQUIRE(jet[1] == 3); - REQUIRE(jet[2] == pars[0] + t * pars[1]); - REQUIRE(jet[3] == 5); - REQUIRE(jet[4] == fp_t{1} / 2 * pars[1]); - REQUIRE(jet[5] == approximately(fp_t{1} / 2 * (jet[3] + jet[2]))); - } - - { - llvm_state s{kw::opt_level = opt_level}; - - taylor_add_jet(s, "jet", {tpoly(par[0], par[3]), x + y}, 2, 1, high_accuracy, compact_mode); - - s.compile(); - - auto jptr = reinterpret_cast(s.jit_lookup("jet")); - - std::vector jet{fp_t{2}, fp_t{3}}; - jet.resize(6); - - fp_t t(-4); - - std::vector pars{42, -1, 4}; - - jptr(jet.data(), pars.data(), &t); - - REQUIRE(jet[0] == 2); - REQUIRE(jet[1] == 3); - REQUIRE(jet[2] == pars[0] + t * pars[1] + t * t * pars[2]); - REQUIRE(jet[3] == 5); - REQUIRE(jet[4] == fp_t{1} / 2 * (pars[1] + 2 * t * pars[2])); - REQUIRE(jet[5] == approximately(fp_t{1} / 2 * (jet[3] + jet[2]))); - } - - { - llvm_state s{kw::opt_level = opt_level}; - - taylor_add_jet(s, "jet", {tpoly(par[0], par[1]) + x, x + y}, 2, 2, high_accuracy, compact_mode); - - s.compile(); - - auto jptr = reinterpret_cast(s.jit_lookup("jet")); - - std::vector jet{fp_t{2}, fp_t{-2}, fp_t{3}, fp_t{-3}}; - jet.resize(12); - - std::vector t{fp_t{-5}, fp_t{6}}; - - std::vector pars{42, 43}; - - jptr(jet.data(), pars.data(), t.data()); - - REQUIRE(jet[0] == 2); - REQUIRE(jet[1] == -2); - - REQUIRE(jet[2] == 3); - REQUIRE(jet[3] == -3); - - REQUIRE(jet[4] == jet[0] + pars[0]); - REQUIRE(jet[5] == jet[1] + pars[1]); - - REQUIRE(jet[6] == 5); - REQUIRE(jet[7] == -5); - - REQUIRE(jet[8] == approximately(fp_t{1} / 2 * (jet[4]))); - REQUIRE(jet[9] == approximately(fp_t{1} / 2 * (jet[5]))); - - REQUIRE(jet[10] == approximately(fp_t{1} / 2 * (jet[6] + jet[4]))); - REQUIRE(jet[11] == approximately(fp_t{1} / 2 * (jet[7] + jet[5]))); - } - - { - llvm_state s{kw::opt_level = opt_level}; - - taylor_add_jet(s, "jet", {tpoly(par[0], par[2]) + x, x + y}, 2, 2, high_accuracy, compact_mode); - - s.compile(); - - auto jptr = reinterpret_cast(s.jit_lookup("jet")); - - std::vector jet{fp_t{2}, fp_t{-2}, fp_t{3}, fp_t{-3}}; - jet.resize(12); - - std::vector t{fp_t{-5}, fp_t{6}}; - - std::vector pars{42, 43, -1, -2}; - - jptr(jet.data(), pars.data(), t.data()); - - REQUIRE(jet[0] == 2); - REQUIRE(jet[1] == -2); - - REQUIRE(jet[2] == 3); - REQUIRE(jet[3] == -3); - - REQUIRE(jet[4] == jet[0] + pars[0] + pars[2] * t[0]); - REQUIRE(jet[5] == jet[1] + pars[1] + pars[3] * t[1]); - - REQUIRE(jet[6] == 5); - REQUIRE(jet[7] == -5); - - REQUIRE(jet[8] == approximately(fp_t{1} / 2 * (pars[2] + jet[4]))); - REQUIRE(jet[9] == approximately(fp_t{1} / 2 * (pars[3] + jet[5]))); - - REQUIRE(jet[10] == approximately(fp_t{1} / 2 * (jet[6] + jet[4]))); - REQUIRE(jet[11] == approximately(fp_t{1} / 2 * (jet[7] + jet[5]))); - } - - { - llvm_state s{kw::opt_level = opt_level}; - - taylor_add_jet(s, "jet", {tpoly(par[0], par[3]) + x, x + y}, 2, 2, high_accuracy, compact_mode); - - s.compile(); - - auto jptr = reinterpret_cast(s.jit_lookup("jet")); - - std::vector jet{fp_t{2}, fp_t{-2}, fp_t{3}, fp_t{-3}}; - jet.resize(12); - - std::vector t{fp_t{-5}, fp_t{6}}; - - std::vector pars{42, 43, -1, -2, 4, 5}; - - jptr(jet.data(), pars.data(), t.data()); - - REQUIRE(jet[0] == 2); - REQUIRE(jet[1] == -2); - - REQUIRE(jet[2] == 3); - REQUIRE(jet[3] == -3); - - REQUIRE(jet[4] == jet[0] + pars[0] + pars[2] * t[0] + pars[4] * t[0] * t[0]); - REQUIRE(jet[5] == jet[1] + pars[1] + pars[3] * t[1] + pars[5] * t[1] * t[1]); - - REQUIRE(jet[6] == 5); - REQUIRE(jet[7] == -5); - - REQUIRE(jet[8] == approximately(fp_t{1} / 2 * (pars[2] + 2 * pars[4] * t[0] + jet[4]))); - REQUIRE(jet[9] == approximately(fp_t{1} / 2 * (pars[3] + 2 * pars[5] * t[1] + jet[5]))); - - REQUIRE(jet[10] == approximately(fp_t{1} / 2 * (jet[6] + jet[4]))); - REQUIRE(jet[11] == approximately(fp_t{1} / 2 * (jet[7] + jet[5]))); - } - - { - llvm_state s{kw::opt_level = opt_level}; - - taylor_add_jet(s, "jet", {tpoly(par[0], par[3]) + x, x + y}, 3, 3, high_accuracy, compact_mode); - - s.compile(); - - auto jptr = reinterpret_cast(s.jit_lookup("jet")); - - std::vector jet{fp_t{2}, fp_t{-2}, fp_t{1}, fp_t{3}, fp_t{-3}, fp_t{0}}; - jet.resize(24); - - std::vector t{fp_t{-5}, fp_t{6}, fp_t{-1}}; - - std::vector pars{42, 43, 44, -1, -2, -3, 4, 5, 6}; - - jptr(jet.data(), pars.data(), t.data()); - - REQUIRE(jet[0] == 2); - REQUIRE(jet[1] == -2); - REQUIRE(jet[2] == 1); - - REQUIRE(jet[3] == 3); - REQUIRE(jet[4] == -3); - REQUIRE(jet[5] == 0); - - REQUIRE(jet[6] == approximately(jet[0] + pars[0] + pars[3] * t[0] + pars[6] * t[0] * t[0])); - REQUIRE(jet[7] == approximately(jet[1] + pars[1] + pars[4] * t[1] + pars[7] * t[1] * t[1])); - REQUIRE(jet[8] == approximately(jet[2] + pars[2] + pars[5] * t[2] + pars[8] * t[2] * t[2])); - - REQUIRE(jet[9] == 5); - REQUIRE(jet[10] == -5); - REQUIRE(jet[11] == 1); - - REQUIRE(jet[12] == approximately(fp_t{1} / 2 * (jet[6] + pars[3] + 2 * pars[6] * t[0]))); - REQUIRE(jet[13] == approximately(fp_t{1} / 2 * (jet[7] + pars[4] + 2 * pars[7] * t[1]))); - REQUIRE(jet[14] == approximately(fp_t{1} / 2 * (jet[8] + pars[5] + 2 * pars[8] * t[2]))); - - REQUIRE(jet[15] == approximately(fp_t{1} / 2 * (jet[9] + jet[6]))); - REQUIRE(jet[16] == approximately(fp_t{1} / 2 * (jet[10] + jet[7]))); - REQUIRE(jet[17] == approximately(fp_t{1} / 2 * (jet[11] + jet[8]))); - - REQUIRE(jet[18] == approximately(fp_t{1} / 6 * (2 * jet[12] + 2 * pars[6]))); - REQUIRE(jet[19] == approximately(fp_t{1} / 6 * (2 * jet[13] + 2 * pars[7]))); - REQUIRE(jet[20] == approximately(fp_t{1} / 6 * (2 * jet[14] + 2 * pars[8]))); - - REQUIRE(jet[21] == approximately(fp_t{1} / 6 * (2 * jet[15] + 2 * jet[12]))); - REQUIRE(jet[22] == approximately(fp_t{1} / 6 * (2 * jet[16] + 2 * jet[13]))); - REQUIRE(jet[23] == approximately(fp_t{1} / 6 * (2 * jet[17] + 2 * jet[14]))); - } - - // Do the batch/scalar comparison. - compare_batch_scalar({x + tpoly(par[0], par[3]), x + y}, opt_level, high_accuracy, compact_mode); - }; - - for (auto cm : {true, false}) { - for (auto f : {false, true}) { - tuple_for_each(fp_types, [&tester, f, cm](auto x) { tester(x, 0, f, cm); }); - tuple_for_each(fp_types, [&tester, f, cm](auto x) { tester(x, 1, f, cm); }); - tuple_for_each(fp_types, [&tester, f, cm](auto x) { tester(x, 2, f, cm); }); - tuple_for_each(fp_types, [&tester, f, cm](auto x) { tester(x, 3, f, cm); }); - } - } -} diff --git a/test/tpoly.cpp b/test/tpoly.cpp deleted file mode 100644 index 633ecb82e..000000000 --- a/test/tpoly.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2020, 2021, 2022, 2023 Francesco Biscani (bluescarni@gmail.com), Dario Izzo (dario.izzo@gmail.com) -// -// This file is part of the heyoka library. -// -// 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/. - -#include -#include -#include - -#include -#include -#include - -#include "catch.hpp" - -using namespace heyoka; - -TEST_CASE("tpoly basics") -{ - using Catch::Matchers::Message; - - { - detail::tpoly_impl tp; - - REQUIRE(tp.m_b_idx == 0u); - REQUIRE(tp.m_e_idx == 1u); - - REQUIRE(tp.args()[0] == par[0]); - REQUIRE(tp.args()[1] == par[1]); - } - - { - detail::tpoly_impl tp(par[10], par[12]); - - REQUIRE(tp.m_b_idx == 10u); - REQUIRE(tp.m_e_idx == 12u); - - REQUIRE(tp.args()[0] == par[10]); - REQUIRE(tp.args()[1] == par[12]); - } - - // Verify equality/hashing. - REQUIRE(tpoly(par[0], par[10]) == tpoly(par[0], par[10])); - REQUIRE(tpoly(par[0], par[10]) != tpoly(par[10], par[20])); - REQUIRE(std::hash{}(tpoly(par[0], par[10])) == std::hash{}(tpoly(par[0], par[10]))); - REQUIRE(std::hash{}(tpoly(par[0], par[10])) != std::hash{}(tpoly(par[10], par[20]))); - - REQUIRE_THROWS_MATCHES(tpoly(par[10], par[9]), std::invalid_argument, - Message("Cannot construct a time polynomial from param indices 10 and 9: the first index is " - "not less than the second")); - REQUIRE_THROWS_MATCHES( - tpoly(par[11], par[11]), std::invalid_argument, - Message("Cannot construct a time polynomial from param indices 11 and 11: the first index is " - "not less than the second")); - - REQUIRE_THROWS_MATCHES(tpoly("x"_var, par[11]), std::invalid_argument, - Message("Cannot construct a time polynomial from a non-param argument")); - REQUIRE_THROWS_MATCHES(tpoly(par[11], "x"_var), std::invalid_argument, - Message("Cannot construct a time polynomial from a non-param argument")); -} - -TEST_CASE("tpoly s11n") -{ - std::stringstream ss; - - auto [x] = make_vars("x"); - - auto ex = tpoly(par[10], par[20]) + x; - - { - boost::archive::binary_oarchive oa(ss); - - oa << ex; - } - - ex = 0_dbl; - - { - boost::archive::binary_iarchive ia(ss); - - ia >> ex; - } - - REQUIRE(ex == tpoly(par[10], par[20]) + x); -}