avoid unnecessary alias checks

This commit is contained in:
conrad
2025-10-09 11:47:00 +10:00
parent 27f50ccc77
commit f44ddefe87
4 changed files with 162 additions and 0 deletions
+12
View File
@@ -34,9 +34,21 @@ struct op_sum
template<typename T1>
inline static void apply(Mat<typename T1::elem_type>& out, const Op< eOp<T1,eop_pow >, op_sum >& in);
template<typename T1>
inline static void apply(Mat_noalias<typename T1::elem_type>& out, const Op< T1, op_sum >& in);
template<typename T1>
inline static void apply(Mat_noalias<typename T1::elem_type>& out, const Op< eOp<T1,eop_square>, op_sum >& in);
template<typename T1>
inline static void apply(Mat_noalias<typename T1::elem_type>& out, const Op< eOp<T1,eop_pow >, op_sum >& in);
template<typename T1>
inline static void apply_generic(Mat<typename T1::elem_type>& out, const Op<T1,op_sum>& in);
template<typename T1>
inline static void apply_generic(Mat_noalias<typename T1::elem_type>& out, const Op<T1,op_sum>& in);
template<typename eT>
inline static void apply_mat_noalias(Mat<eT>& out, const Mat<eT>& X, const uword dim);
+100
View File
@@ -158,6 +158,106 @@ op_sum::apply_generic(Mat<typename T1::elem_type>& out, const Op<T1,op_sum>& in)
template<typename T1>
inline
void
op_sum::apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1,op_sum>& in)
{
arma_debug_sigprint();
op_sum::apply_generic(out, in);
}
template<typename T1>
inline
void
op_sum::apply(Mat_noalias<typename T1::elem_type>& out, const Op< eOp<T1,eop_square>, op_sum >& in)
{
arma_debug_sigprint();
typedef eOp<T1,eop_square> inner_expr_type;
typedef typename inner_expr_type::proxy_type::stored_type inner_expr_P_stored_type;
if(is_Mat<inner_expr_P_stored_type>::value)
{
const uword dim = in.aux_uword_a;
arma_conform_check( (dim > 1), "sum(): parameter 'dim' must be 0 or 1" );
const quasi_unwrap<inner_expr_P_stored_type> U(in.m.P.Q);
op_sum::apply_mat_square_noalias(out, U.M, dim);
return;
}
op_sum::apply_generic(out, in);
}
template<typename T1>
inline
void
op_sum::apply(Mat_noalias<typename T1::elem_type>& out, const Op< eOp<T1,eop_pow>, op_sum >& in)
{
arma_debug_sigprint();
typedef typename T1::elem_type eT;
if(arma_config::optimise_powexpr && (in.m.aux == eT(2)))
{
typedef Op< eOp<T1,eop_square>, op_sum > modified_whole_expr_type;
op_sum::apply(out, reinterpret_cast<const modified_whole_expr_type& >(in) );
return;
}
if(arma_config::optimise_powexpr && (in.m.aux == eT(0.5)) && is_real_or_cx<eT>::value)
{
typedef Op< eOp<T1,eop_sqrt>, op_sum > modified_whole_expr_type;
op_sum::apply(out, reinterpret_cast<const modified_whole_expr_type& >(in) );
return;
}
op_sum::apply_generic(out, in);
}
template<typename T1>
inline
void
op_sum::apply_generic(Mat_noalias<typename T1::elem_type>& out, const Op<T1,op_sum>& in)
{
arma_debug_sigprint();
const uword dim = in.aux_uword_a;
arma_conform_check( (dim > 1), "sum(): parameter 'dim' must be 0 or 1" );
if((quasi_unwrap<T1>::has_orig_mem) || (is_Mat<typename Proxy<T1>::stored_type>::value) || (arma_config::openmp && Proxy<T1>::use_mp))
{
const quasi_unwrap<T1> U(in.m);
op_sum::apply_mat_noalias(out, U.M, dim);
}
else
{
const Proxy<T1> P(in.m);
op_sum::apply_proxy_noalias(out, P, dim);
}
}
template<typename eT>
inline
void
@@ -29,6 +29,10 @@ struct op_vectorise_col
template<typename T1> inline static void apply_direct(Mat<typename T1::elem_type>& out, const T1& expr);
template<typename T1> inline static void apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1,op_vectorise_col>& in);
template<typename T1> inline static void apply_direct(Mat_noalias<typename T1::elem_type>& out, const T1& expr);
template<typename eT> inline static void apply_subview(Mat<eT>& out, const subview<eT>& sv);
template<typename T1> inline static void apply_proxy(Mat<typename T1::elem_type>& out, const Proxy<T1>& P);
@@ -118,6 +118,52 @@ op_vectorise_col::apply_direct(Mat<typename T1::elem_type>& out, const T1& expr)
template<typename T1>
inline
void
op_vectorise_col::apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1,op_vectorise_col>& in)
{
arma_debug_sigprint();
op_vectorise_col::apply_direct(out, in.m);
}
template<typename T1>
inline
void
op_vectorise_col::apply_direct(Mat_noalias<typename T1::elem_type>& out, const T1& expr)
{
arma_debug_sigprint();
typedef typename T1::elem_type eT;
if(is_subview<T1>::value)
{
const subview<eT>& sv = reinterpret_cast< const subview<eT>& >(expr);
op_vectorise_col::apply_subview(out, sv);
}
else
if( (quasi_unwrap<T1>::has_orig_mem) || (is_Mat<typename Proxy<T1>::stored_type>::value) || (arma_config::openmp && Proxy<T1>::use_mp) )
{
const quasi_unwrap<T1> U(expr);
out.set_size(U.M.n_elem, 1);
arrayops::copy(out.memptr(), U.M.memptr(), U.M.n_elem);
}
else
{
const Proxy<T1> P(expr);
op_vectorise_col::apply_proxy(out, P);
}
}
template<typename eT>
inline
void