Add support for hypot function
Hi again Klaus!
I hope things are well with you. I just added the hypot function to our code base for use with Blaze and thought I'd share the implementation so that you can tweak it and add it to Blaze. Thanks!
namespace blaze {
template <typename T0, typename T1>
BLAZE_ALWAYS_INLINE const SIMDfloat hypot(const SIMDf32<T0>& a,
const SIMDf32<T1>& b) noexcept
#if BLAZE_SVML_MODE && (BLAZE_AVX512F_MODE || BLAZE_MIC_MODE)
{
return _mm512_hypot_ps((~a).eval().value, (~b).eval().value);
}
#elif BLAZE_SVML_MODE && BLAZE_AVX_MODE
{
return _mm256_hypot_ps((~a).eval().value, (~b).eval().value);
}
#elif BLAZE_SVML_MODE && BLAZE_SSE_MODE
{
return _mm_hypot_ps((~a).eval().value, (~b).eval().value);
}
#else
= delete;
#endif
template <typename T0, typename T1>
BLAZE_ALWAYS_INLINE const SIMDdouble hypot(const SIMDf64<T0>& a,
const SIMDf64<T1>& b) noexcept
#if BLAZE_SVML_MODE && (BLAZE_AVX512F_MODE || BLAZE_MIC_MODE)
{
return _mm512_hypot_pd((~a).eval().value, (~b).eval().value);
}
#elif BLAZE_SVML_MODE && BLAZE_AVX_MODE
{
return _mm256_hypot_pd((~a).eval().value, (~b).eval().value);
}
#elif BLAZE_SVML_MODE && BLAZE_SSE_MODE
{
return _mm_hypot_pd((~a).eval().value, (~b).eval().value);
}
#else
= delete;
#endif
template <typename T0, typename T1>
using HasSIMDHypot = std::integral_constant<
bool, std::is_same<std::decay_t<T0>, std::decay_t<T1>>::value and
std::is_arithmetic<std::decay_t<T0>>::value and bool( // NOLINT
BLAZE_SVML_MODE) and // NOLINT
(bool(BLAZE_SSE_MODE) || bool(BLAZE_AVX_MODE) || // NOLINT
bool(BLAZE_MIC_MODE) || bool(BLAZE_AVX512F_MODE))>; // NOLINT
struct Hypot {
template <typename T1, typename T2>
BLAZE_ALWAYS_INLINE decltype(auto) operator()(const T1& a, const T2& b) const
noexcept {
using std::hypot;
return hypot(a, b);
}
template <typename T1, typename T2>
static constexpr bool simdEnabled() noexcept {
return HasSIMDHypot<T1, T2>::value;
}
template <typename T1, typename T2>
BLAZE_ALWAYS_INLINE decltype(auto) load(const T1& a, const T2& b) const
noexcept {
using std::hypot;
BLAZE_CONSTRAINT_MUST_BE_SIMD_PACK(T1);
BLAZE_CONSTRAINT_MUST_BE_SIMD_PACK(T2);
return hypot(a, b);
}
};
} // namespace blaze
template <typename VT0, typename VT1, bool TF>
BLAZE_ALWAYS_INLINE decltype(auto) hypot(
const blaze::DenseVector<VT0, TF>& y,
const blaze::DenseVector<VT1, TF>& x) noexcept {
return map(~y, ~x, blaze::Hypot{});
}
Best,
Nils
Comments (5)
-
-
reporter Hi Klaus!
You're welcome :) Thank you very much for the quick response!
Cheers,
Nils
-
-
assigned issue to
-
assigned issue to
-
- changed status to open
-
- changed status to resolved
Summary
The feature has been implemented, tested, optimized, and documented as required. It is immediately available via cloning the Blaze repository and will be officially released in Blaze 3.3.
The hypot() Function
The
hypot()
function can be used to compute the componentwise hypotenous for a pair of dense vectors:blaze::StaticVector<double,3UL> a, b, c; c = hypot( a, b ); // Computes the componentwise hypotenuous
blaze::StaticMatrix<double,3UL,3UL> A, B, C; C = hypot( A, B ); // Computes the componentwise hypotenuous
The operation is vectorized for SSE, AVX, and AVX-512 via the SVML. Additionally, the operation runs in parallel for large enough vectors and matrices (see for instance the OpenMP configuration).
- Log in to comment
Hi Nils!
Thanks a lot for this perfect support :-) We will integrate this as soon as possible and definitely before the release of Blaze 3.3.
Best regards,
Klaus!