From 39b2a52bd0cb6a6d58bd12e90466fdef7f3f6992 Mon Sep 17 00:00:00 2001 From: conrad Date: Mon, 14 Jul 2025 14:02:19 +1000 Subject: [PATCH] allow to optionally disable optimised handling of pow() --- include/armadillo_bits/Cube_meat.hpp | 12 ++++++------ include/armadillo_bits/Mat_meat.hpp | 12 ++++++------ include/armadillo_bits/arma_config.hpp | 7 +++++++ include/armadillo_bits/config.hpp | 9 +++++++++ include/armadillo_bits/config.hpp.cmake | 9 +++++++++ include/armadillo_bits/debug.hpp | 1 + include/armadillo_bits/fn_accu.hpp | 8 ++++---- include/armadillo_bits/op_sum_meat.hpp | 4 ++-- 8 files changed, 44 insertions(+), 18 deletions(-) diff --git a/include/armadillo_bits/Cube_meat.hpp b/include/armadillo_bits/Cube_meat.hpp index 41c6b30a..e9de1e22 100644 --- a/include/armadillo_bits/Cube_meat.hpp +++ b/include/armadillo_bits/Cube_meat.hpp @@ -2872,7 +2872,7 @@ Cube::Cube(const eOpCube& X) init_cold(); - if(is_same_type::value) + if(arma_config::optimise_powexpr && is_same_type::value) { constexpr bool eT_non_int = is_non_integral::value; @@ -2902,7 +2902,7 @@ Cube::operator=(const eOpCube& X) init_warm(X.get_n_rows(), X.get_n_cols(), X.get_n_slices()); - if(is_same_type::value) + if(arma_config::optimise_powexpr && is_same_type::value) { constexpr bool eT_non_int = is_non_integral::value; @@ -2932,7 +2932,7 @@ Cube::operator+=(const eOpCube& X) if(bad_alias) { const Cube tmp(X); return (*this).operator+=(tmp); } - if(is_same_type::value) + if(arma_config::optimise_powexpr && is_same_type::value) { constexpr bool eT_non_int = is_non_integral::value; @@ -2962,7 +2962,7 @@ Cube::operator-=(const eOpCube& X) if(bad_alias) { const Cube tmp(X); return (*this).operator-=(tmp); } - if(is_same_type::value) + if(arma_config::optimise_powexpr && is_same_type::value) { constexpr bool eT_non_int = is_non_integral::value; @@ -2992,7 +2992,7 @@ Cube::operator%=(const eOpCube& X) if(bad_alias) { const Cube tmp(X); return (*this).operator%=(tmp); } - if(is_same_type::value) + if(arma_config::optimise_powexpr && is_same_type::value) { constexpr bool eT_non_int = is_non_integral::value; @@ -3022,7 +3022,7 @@ Cube::operator/=(const eOpCube& X) if(bad_alias) { const Cube tmp(X); return (*this).operator/=(tmp); } - if(is_same_type::value) + if(arma_config::optimise_powexpr && is_same_type::value) { constexpr bool eT_non_int = is_non_integral::value; diff --git a/include/armadillo_bits/Mat_meat.hpp b/include/armadillo_bits/Mat_meat.hpp index 5dc3dbce..e4e0d695 100644 --- a/include/armadillo_bits/Mat_meat.hpp +++ b/include/armadillo_bits/Mat_meat.hpp @@ -5201,7 +5201,7 @@ Mat::Mat(const eOp& X) init_cold(); - if(is_same_type::value) + if(arma_config::optimise_powexpr && is_same_type::value) { constexpr bool eT_non_int = is_non_integral::value; @@ -5231,7 +5231,7 @@ Mat::operator=(const eOp& X) init_warm(X.get_n_rows(), X.get_n_cols()); - if(is_same_type::value) + if(arma_config::optimise_powexpr && is_same_type::value) { constexpr bool eT_non_int = is_non_integral::value; @@ -5260,7 +5260,7 @@ Mat::operator+=(const eOp& X) if(bad_alias) { const Mat tmp(X); return (*this).operator+=(tmp); } - if(is_same_type::value) + if(arma_config::optimise_powexpr && is_same_type::value) { constexpr bool eT_non_int = is_non_integral::value; @@ -5289,7 +5289,7 @@ Mat::operator-=(const eOp& X) if(bad_alias) { const Mat tmp(X); return (*this).operator-=(tmp); } - if(is_same_type::value) + if(arma_config::optimise_powexpr && is_same_type::value) { constexpr bool eT_non_int = is_non_integral::value; @@ -5335,7 +5335,7 @@ Mat::operator%=(const eOp& X) if(bad_alias) { const Mat tmp(X); return (*this).operator%=(tmp); } - if(is_same_type::value) + if(arma_config::optimise_powexpr && is_same_type::value) { constexpr bool eT_non_int = is_non_integral::value; @@ -5364,7 +5364,7 @@ Mat::operator/=(const eOp& X) if(bad_alias) { const Mat tmp(X); return (*this).operator/=(tmp); } - if(is_same_type::value) + if(arma_config::optimise_powexpr && is_same_type::value) { constexpr bool eT_non_int = is_non_integral::value; diff --git a/include/armadillo_bits/arma_config.hpp b/include/armadillo_bits/arma_config.hpp index b528219f..5467dc16 100644 --- a/include/armadillo_bits/arma_config.hpp +++ b/include/armadillo_bits/arma_config.hpp @@ -65,6 +65,13 @@ struct arma_config #endif + #if defined(ARMA_OPTIMISE_POWEXPR) + static constexpr bool optimise_powexpr = true; + #else + static constexpr bool optimise_powexpr = false; + #endif + + #if defined(ARMA_CHECK_CONFORMANCE) static constexpr bool check_conform = true; #else diff --git a/include/armadillo_bits/config.hpp b/include/armadillo_bits/config.hpp index a567629d..ea9e64fc 100644 --- a/include/armadillo_bits/config.hpp +++ b/include/armadillo_bits/config.hpp @@ -172,6 +172,11 @@ //// of inv() and inv_sympd() within compound expressions #endif +#if !defined(ARMA_OPTIMISE_POWEXPR) + #define ARMA_OPTIMISE_POWEXPR + //// Comment out the above line to disable optimised handling of pow() +#endif + #if !defined(ARMA_CHECK_CONFORMANCE) #define ARMA_CHECK_CONFORMANCE //// Comment out the above line to disable conformance checks for bounds and size. @@ -346,6 +351,10 @@ #undef ARMA_OPTIMISE_INVEXPR #endif +#if defined(ARMA_DONT_OPTIMISE_POWEXPR) + #undef ARMA_OPTIMISE_POWEXPR +#endif + #if defined(ARMA_DONT_CHECK_CONFORMANCE) #if defined(ARMA_CHECK_CONFORMANCE) && (ARMA_WARN_LEVEL >= 2) #pragma message ("WARNING: conformance checks disabled") diff --git a/include/armadillo_bits/config.hpp.cmake b/include/armadillo_bits/config.hpp.cmake index 32036333..706da587 100644 --- a/include/armadillo_bits/config.hpp.cmake +++ b/include/armadillo_bits/config.hpp.cmake @@ -172,6 +172,11 @@ //// of inv() and inv_sympd() within compound expressions #endif +#if !defined(ARMA_OPTIMISE_POWEXPR) + #define ARMA_OPTIMISE_POWEXPR + //// Comment out the above line to disable optimised handling of pow() +#endif + #if !defined(ARMA_CHECK_CONFORMANCE) #define ARMA_CHECK_CONFORMANCE //// Comment out the above line to disable conformance checks for bounds and size. @@ -346,6 +351,10 @@ #undef ARMA_OPTIMISE_INVEXPR #endif +#if defined(ARMA_DONT_OPTIMISE_POWEXPR) + #undef ARMA_OPTIMISE_POWEXPR +#endif + #if defined(ARMA_DONT_CHECK_CONFORMANCE) #if defined(ARMA_CHECK_CONFORMANCE) && (ARMA_WARN_LEVEL >= 2) #pragma message ("WARNING: conformance checks disabled") diff --git a/include/armadillo_bits/debug.hpp b/include/armadillo_bits/debug.hpp index 3244d0ad..f0d435f9 100644 --- a/include/armadillo_bits/debug.hpp +++ b/include/armadillo_bits/debug.hpp @@ -1440,6 +1440,7 @@ inline void arma_debug_check(bool state, const char* msg) { arma_conform_check( out << "\n@ arma_config::optimise_band = " << arma_config::optimise_band; out << "\n@ arma_config::optimise_sym = " << arma_config::optimise_sym; out << "\n@ arma_config::optimise_invexpr = " << arma_config::optimise_invexpr; + out << "\n@ arma_config::optimise_powexpr = " << arma_config::optimise_powexpr; out << "\n@ arma_config::check_conform = " << arma_config::check_conform; out << "\n@ arma_config::check_nonfinite = " << arma_config::check_nonfinite; out << "\n@ arma_config::fast_math = " << arma_config::fast_math; diff --git a/include/armadillo_bits/fn_accu.hpp b/include/armadillo_bits/fn_accu.hpp index 250f2785..46dfa02f 100644 --- a/include/armadillo_bits/fn_accu.hpp +++ b/include/armadillo_bits/fn_accu.hpp @@ -407,14 +407,14 @@ accu(const eOp& expr) typedef eOp expr_type; - if(expr.aux == eT(2)) + if(arma_config::optimise_powexpr && (expr.aux == eT(2))) { typedef eOp modified_expr_type; return accu( reinterpret_cast< const modified_expr_type& >(expr) ); } - if((expr.aux == eT(0.5)) && is_non_integral::value) + if(arma_config::optimise_powexpr && (expr.aux == eT(0.5)) && is_non_integral::value) { typedef eOp modified_expr_type; @@ -1048,14 +1048,14 @@ accu(const eOpCube& expr) typedef eOpCube expr_type; - if(expr.aux == eT(2)) + if(arma_config::optimise_powexpr && (expr.aux == eT(2))) { typedef eOpCube modified_expr_type; return accu( reinterpret_cast< const modified_expr_type& >(expr) ); } - if((expr.aux == eT(0.5)) && is_non_integral::value) + if(arma_config::optimise_powexpr && (expr.aux == eT(0.5)) && is_non_integral::value) { typedef eOpCube modified_expr_type; diff --git a/include/armadillo_bits/op_sum_meat.hpp b/include/armadillo_bits/op_sum_meat.hpp index d2f1eb8a..7eb044d5 100644 --- a/include/armadillo_bits/op_sum_meat.hpp +++ b/include/armadillo_bits/op_sum_meat.hpp @@ -154,7 +154,7 @@ op_sum::apply(Mat& out, const Op< eOp, op_su typedef typename T1::elem_type eT; - if(in.m.aux == eT(2)) + if(arma_config::optimise_powexpr && (in.m.aux == eT(2))) { typedef Op< eOp, op_sum > modified_whole_expr_type; @@ -163,7 +163,7 @@ op_sum::apply(Mat& out, const Op< eOp, op_su return; } - if((in.m.aux == eT(0.5)) && is_non_integral::value) + if(arma_config::optimise_powexpr && (in.m.aux == eT(0.5)) && is_non_integral::value) { typedef Op< eOp, op_sum > modified_whole_expr_type;