diff --git a/include/armadillo_bits/mul_herk.hpp b/include/armadillo_bits/mul_herk.hpp index 61c236c1..59afb4ad 100644 --- a/include/armadillo_bits/mul_herk.hpp +++ b/include/armadillo_bits/mul_herk.hpp @@ -484,7 +484,26 @@ class herk { herk::apply_blas_type(C,A,alpha,beta); } - + + + + #if defined(ARMA_HAVE_FP16) + template + arma_inline + static + void + apply + ( + Mat< std::complex >& C, + const TA& A, + const fp16 alpha = fp16(1), + const fp16 beta = fp16(0) + ) + { + herk_emul::apply(C,A,alpha,beta); + } + #endif + }; diff --git a/include/armadillo_bits/op_dot_bones.hpp b/include/armadillo_bits/op_dot_bones.hpp index c8e05bad..80988eab 100644 --- a/include/armadillo_bits/op_dot_bones.hpp +++ b/include/armadillo_bits/op_dot_bones.hpp @@ -40,13 +40,13 @@ class op_dot template arma_hot inline static typename arma_blas_real_only::result direct_dot(const uword n_elem, const eT* const A, const eT* const B); - + template - arma_hot inline static typename arma_fp16_only::result + arma_hot inline static typename arma_blas_cx_only::result direct_dot(const uword n_elem, const eT* const A, const eT* const B); - + template - arma_hot inline static typename arma_cx_only::result + arma_hot inline static typename arma_fp16_real_or_cx_only::result direct_dot(const uword n_elem, const eT* const A, const eT* const B); template @@ -98,7 +98,7 @@ class op_cdot arma_hot inline static eT direct_cdot(const uword n_elem, const eT* const A, const eT* const B, const typename arma_blas_real_or_cx_only::result* junk = 0); template - arma_hot inline static eT direct_cdot(const uword n_elem, const eT* const A, const eT* const B, const typename arma_fp16_only::result* junk = 0); + arma_hot inline static eT direct_cdot(const uword n_elem, const eT* const A, const eT* const B, const typename arma_fp16_real_or_cx_only::result* junk = 0); template arma_hot inline static typename T1::elem_type apply (const T1& X, const T2& Y); diff --git a/include/armadillo_bits/op_dot_meat.hpp b/include/armadillo_bits/op_dot_meat.hpp index e857c666..f2ec7bee 100644 --- a/include/armadillo_bits/op_dot_meat.hpp +++ b/include/armadillo_bits/op_dot_meat.hpp @@ -98,7 +98,7 @@ op_dot::direct_dot_arma(const uword n_elem, const eT* const A, const eT* const B -//! for two arrays, floating-point version +//! for two arrays, float and double version template inline typename arma_blas_real_only::result @@ -129,23 +129,10 @@ op_dot::direct_dot(const uword n_elem, const eT* const A, const eT* const B) -//! for two arrays, fp16 version -template -inline -typename arma_fp16_only::result -op_dot::direct_dot(const uword n_elem, const eT* const A, const eT* const B) - { - arma_debug_sigprint(); - - return op_dot::direct_dot_arma(n_elem, A, B); - } - - - //! for two arrays, complex version template inline -typename arma_cx_only::result +typename arma_blas_cx_only::result op_dot::direct_dot(const uword n_elem, const eT* const A, const eT* const B) { if(n_elem <= 16u) { return op_dot::direct_dot_arma(n_elem, A, B); } @@ -171,6 +158,17 @@ op_dot::direct_dot(const uword n_elem, const eT* const A, const eT* const B) +//! for two arrays, fp16 version +template +inline +typename arma_fp16_real_or_cx_only::result +op_dot::direct_dot(const uword n_elem, const eT* const A, const eT* const B) + { + return op_dot::direct_dot_arma(n_elem, A, B); + } + + + //! for two arrays, integral version template inline @@ -502,7 +500,7 @@ op_cdot::direct_cdot(const uword n_elem, const eT* const A, const eT* const B, c template inline eT -op_cdot::direct_cdot(const uword n_elem, const eT* const A, const eT* const B, const typename arma_fp16_only::result* junk) +op_cdot::direct_cdot(const uword n_elem, const eT* const A, const eT* const B, const typename arma_fp16_real_or_cx_only::result* junk) { arma_debug_sigprint(); arma_ignore(junk); diff --git a/include/armadillo_bits/op_norm_bones.hpp b/include/armadillo_bits/op_norm_bones.hpp index e415096e..6c9112c3 100644 --- a/include/armadillo_bits/op_norm_bones.hpp +++ b/include/armadillo_bits/op_norm_bones.hpp @@ -49,7 +49,7 @@ class op_norm template inline static typename get_pod_type::result mat_norm_1(const Mat& X); template inline static typename get_pod_type::result mat_norm_2(const Mat& X, const typename arma_blas_real_or_cx_only::result* junk = nullptr); - template inline static typename get_pod_type::result mat_norm_2(const Mat& X, const typename arma_fp16_only::result* junk = nullptr); + template inline static typename get_pod_type::result mat_norm_2(const Mat& X, const typename arma_fp16_real_or_cx_only::result* junk = nullptr); template inline static typename get_pod_type::result mat_norm_inf(const Mat& X); }; diff --git a/include/armadillo_bits/op_norm_meat.hpp b/include/armadillo_bits/op_norm_meat.hpp index 62cfcdc3..e2b107fc 100644 --- a/include/armadillo_bits/op_norm_meat.hpp +++ b/include/armadillo_bits/op_norm_meat.hpp @@ -954,7 +954,7 @@ op_norm::mat_norm_2(const Mat& X, const typename arma_blas_real_or_cx_only inline typename get_pod_type::result -op_norm::mat_norm_2(const Mat& X, const typename arma_fp16_only::result* junk) +op_norm::mat_norm_2(const Mat& X, const typename arma_fp16_real_or_cx_only::result* junk) { arma_debug_sigprint(); arma_ignore(junk); diff --git a/include/armadillo_bits/restrictors.hpp b/include/armadillo_bits/restrictors.hpp index 827fd680..d2146140 100644 --- a/include/armadillo_bits/restrictors.hpp +++ b/include/armadillo_bits/restrictors.hpp @@ -40,11 +40,12 @@ template<> struct arma_scalar_only< ulng_t > { typedef ulng_t result; }; template<> struct arma_scalar_only< slng_t > { typedef slng_t result; }; template<> struct arma_scalar_only< float > { typedef float result; }; template<> struct arma_scalar_only< double > { typedef double result; }; -#if defined(ARMA_HAVE_FP16) -template<> struct arma_scalar_only< fp16 > { typedef fp16 result; }; -#endif template<> struct arma_scalar_only< cx_float > { typedef cx_float result; }; template<> struct arma_scalar_only< cx_double > { typedef cx_double result; }; +#if defined(ARMA_HAVE_FP16) +template<> struct arma_scalar_only< fp16 > { typedef fp16 result; }; +template<> struct arma_scalar_only< cx_fp16 > { typedef cx_fp16 result; }; +#endif @@ -92,11 +93,12 @@ template<> struct arma_signed_only< s64 > { typedef s64 result; }; template<> struct arma_signed_only< slng_t > { typedef slng_t result; }; template<> struct arma_signed_only< float > { typedef float result; }; template<> struct arma_signed_only< double > { typedef double result; }; -#if defined(ARMA_HAVE_FP16) -template<> struct arma_signed_only< fp16 > { typedef fp16 result; }; -#endif template<> struct arma_signed_only< cx_float > { typedef cx_float result; }; template<> struct arma_signed_only< cx_double > { typedef cx_double result; }; +#if defined(ARMA_HAVE_FP16) +template<> struct arma_signed_only< fp16 > { typedef fp16 result; }; +template<> struct arma_signed_only< cx_fp16 > { typedef cx_fp16 result; }; +#endif @@ -129,11 +131,12 @@ template struct arma_real_or_cx_only { }; template<> struct arma_real_or_cx_only< float > { typedef float result; }; template<> struct arma_real_or_cx_only< double > { typedef double result; }; -#if defined(ARMA_HAVE_FP16) -template<> struct arma_real_or_cx_only< fp16 > { typedef fp16 result; }; -#endif template<> struct arma_real_or_cx_only< cx_float > { typedef cx_float result; }; template<> struct arma_real_or_cx_only< cx_double > { typedef cx_double result; }; +#if defined(ARMA_HAVE_FP16) +template<> struct arma_real_or_cx_only< fp16 > { typedef fp16 result; }; +template<> struct arma_real_or_cx_only< cx_fp16 > { typedef cx_fp16 result; }; +#endif template struct arma_blas_real_or_cx_only { }; @@ -145,10 +148,37 @@ template<> struct arma_blas_real_or_cx_only< cx_double > { typedef cx_double res +template struct arma_fp16_real_or_cx_only { }; + +#if defined(ARMA_HAVE_FP16) +template<> struct arma_fp16_real_or_cx_only< fp16 > { typedef fp16 result; }; +template<> struct arma_fp16_real_or_cx_only< cx_fp16 > { typedef cx_fp16 result; }; +#endif + + + template struct arma_cx_only { }; template<> struct arma_cx_only< cx_float > { typedef cx_float result; }; template<> struct arma_cx_only< cx_double > { typedef cx_double result; }; +#if defined(ARMA_HAVE_FP16) +template<> struct arma_cx_only< cx_fp16 > { typedef cx_fp16 result; }; +#endif + + + +template struct arma_blas_cx_only { }; + +template<> struct arma_blas_real_only< cx_float > { typedef cx_float result; }; +template<> struct arma_blas_real_only< cx_double > { typedef cx_double result; }; + + + +template struct arma_cx_fp16_only { }; + +#if defined(ARMA_HAVE_FP16) +template<> struct arma_cx_fp16_only< cx_fp16 > { typedef cx_fp16 result; }; +#endif diff --git a/include/armadillo_bits/traits.hpp b/include/armadillo_bits/traits.hpp index b560b6df..11264837 100644 --- a/include/armadillo_bits/traits.hpp +++ b/include/armadillo_bits/traits.hpp @@ -1119,6 +1119,26 @@ struct is_cx_double< std::complex > +template +struct is_cx_fp16 + { + static constexpr bool value = false; + static constexpr bool yes = false; + static constexpr bool no = true; + }; + +#ifdef ARMA_HAVE_FP16 +template<> +struct is_cx_fp16< std::complex > + { + static constexpr bool value = true; + static constexpr bool yes = true; + static constexpr bool no = false; + }; +#endif + + + template struct is_supported_elem_type { @@ -1137,7 +1157,8 @@ struct is_supported_elem_type is_double::value || is_fp16::value || is_cx_float::value || - is_cx_double::value; + is_cx_double::value || + is_cx_fp16::value; }; @@ -1194,6 +1215,7 @@ template<> struct is_non_integral< std::complex > { static constexpr boo #if defined(ARMA_HAVE_FP16) template<> struct is_non_integral< fp16 > { static constexpr bool value = true; }; +template<> struct is_non_integral< std::complex > { static constexpr bool value = true; }; #endif diff --git a/include/armadillo_bits/typedef_elem.hpp b/include/armadillo_bits/typedef_elem.hpp index 3d924fc4..4ee60955 100644 --- a/include/armadillo_bits/typedef_elem.hpp +++ b/include/armadillo_bits/typedef_elem.hpp @@ -154,7 +154,8 @@ typedef void* void_ptr; #if defined(ARMA_FORCE_USE_FP16) || defined(ARMA_GOOD_FP16) #define ARMA_HAVE_FP16 - typedef std::float16_t fp16; + typedef std::float16_t fp16; + typedef std::complex cx_fp16; #endif #if defined(ARMA_FORCE_USE_FP16) && !defined(ARMA_GOOD_FP16) diff --git a/include/armadillo_bits/typedef_mat.hpp b/include/armadillo_bits/typedef_mat.hpp index de8567d0..7a07c77e 100644 --- a/include/armadillo_bits/typedef_mat.hpp +++ b/include/armadillo_bits/typedef_mat.hpp @@ -104,6 +104,12 @@ typedef Col fp16_vec; typedef Col fp16_colvec; typedef Row fp16_rowvec; typedef Cube fp16_cube; + +typedef Mat cx_fp16_mat; +typedef Col cx_fp16_vec; +typedef Col cx_fp16_colvec; +typedef Row cx_fp16_rowvec; +typedef Cube cx_fp16_cube; #endif @@ -153,6 +159,11 @@ typedef SpMat sp_fp16_mat; typedef SpCol sp_fp16_vec; typedef SpCol sp_fp16_colvec; typedef SpRow sp_fp16_rowvec; + +typedef SpMat sp_cx_fp16_mat; +typedef SpCol sp_cx_fp16_vec; +typedef SpCol sp_cx_fp16_colvec; +typedef SpRow sp_cx_fp16_rowvec; #endif