From 0c8e97e10eb24f3982bb703f980cafc6f91eaea6 Mon Sep 17 00:00:00 2001 From: conrad Date: Thu, 7 Aug 2025 16:02:57 +1000 Subject: [PATCH] use type promotion only where necessary --- include/armadillo_bits/op_norm_meat.hpp | 207 ++++++++++++++---------- 1 file changed, 118 insertions(+), 89 deletions(-) diff --git a/include/armadillo_bits/op_norm_meat.hpp b/include/armadillo_bits/op_norm_meat.hpp index 57b2280a..f239cc1a 100644 --- a/include/armadillo_bits/op_norm_meat.hpp +++ b/include/armadillo_bits/op_norm_meat.hpp @@ -40,9 +40,7 @@ op_norm::vec_norm_1(const Proxy& P, const typename arma_not_cx::value, eT, float>::result acc_eT; - - acc_eT acc = acc_eT(0); + eT acc = eT(0); if(Proxy::use_at == false) { @@ -50,22 +48,22 @@ op_norm::vec_norm_1(const Proxy& P, const typename arma_not_cx& P, const typename arma_not_cx& P, const typename arma_not_cx& P, const typename arma_cx_only::value, eT, float>::result acc_eT; - - typedef typename get_pod_type::result acc_T; - - acc_T acc = acc_T(0); + T acc = T(0); if(Proxy::use_at == false) { @@ -139,7 +133,7 @@ op_norm::vec_norm_1(const Proxy& P, const typename arma_cx_only& P, const typename arma_cx_only& P, const typename arma_cx_only::result acc_eT; + + typedef typename get_pod_type::result acc_T; + const quasi_unwrap::stored_type> R(P.Q); const uword N = R.M.n_elem; @@ -232,7 +230,7 @@ op_norm::vec_norm_1_direct_std(const Mat& X, const typename arma_blas_real_o const eT* A = X.memptr(); eT out_val = eT(0); - + #if defined(ARMA_USE_ATLAS) { arma_debug_print("atlas::cblas_asum()"); @@ -287,36 +285,34 @@ op_norm::vec_norm_1_direct_mem(const uword N, const eT* A) { arma_debug_sigprint(); - typedef typename conditional_promote_type::value, eT, float>::result acc_eT; - #if (defined(ARMA_SIMPLE_LOOPS) || defined(__FAST_MATH__)) { - acc_eT acc1 = acc_eT(0); + eT acc1 = eT(0); if(memory::is_aligned(A)) { memory::mark_as_aligned(A); - for(uword i=0; i& P, const typename arma_not_cx::value, eT, float>::result acc_eT; - - acc_eT acc = acc_eT(0); + eT acc = eT(0); if(Proxy::use_at == false) { @@ -363,8 +357,8 @@ op_norm::vec_norm_2(const Proxy& P, const typename arma_not_cx& P, const typename arma_not_cx& P, const typename arma_not_cx& P, const typename arma_not_cx& P, const typename arma_cx_only::value, eT, float>::result acc_eT; - - typedef typename get_pod_type::result acc_T; - - acc_T acc = acc_T(0); + T acc = T(0); if(Proxy::use_at == false) { @@ -473,7 +467,7 @@ op_norm::vec_norm_2(const Proxy& P, const typename arma_cx_only& P, const typename arma_cx_only& P, const typename arma_cx_only::result acc_eT; + + typedef typename get_pod_type::result acc_T; + const quasi_unwrap::stored_type> R(P.Q); const uword N = R.M.n_elem; @@ -606,13 +604,13 @@ op_norm::vec_norm_2_direct_std(const Mat& X, const typename arma_fp16_real_o { arma_debug_sigprint(); arma_ignore(junk); - + const uword N = X.n_elem; const eT* A = X.memptr(); - + // fp16 support must be non-BLAS eT out_val = op_norm::vec_norm_2_direct_mem(N,A); - + if( (out_val != eT(0)) && arma_isfinite(out_val) ) { return (out_val < eT(0)) ? eT(0) : out_val; @@ -620,7 +618,7 @@ op_norm::vec_norm_2_direct_std(const Mat& X, const typename arma_fp16_real_o else { arma_debug_print("detected possible underflow or overflow"); - + return op_norm::vec_norm_2_direct_robust(X); } } @@ -634,31 +632,29 @@ op_norm::vec_norm_2_direct_mem(const uword N, const eT* A) { arma_debug_sigprint(); - typedef typename conditional_promote_type::value, eT, float>::result acc_eT; - - acc_eT acc = acc_eT(0); + eT acc = eT(0); #if (defined(ARMA_SIMPLE_LOOPS) || defined(__FAST_MATH__)) { - acc_eT acc1 = acc_eT(0); + eT acc1 = eT(0); if(memory::is_aligned(A)) { memory::mark_as_aligned(A); - for(uword i=0; i& X) { arma_debug_sigprint(); - typedef typename conditional_promote_type::value, eT, float>::result acc_eT; + typedef typename promote_type::result acc_eT; const uword N = X.n_elem; - const eT* A = X.memptr(); + + if(is_fp16::yes) + { + // try straightforward type promotion before the default slow algorithm + + const eT* X_mem = X.memptr(); + + acc_eT acc1 = acc_eT(0); + acc_eT acc2 = acc_eT(0); + + uword j; + + for(j=1; j(); @@ -737,15 +766,15 @@ op_norm::vec_norm_2_direct_robust(const Mat& X) val_i /= max_val; val_j /= max_val; - acc1 += val_i * val_i; - acc2 += val_j * val_j; + acc1 += (val_i * val_i); + acc2 += (val_j * val_j); } if((j-1) < N) { const acc_eT val_i = acc_eT(*B) / max_val; - acc1 += val_i * val_i; + acc1 += (val_i * val_i); } const acc_eT out_val = std::sqrt(acc1 + acc2) * max_val;