From ef1383c4d9aca2020bff6f5e37bc0b8bda3deaea Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sun, 15 Sep 2024 17:10:48 +0200 Subject: [PATCH] Test additions, coverage fixes, simplifications. --- src/math/pow.cpp | 25 ++++++++-------------- test/taylor_pow.cpp | 51 ++++++++++++++++++++++++++++++++------------- 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/src/math/pow.cpp b/src/math/pow.cpp index c71e98ac2..7a7d7fa62 100644 --- a/src/math/pow.cpp +++ b/src/math/pow.cpp @@ -528,23 +528,14 @@ llvm::Value *taylor_diff_pow_impl(llvm_state &s, llvm::Type *fp_t, const pow_imp auto *v1 = taylor_fetch_diff(arr, idx, j, n_uvars); // Compute the scalar factor: order * num - j * (num + 1). - auto scal_f = [&]() -> llvm::Value * { - if constexpr (std::is_same_v) { - return llvm_codegen(s, vec_t, - number_like(s, fp_t, static_cast(order)) * num - - number_like(s, fp_t, static_cast(j)) - * (num + number_like(s, fp_t, 1.))); - } else { - auto *jvec = llvm_codegen(s, vec_t, number(static_cast(j))); - auto *ordvec = llvm_codegen(s, vec_t, number(static_cast(order))); - auto *onevec = llvm_codegen(s, vec_t, number(1.)); + auto *jvec = llvm_codegen(s, vec_t, number(static_cast(j))); + auto *ordvec = llvm_codegen(s, vec_t, number(static_cast(order))); + auto *onevec = llvm_codegen(s, vec_t, number(1.)); - auto *tmp1 = llvm_fmul(s, ordvec, expo); - auto *tmp2 = llvm_fmul(s, jvec, llvm_fadd(s, expo, onevec)); + auto *tmp1 = llvm_fmul(s, ordvec, expo); + auto *tmp2 = llvm_fmul(s, jvec, llvm_fadd(s, expo, onevec)); - return llvm_fsub(s, tmp1, tmp2); - } - }(); + auto *scal_f = llvm_fsub(s, tmp1, tmp2); // Add scal_f*v0*v1 to the sum. sum.push_back(llvm_fmul(s, scal_f, llvm_fmul(s, v0, v1))); @@ -584,6 +575,7 @@ llvm::Value *taylor_diff_pow(llvm_state &s, llvm::Type *fp_t, const pow_impl &f, { assert(f.args().size() == 2u); + // LCOV_EXCL_START if (!deps.empty()) { throw std::invalid_argument( fmt::format("An empty hidden dependency vector is expected in order to compute the Taylor " @@ -591,6 +583,7 @@ llvm::Value *taylor_diff_pow(llvm_state &s, llvm::Type *fp_t, const pow_impl &f, "instead", deps.size())); } + // LCOV_EXCL_STOP return std::visit( [&](const auto &v1, const auto &v2) { @@ -904,7 +897,7 @@ llvm::Function *taylor_c_diff_func_pow_impl(llvm_state &s, llvm::Type *fp_t, con 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); + assert(f != nullptr); // LCOV_EXCL_LINE // Fetch the necessary function arguments. auto ord = f->args().begin(); diff --git a/test/taylor_pow.cpp b/test/taylor_pow.cpp index 17e1632ff..ccf2d480f 100644 --- a/test/taylor_pow.cpp +++ b/test/taylor_pow.cpp @@ -718,28 +718,49 @@ TEST_CASE("taylor pow") } } -// Small test for the preprocessing that turns pow into exp+log. +// Tests for the preprocessing that turns pow into exp+log. TEST_CASE("pow_to_explog") { auto [x, y] = make_vars("x", "y"); - auto tmp1 = x + pow(y, par[0]); - auto tmp2 = pow(x, tmp1); - auto tmp3 = pow(tmp1, y); + for (auto cm : {false, true}) { + auto tmp1 = x + pow(y, par[0]); + auto tmp2 = pow(x, tmp1); + auto tmp3 = pow(tmp1, par[1]); - auto ta = taylor_adaptive{{prime(x) = (tmp1 * tmp2) / tmp3, prime(y) = tmp1}, {}, kw::tol = 1e-1}; + auto ta = taylor_adaptive{ + {prime(x) = (tmp1 * tmp2) / tmp3, prime(y) = tmp1}, {.1, .2}, kw::pars = {1.2, 3.4}, kw::compact_mode = cm}; - REQUIRE(ta.get_decomposition().size() == 16u); + REQUIRE(ta.get_decomposition().size() == 16u); - // Count the number of exps and logs. - auto n_exp = 0, n_log = 0; - for (const auto &[ex, _] : ta.get_decomposition()) { - if (const auto *fptr = std::get_if(&ex.value())) { - n_exp += (fptr->extract() != nullptr); - n_log += (fptr->extract() != nullptr); + // Count the number of exps and logs. + auto n_exp = 0, n_log = 0; + for (const auto &[ex, _] : ta.get_decomposition()) { + if (const auto *fptr = std::get_if(&ex.value())) { + n_exp += (fptr->extract() != nullptr); + n_log += (fptr->extract() != nullptr); + } } - } - REQUIRE(n_exp == 3); - REQUIRE(n_log == 3); + REQUIRE(n_exp == 3); + REQUIRE(n_log == 3); + + // Create an analogous of ta in which the pars have been hard-coded to numbers. + tmp1 = x + pow(y, 1.2); + tmp2 = pow(x, tmp1); + tmp3 = pow(tmp1, 3.4); + + auto ta_hc = taylor_adaptive{ + {prime(x) = (tmp1 * tmp2) / tmp3, prime(y) = tmp1}, {.1, .2}, kw::compact_mode = cm}; + + // Compute the Taylor coefficients. + ta.step(0., true); + ta_hc.step(0., true); + + // Compare them. + auto n_tc = ta.get_tc().size(); + for (decltype(n_tc) i = 0; i < n_tc; ++i) { + REQUIRE(ta.get_tc()[i] == approximately(ta_hc.get_tc()[i], 1000.)); + } + } }