11#ifndef EIGEN_REDUCTIONS_AVX512_H
12#define EIGEN_REDUCTIONS_AVX512_H
15#include "../../InternalHeaderCheck.h"
22EIGEN_STRONG_INLINE
bool avx512_predux_any(
const Packet16i& bits) {
return _mm512_test_epi32_mask(bits, bits) != 0; }
27EIGEN_STRONG_INLINE
int predux(
const Packet16i& a) {
28 return _mm512_reduce_add_epi32(a);
32EIGEN_STRONG_INLINE
int predux_mul(
const Packet16i& a) {
33 return _mm512_reduce_mul_epi32(a);
37EIGEN_STRONG_INLINE
int predux_min(
const Packet16i& a) {
38 return _mm512_reduce_min_epi32(a);
42EIGEN_STRONG_INLINE
int predux_max(
const Packet16i& a) {
43 return _mm512_reduce_max_epi32(a);
47EIGEN_STRONG_INLINE
bool predux_any(
const Packet16i& a) {
48 return avx512_predux_any(a);
52EIGEN_STRONG_INLINE
bool predux_all(
const Packet16i& a) {
53 return _mm512_cmp_epi32_mask(a, _mm512_setzero_epi32(), _MM_CMPINT_EQ) == 0;
59EIGEN_STRONG_INLINE int64_t predux(
const Packet8l& a) {
60 return _mm512_reduce_add_epi64(a);
70EIGEN_STRONG_INLINE int64_t predux_mul(
const Packet8l& a) {
71 Packet4l lane0 = _mm512_extracti64x4_epi64(a, 0);
72 Packet4l lane1 = _mm512_extracti64x4_epi64(a, 1);
73 return predux_mul(pmul(lane0, lane1));
77EIGEN_STRONG_INLINE int64_t predux_mul<Packet8l>(
const Packet8l& a) {
78 return _mm512_reduce_mul_epi64(a);
83EIGEN_STRONG_INLINE int64_t predux_min(
const Packet8l& a) {
84 return _mm512_reduce_min_epi64(a);
88EIGEN_STRONG_INLINE int64_t predux_max(
const Packet8l& a) {
89 return _mm512_reduce_max_epi64(a);
93EIGEN_STRONG_INLINE
bool predux_any(
const Packet8l& a) {
94 return avx512_predux_any(a);
98EIGEN_STRONG_INLINE
bool predux_all(
const Packet8l& a) {
99 return _mm512_cmp_epi64_mask(a, _mm512_setzero_si512(), _MM_CMPINT_EQ) == 0;
105EIGEN_STRONG_INLINE
float predux(
const Packet16f& a) {
106 return _mm512_reduce_add_ps(a);
110EIGEN_STRONG_INLINE
float predux_mul(
const Packet16f& a) {
111 return _mm512_reduce_mul_ps(a);
115EIGEN_STRONG_INLINE
float predux_min(
const Packet16f& a) {
116 return _mm512_reduce_min_ps(a);
120EIGEN_STRONG_INLINE
float predux_min<PropagateNumbers>(
const Packet16f& a) {
121 Packet8f lane0 = _mm512_extractf32x8_ps(a, 0);
122 Packet8f lane1 = _mm512_extractf32x8_ps(a, 1);
123 return predux_min<PropagateNumbers>(pmin<PropagateNumbers>(lane0, lane1));
127EIGEN_STRONG_INLINE
float predux_min<PropagateNaN>(
const Packet16f& a) {
128 Packet8f lane0 = _mm512_extractf32x8_ps(a, 0);
129 Packet8f lane1 = _mm512_extractf32x8_ps(a, 1);
130 return predux_min<PropagateNaN>(pmin<PropagateNaN>(lane0, lane1));
134EIGEN_STRONG_INLINE
float predux_max(
const Packet16f& a) {
135 return _mm512_reduce_max_ps(a);
139EIGEN_STRONG_INLINE
float predux_max<PropagateNumbers>(
const Packet16f& a) {
140 Packet8f lane0 = _mm512_extractf32x8_ps(a, 0);
141 Packet8f lane1 = _mm512_extractf32x8_ps(a, 1);
142 return predux_max<PropagateNumbers>(pmax<PropagateNumbers>(lane0, lane1));
146EIGEN_STRONG_INLINE
float predux_max<PropagateNaN>(
const Packet16f& a) {
147 Packet8f lane0 = _mm512_extractf32x8_ps(a, 0);
148 Packet8f lane1 = _mm512_extractf32x8_ps(a, 1);
149 return predux_max<PropagateNaN>(pmax<PropagateNaN>(lane0, lane1));
153EIGEN_STRONG_INLINE
bool predux_any(
const Packet16f& a) {
154 return avx512_predux_any(_mm512_castps_si512(a));
158EIGEN_STRONG_INLINE
bool predux_all(
const Packet16f& a) {
159 return _mm512_cmp_ps_mask(a, _mm512_setzero_ps(), _CMP_EQ_OQ) == 0;
163EIGEN_STRONG_INLINE Index predux_count(
const Packet16f& a) {
164 return Index(popcount(
static_cast<unsigned int>(_mm512_cmp_ps_mask(a, _mm512_setzero_ps(), _CMP_NEQ_UQ))));
170EIGEN_STRONG_INLINE
double predux(
const Packet8d& a) {
171 return _mm512_reduce_add_pd(a);
175EIGEN_STRONG_INLINE
double predux_mul(
const Packet8d& a) {
176 return _mm512_reduce_mul_pd(a);
180EIGEN_STRONG_INLINE
double predux_min(
const Packet8d& a) {
181 return _mm512_reduce_min_pd(a);
185EIGEN_STRONG_INLINE
double predux_min<PropagateNumbers>(
const Packet8d& a) {
186 Packet4d lane0 = _mm512_extractf64x4_pd(a, 0);
187 Packet4d lane1 = _mm512_extractf64x4_pd(a, 1);
188 return predux_min<PropagateNumbers>(pmin<PropagateNumbers>(lane0, lane1));
192EIGEN_STRONG_INLINE
double predux_min<PropagateNaN>(
const Packet8d& a) {
193 Packet4d lane0 = _mm512_extractf64x4_pd(a, 0);
194 Packet4d lane1 = _mm512_extractf64x4_pd(a, 1);
195 return predux_min<PropagateNaN>(pmin<PropagateNaN>(lane0, lane1));
199EIGEN_STRONG_INLINE
double predux_max(
const Packet8d& a) {
200 return _mm512_reduce_max_pd(a);
204EIGEN_STRONG_INLINE
double predux_max<PropagateNumbers>(
const Packet8d& a) {
205 Packet4d lane0 = _mm512_extractf64x4_pd(a, 0);
206 Packet4d lane1 = _mm512_extractf64x4_pd(a, 1);
207 return predux_max<PropagateNumbers>(pmax<PropagateNumbers>(lane0, lane1));
211EIGEN_STRONG_INLINE
double predux_max<PropagateNaN>(
const Packet8d& a) {
212 Packet4d lane0 = _mm512_extractf64x4_pd(a, 0);
213 Packet4d lane1 = _mm512_extractf64x4_pd(a, 1);
214 return predux_max<PropagateNaN>(pmax<PropagateNaN>(lane0, lane1));
218EIGEN_STRONG_INLINE
bool predux_any(
const Packet8d& a) {
219 return avx512_predux_any(_mm512_castpd_si512(a));
223EIGEN_STRONG_INLINE
bool predux_all(
const Packet8d& a) {
224 return _mm512_cmp_pd_mask(a, _mm512_setzero_pd(), _CMP_EQ_OQ) == 0;
228EIGEN_STRONG_INLINE Index predux_count(
const Packet8d& a) {
229 return Index(popcount(
static_cast<unsigned int>(_mm512_cmp_pd_mask(a, _mm512_setzero_pd(), _CMP_NEQ_UQ))));
233EIGEN_STRONG_INLINE Index predux_count_16bit(
const __m256i& a) {
234#if defined(EIGEN_VECTORIZE_AVX512VL) && defined(__AVX512BW__)
236 const unsigned int nonzero_lanes =
static_cast<unsigned int>(_mm256_test_epi16_mask(a, _mm256_set1_epi16(0x7fff)));
237 return Index(popcount(nonzero_lanes));
239 const __m256i magnitude = _mm256_and_si256(a, _mm256_set1_epi16(0x7fff));
240 const __m256i zeros = _mm256_cmpeq_epi16(magnitude, _mm256_setzero_si256());
241 const unsigned int zero_bytes =
static_cast<unsigned int>(_mm256_movemask_epi8(zeros));
242 return Index(16 - popcount(zero_bytes) / 2);
246#ifndef EIGEN_VECTORIZE_AVX512FP16
250EIGEN_STRONG_INLINE half predux(
const Packet16h& from) {
251 return half(predux(half2float(from)));
255EIGEN_STRONG_INLINE half predux_mul(
const Packet16h& from) {
256 return half(predux_mul(half2float(from)));
260EIGEN_STRONG_INLINE half predux_min(
const Packet16h& from) {
261 return half(predux_min(half2float(from)));
265EIGEN_STRONG_INLINE half predux_min<PropagateNumbers>(
const Packet16h& from) {
266 return half(predux_min<PropagateNumbers>(half2float(from)));
270EIGEN_STRONG_INLINE half predux_min<PropagateNaN>(
const Packet16h& from) {
271 return half(predux_min<PropagateNaN>(half2float(from)));
275EIGEN_STRONG_INLINE half predux_max(
const Packet16h& from) {
276 return half(predux_max(half2float(from)));
280EIGEN_STRONG_INLINE half predux_max<PropagateNumbers>(
const Packet16h& from) {
281 return half(predux_max<PropagateNumbers>(half2float(from)));
285EIGEN_STRONG_INLINE half predux_max<PropagateNaN>(
const Packet16h& from) {
286 return half(predux_max<PropagateNaN>(half2float(from)));
290EIGEN_STRONG_INLINE
bool predux_any(
const Packet16h& a) {
291 return predux_any<Packet8i>(a.m_val);
295EIGEN_STRONG_INLINE
bool predux_all(
const Packet16h& a) {
296 return predux_count_16bit(a.m_val) == 16;
300EIGEN_STRONG_INLINE Index predux_count(
const Packet16h& a) {
301 return predux_count_16bit(a.m_val);
308EIGEN_STRONG_INLINE bfloat16 predux(
const Packet16bf& from) {
309 return static_cast<bfloat16
>(predux<Packet16f>(Bf16ToF32(from)));
313EIGEN_STRONG_INLINE bfloat16 predux_mul(
const Packet16bf& from) {
314 return static_cast<bfloat16
>(predux_mul<Packet16f>(Bf16ToF32(from)));
318EIGEN_STRONG_INLINE bfloat16 predux_min(
const Packet16bf& from) {
319 return static_cast<bfloat16
>(predux_min<Packet16f>(Bf16ToF32(from)));
323EIGEN_STRONG_INLINE bfloat16 predux_min<PropagateNumbers>(
const Packet16bf& from) {
324 return static_cast<bfloat16
>(predux_min<PropagateNumbers>(Bf16ToF32(from)));
328EIGEN_STRONG_INLINE bfloat16 predux_min<PropagateNaN>(
const Packet16bf& from) {
329 return static_cast<bfloat16
>(predux_min<PropagateNaN>(Bf16ToF32(from)));
333EIGEN_STRONG_INLINE bfloat16 predux_max(
const Packet16bf& from) {
334 return static_cast<bfloat16
>(predux_max(Bf16ToF32(from)));
338EIGEN_STRONG_INLINE bfloat16 predux_max<PropagateNumbers>(
const Packet16bf& from) {
339 return static_cast<bfloat16
>(predux_max<PropagateNumbers>(Bf16ToF32(from)));
343EIGEN_STRONG_INLINE bfloat16 predux_max<PropagateNaN>(
const Packet16bf& from) {
344 return static_cast<bfloat16
>(predux_max<PropagateNaN>(Bf16ToF32(from)));
348EIGEN_STRONG_INLINE
bool predux_any(
const Packet16bf& a) {
349 return predux_any<Packet8i>(a.m_val);
353EIGEN_STRONG_INLINE
bool predux_all(
const Packet16bf& a) {
354 return predux_count_16bit(a.m_val) == 16;
358EIGEN_STRONG_INLINE Index predux_count(
const Packet16bf& a) {
359 return predux_count_16bit(a.m_val);