From c33258d10cbeda7dcbf265afd879b6786d97bb93 Mon Sep 17 00:00:00 2001 From: conrad Date: Thu, 9 Oct 2025 19:54:41 +1000 Subject: [PATCH] avoid unnecessary alias checks --- include/armadillo_bits/Mat_meat.hpp | 2 +- include/armadillo_bits/glue_times_bones.hpp | 29 ++++----- include/armadillo_bits/glue_times_meat.hpp | 65 ++++++++++++++------- 3 files changed, 60 insertions(+), 36 deletions(-) diff --git a/include/armadillo_bits/Mat_meat.hpp b/include/armadillo_bits/Mat_meat.hpp index b7719217..b8eebe97 100644 --- a/include/armadillo_bits/Mat_meat.hpp +++ b/include/armadillo_bits/Mat_meat.hpp @@ -5869,7 +5869,7 @@ Mat::Mat(const Glue& X) arma_type_check(( is_same_type< eT, typename T1::elem_type >::no )); arma_type_check(( is_same_type< eT, typename T2::elem_type >::no )); - glue_type::apply(*this, X); + glue_type::apply(static_cast< Mat_noalias& >(*this), X); } diff --git a/include/armadillo_bits/glue_times_bones.hpp b/include/armadillo_bits/glue_times_bones.hpp index 6443033e..a3dfb7e9 100644 --- a/include/armadillo_bits/glue_times_bones.hpp +++ b/include/armadillo_bits/glue_times_bones.hpp @@ -40,7 +40,7 @@ struct depth_lhs< glue_type, Glue > -template +template struct glue_times_redirect2_helper { template @@ -48,8 +48,8 @@ struct glue_times_redirect2_helper }; -template<> -struct glue_times_redirect2_helper +template +struct glue_times_redirect2_helper { template arma_hot inline static void apply(Mat& out, const Glue& X); @@ -57,7 +57,7 @@ struct glue_times_redirect2_helper -template +template struct glue_times_redirect3_helper { template @@ -65,8 +65,8 @@ struct glue_times_redirect3_helper }; -template<> -struct glue_times_redirect3_helper +template +struct glue_times_redirect3_helper { template arma_hot inline static void apply(Mat& out, const Glue< Glue,T3,glue_times>& X); @@ -74,7 +74,7 @@ struct glue_times_redirect3_helper -template +template struct glue_times_redirect { template @@ -82,24 +82,24 @@ struct glue_times_redirect }; -template<> -struct glue_times_redirect<2> +template +struct glue_times_redirect<2, check_alias> { template arma_hot inline static void apply(Mat& out, const Glue& X); }; -template<> -struct glue_times_redirect<3> +template +struct glue_times_redirect<3, check_alias> { template arma_hot inline static void apply(Mat& out, const Glue< Glue,T3,glue_times>& X); }; -template<> -struct glue_times_redirect<4> +template +struct glue_times_redirect<4, check_alias> { template arma_hot inline static void apply(Mat& out, const Glue< Glue< Glue, T3, glue_times>, T4, glue_times>& X); @@ -121,6 +121,9 @@ struct glue_times template arma_hot inline static void apply(Mat& out, const Glue& X); + template + arma_hot inline static void apply(Mat_noalias& out, const Glue& X); + template arma_hot inline static void apply_inplace(Mat& out, const T1& X); diff --git a/include/armadillo_bits/glue_times_meat.hpp b/include/armadillo_bits/glue_times_meat.hpp index 53f78238..479a49e7 100644 --- a/include/armadillo_bits/glue_times_meat.hpp +++ b/include/armadillo_bits/glue_times_meat.hpp @@ -21,11 +21,11 @@ -template +template template inline void -glue_times_redirect2_helper::apply(Mat& out, const Glue& X) +glue_times_redirect2_helper::apply(Mat& out, const Glue& X) { arma_debug_sigprint(); @@ -55,7 +55,7 @@ glue_times_redirect2_helper::apply(Mat& o return; } - const bool alias = U1.is_alias(out) || U2.is_alias(out); + const bool alias = (check_alias) && (U1.is_alias(out) || U2.is_alias(out)); if(alias == false) { @@ -87,10 +87,11 @@ glue_times_redirect2_helper::apply(Mat& o +template template inline void -glue_times_redirect2_helper::apply(Mat& out, const Glue& X) +glue_times_redirect2_helper::apply(Mat& out, const Glue& X) { arma_debug_sigprint(); @@ -148,7 +149,7 @@ glue_times_redirect2_helper::apply(Mat& out, const if(is_cx::yes) { arma_warn(1, "inv_sympd(): given matrix is not hermitian"); } } - const unwrap_check B_tmp(X.B, out); + const unwrap_check B_tmp(X.B, out); // TODO: refactor to use quasi_unwrap const Mat& B = B_tmp.M; arma_conform_assert_mul_size(A, B, "matrix multiplication"); @@ -202,16 +203,16 @@ glue_times_redirect2_helper::apply(Mat& out, const return; } - glue_times_redirect2_helper::apply(out, X); + glue_times_redirect2_helper::apply(out, X); } -template +template template inline void -glue_times_redirect3_helper::apply(Mat& out, const Glue< Glue, T3, glue_times>& X) +glue_times_redirect3_helper::apply(Mat& out, const Glue< Glue, T3, glue_times>& X) { arma_debug_sigprint(); @@ -231,7 +232,7 @@ glue_times_redirect3_helper::apply(Mat& o constexpr bool use_alpha = partial_unwrap::do_times || partial_unwrap::do_times || partial_unwrap::do_times; const eT alpha = use_alpha ? (U1.get_val() * U2.get_val() * U3.get_val()) : eT(0); - const bool alias = U1.is_alias(out) || U2.is_alias(out) || U3.is_alias(out); + const bool alias = (check_alias) && (U1.is_alias(out) || U2.is_alias(out) || U3.is_alias(out)); if(alias == false) { @@ -265,10 +266,11 @@ glue_times_redirect3_helper::apply(Mat& o +template template inline void -glue_times_redirect3_helper::apply(Mat& out, const Glue< Glue, T3, glue_times>& X) +glue_times_redirect3_helper::apply(Mat& out, const Glue< Glue, T3, glue_times>& X) { arma_debug_sigprint(); @@ -371,7 +373,7 @@ glue_times_redirect3_helper::apply(Mat& out, const constexpr bool use_alpha = partial_unwrap::do_times; const eT alpha = use_alpha ? U1.get_val() : eT(0); - if(U1.is_alias(out)) + if( (check_alias) && U1.is_alias(out) ) { Mat tmp; @@ -388,16 +390,16 @@ glue_times_redirect3_helper::apply(Mat& out, const } - glue_times_redirect3_helper::apply(out, X); + glue_times_redirect3_helper::apply(out, X); } -template +template template inline void -glue_times_redirect::apply(Mat& out, const Glue& X) +glue_times_redirect::apply(Mat& out, const Glue& X) { arma_debug_sigprint(); @@ -412,7 +414,7 @@ glue_times_redirect::apply(Mat& out, const Glue::do_times || partial_unwrap::do_times; const eT alpha = use_alpha ? (U1.get_val() * U2.get_val()) : eT(0); - const bool alias = U1.is_alias(out) || U2.is_alias(out); + const bool alias = (check_alias) && (U1.is_alias(out) || U2.is_alias(out)); if(alias == false) { @@ -444,38 +446,41 @@ glue_times_redirect::apply(Mat& out, const Glue template inline void -glue_times_redirect<2>::apply(Mat& out, const Glue& X) +glue_times_redirect<2, check_alias>::apply(Mat& out, const Glue& X) { arma_debug_sigprint(); typedef typename T1::elem_type eT; - glue_times_redirect2_helper< is_blas_type::value >::apply(out, X); + glue_times_redirect2_helper< is_blas_type::value, check_alias >::apply(out, X); } +template template inline void -glue_times_redirect<3>::apply(Mat& out, const Glue< Glue, T3, glue_times>& X) +glue_times_redirect<3, check_alias>::apply(Mat& out, const Glue< Glue, T3, glue_times>& X) { arma_debug_sigprint(); typedef typename T1::elem_type eT; - glue_times_redirect3_helper< is_blas_type::value >::apply(out, X); + glue_times_redirect3_helper< is_blas_type::value, check_alias >::apply(out, X); } +template template inline void -glue_times_redirect<4>::apply(Mat& out, const Glue< Glue< Glue, T3, glue_times>, T4, glue_times>& X) +glue_times_redirect<4, check_alias>::apply(Mat& out, const Glue< Glue< Glue, T3, glue_times>, T4, glue_times>& X) { arma_debug_sigprint(); @@ -497,7 +502,7 @@ glue_times_redirect<4>::apply(Mat& out, const Glue< Glue constexpr bool use_alpha = partial_unwrap::do_times || partial_unwrap::do_times || partial_unwrap::do_times || partial_unwrap::do_times; const eT alpha = use_alpha ? (U1.get_val() * U2.get_val() * U3.get_val() * U4.get_val()) : eT(0); - const bool alias = U1.is_alias(out) || U2.is_alias(out) || U3.is_alias(out) || U4.is_alias(out); + const bool alias = (check_alias) && (U1.is_alias(out) || U2.is_alias(out) || U3.is_alias(out) || U4.is_alias(out)); if(alias == false) { @@ -544,7 +549,23 @@ glue_times::apply(Mat& out, const Glue arma_debug_print(arma_str::format("glue_times::apply(): N_mat: %u") % N_mat); - glue_times_redirect::apply(out, X); + glue_times_redirect::apply(out, X); + } + + + +template +inline +void +glue_times::apply(Mat_noalias& out, const Glue& X) + { + arma_debug_sigprint(); + + constexpr uword N_mat = 1 + depth_lhs< glue_times, Glue >::num; + + arma_debug_print(arma_str::format("glue_times::apply(): N_mat: %u") % N_mat); + + glue_times_redirect::apply(out, X); }