11#ifndef EIGEN_REDUCTIONS_AVX_H
12#define EIGEN_REDUCTIONS_AVX_H
15#include "../../InternalHeaderCheck.h"
24EIGEN_STRONG_INLINE
int predux(
const Packet8i& a) {
25 Packet4i lo = _mm256_castsi256_si128(a);
26 Packet4i hi = _mm256_extractf128_si256(a, 1);
27 return predux(padd(lo, hi));
31EIGEN_STRONG_INLINE
int predux_mul(
const Packet8i& a) {
32 Packet4i lo = _mm256_castsi256_si128(a);
33 Packet4i hi = _mm256_extractf128_si256(a, 1);
34 return predux_mul(pmul(lo, hi));
38EIGEN_STRONG_INLINE
int predux_min(
const Packet8i& a) {
39 Packet4i lo = _mm256_castsi256_si128(a);
40 Packet4i hi = _mm256_extractf128_si256(a, 1);
41 return predux_min(pmin(lo, hi));
45EIGEN_STRONG_INLINE
int predux_max(
const Packet8i& a) {
46 Packet4i lo = _mm256_castsi256_si128(a);
47 Packet4i hi = _mm256_extractf128_si256(a, 1);
48 return predux_max(pmax(lo, hi));
52EIGEN_STRONG_INLINE
bool predux_any(
const Packet8i& a) {
53#ifdef EIGEN_VECTORIZE_AVX2
54 return _mm256_movemask_epi8(a) != 0x0;
56 return _mm256_movemask_ps(_mm256_castsi256_ps(a)) != 0x0;
63EIGEN_STRONG_INLINE uint32_t predux(
const Packet8ui& a) {
64 Packet4ui lo = _mm256_castsi256_si128(a);
65 Packet4ui hi = _mm256_extractf128_si256(a, 1);
66 return predux(padd(lo, hi));
70EIGEN_STRONG_INLINE uint32_t predux_mul(
const Packet8ui& a) {
71 Packet4ui lo = _mm256_castsi256_si128(a);
72 Packet4ui hi = _mm256_extractf128_si256(a, 1);
73 return predux_mul(pmul(lo, hi));
77EIGEN_STRONG_INLINE uint32_t predux_min(
const Packet8ui& a) {
78 Packet4ui lo = _mm256_castsi256_si128(a);
79 Packet4ui hi = _mm256_extractf128_si256(a, 1);
80 return predux_min(pmin(lo, hi));
84EIGEN_STRONG_INLINE uint32_t predux_max(
const Packet8ui& a) {
85 Packet4ui lo = _mm256_castsi256_si128(a);
86 Packet4ui hi = _mm256_extractf128_si256(a, 1);
87 return predux_max(pmax(lo, hi));
91EIGEN_STRONG_INLINE
bool predux_any(
const Packet8ui& a) {
92#ifdef EIGEN_VECTORIZE_AVX2
93 return _mm256_movemask_epi8(a) != 0x0;
95 return _mm256_movemask_ps(_mm256_castsi256_ps(a)) != 0x0;
99#ifdef EIGEN_VECTORIZE_AVX2
104EIGEN_STRONG_INLINE int64_t predux(
const Packet4l& a) {
105 Packet2l lo = _mm256_castsi256_si128(a);
106 Packet2l hi = _mm256_extractf128_si256(a, 1);
107 return predux(padd(lo, hi));
111EIGEN_STRONG_INLINE
bool predux_any(
const Packet4l& a) {
112 return _mm256_movemask_pd(_mm256_castsi256_pd(a)) != 0x0;
118EIGEN_STRONG_INLINE uint64_t predux(
const Packet4ul& a) {
119 return static_cast<uint64_t
>(predux(Packet4l(a)));
123EIGEN_STRONG_INLINE
bool predux_any(
const Packet4ul& a) {
124 return _mm256_movemask_pd(_mm256_castsi256_pd(a)) != 0x0;
132EIGEN_STRONG_INLINE
float predux(
const Packet8f& a) {
133 Packet4f lo = _mm256_castps256_ps128(a);
134 Packet4f hi = _mm256_extractf128_ps(a, 1);
135 return predux(padd(lo, hi));
139EIGEN_STRONG_INLINE
float predux_mul(
const Packet8f& a) {
140 Packet4f lo = _mm256_castps256_ps128(a);
141 Packet4f hi = _mm256_extractf128_ps(a, 1);
142 return predux_mul(pmul(lo, hi));
146EIGEN_STRONG_INLINE
float predux_min(
const Packet8f& a) {
147 Packet4f lo = _mm256_castps256_ps128(a);
148 Packet4f hi = _mm256_extractf128_ps(a, 1);
149 return predux_min(pmin(lo, hi));
153EIGEN_STRONG_INLINE
float predux_min<PropagateNumbers>(
const Packet8f& a) {
154 Packet4f lo = _mm256_castps256_ps128(a);
155 Packet4f hi = _mm256_extractf128_ps(a, 1);
156 return predux_min<PropagateNumbers>(pmin<PropagateNumbers>(lo, hi));
160EIGEN_STRONG_INLINE
float predux_min<PropagateNaN>(
const Packet8f& a) {
161 Packet4f lo = _mm256_castps256_ps128(a);
162 Packet4f hi = _mm256_extractf128_ps(a, 1);
163 return predux_min<PropagateNaN>(pmin<PropagateNaN>(lo, hi));
167EIGEN_STRONG_INLINE
float predux_max(
const Packet8f& a) {
168 Packet4f lo = _mm256_castps256_ps128(a);
169 Packet4f hi = _mm256_extractf128_ps(a, 1);
170 return predux_max(pmax(lo, hi));
174EIGEN_STRONG_INLINE
float predux_max<PropagateNumbers>(
const Packet8f& a) {
175 Packet4f lo = _mm256_castps256_ps128(a);
176 Packet4f hi = _mm256_extractf128_ps(a, 1);
177 return predux_max<PropagateNumbers>(pmax<PropagateNumbers>(lo, hi));
181EIGEN_STRONG_INLINE
float predux_max<PropagateNaN>(
const Packet8f& a) {
182 Packet4f lo = _mm256_castps256_ps128(a);
183 Packet4f hi = _mm256_extractf128_ps(a, 1);
184 return predux_max<PropagateNaN>(pmax<PropagateNaN>(lo, hi));
188EIGEN_STRONG_INLINE
bool predux_any(
const Packet8f& a) {
189 return _mm256_movemask_ps(a) != 0x0;
193EIGEN_STRONG_INLINE Index predux_count(
const Packet8f& a) {
194 const unsigned int mask =
195 static_cast<unsigned int>(_mm256_movemask_ps(_mm256_cmp_ps(a, _mm256_setzero_ps(), _CMP_NEQ_UQ)));
196 return Index(popcount(mask));
202EIGEN_STRONG_INLINE
double predux(
const Packet4d& a) {
203 Packet2d lo = _mm256_castpd256_pd128(a);
204 Packet2d hi = _mm256_extractf128_pd(a, 1);
205 return predux(padd(lo, hi));
209EIGEN_STRONG_INLINE
double predux_mul(
const Packet4d& a) {
210 Packet2d lo = _mm256_castpd256_pd128(a);
211 Packet2d hi = _mm256_extractf128_pd(a, 1);
212 return predux_mul(pmul(lo, hi));
216EIGEN_STRONG_INLINE
double predux_min(
const Packet4d& a) {
217 Packet2d lo = _mm256_castpd256_pd128(a);
218 Packet2d hi = _mm256_extractf128_pd(a, 1);
219 return predux_min(pmin(lo, hi));
223EIGEN_STRONG_INLINE
double predux_min<PropagateNumbers>(
const Packet4d& a) {
224 Packet2d lo = _mm256_castpd256_pd128(a);
225 Packet2d hi = _mm256_extractf128_pd(a, 1);
226 return predux_min<PropagateNumbers>(pmin<PropagateNumbers>(lo, hi));
230EIGEN_STRONG_INLINE
double predux_min<PropagateNaN>(
const Packet4d& a) {
231 Packet2d lo = _mm256_castpd256_pd128(a);
232 Packet2d hi = _mm256_extractf128_pd(a, 1);
233 return predux_min<PropagateNaN>(pmin<PropagateNaN>(lo, hi));
237EIGEN_STRONG_INLINE
double predux_max(
const Packet4d& a) {
238 Packet2d lo = _mm256_castpd256_pd128(a);
239 Packet2d hi = _mm256_extractf128_pd(a, 1);
240 return predux_max(pmax(lo, hi));
244EIGEN_STRONG_INLINE
double predux_max<PropagateNumbers>(
const Packet4d& a) {
245 Packet2d lo = _mm256_castpd256_pd128(a);
246 Packet2d hi = _mm256_extractf128_pd(a, 1);
247 return predux_max<PropagateNumbers>(pmax<PropagateNumbers>(lo, hi));
251EIGEN_STRONG_INLINE
double predux_max<PropagateNaN>(
const Packet4d& a) {
252 Packet2d lo = _mm256_castpd256_pd128(a);
253 Packet2d hi = _mm256_extractf128_pd(a, 1);
254 return predux_max<PropagateNaN>(pmax<PropagateNaN>(lo, hi));
258EIGEN_STRONG_INLINE
bool predux_any(
const Packet4d& a) {
259 return _mm256_movemask_pd(a) != 0x0;
263EIGEN_STRONG_INLINE Index predux_count(
const Packet4d& a) {
264 const unsigned int mask =
265 static_cast<unsigned int>(_mm256_movemask_pd(_mm256_cmp_pd(a, _mm256_setzero_pd(), _CMP_NEQ_UQ)));
266 return Index(popcount(mask));
270#ifndef EIGEN_VECTORIZE_AVX512FP16
273EIGEN_STRONG_INLINE half predux(
const Packet8h& a) {
274 return static_cast<half
>(predux(half2float(a)));
278EIGEN_STRONG_INLINE half predux_mul(
const Packet8h& a) {
279 return static_cast<half
>(predux_mul(half2float(a)));
283EIGEN_STRONG_INLINE half predux_min(
const Packet8h& a) {
284 return static_cast<half
>(predux_min(half2float(a)));
288EIGEN_STRONG_INLINE half predux_min<PropagateNumbers>(
const Packet8h& a) {
289 return static_cast<half
>(predux_min<PropagateNumbers>(half2float(a)));
293EIGEN_STRONG_INLINE half predux_min<PropagateNaN>(
const Packet8h& a) {
294 return static_cast<half
>(predux_min<PropagateNaN>(half2float(a)));
298EIGEN_STRONG_INLINE half predux_max(
const Packet8h& a) {
299 return static_cast<half
>(predux_max(half2float(a)));
303EIGEN_STRONG_INLINE half predux_max<PropagateNumbers>(
const Packet8h& a) {
304 return static_cast<half
>(predux_max<PropagateNumbers>(half2float(a)));
308EIGEN_STRONG_INLINE half predux_max<PropagateNaN>(
const Packet8h& a) {
309 return static_cast<half
>(predux_max<PropagateNaN>(half2float(a)));
313EIGEN_STRONG_INLINE
bool predux_any(
const Packet8h& a) {
314 return _mm_movemask_epi8(a) != 0;
321EIGEN_STRONG_INLINE bfloat16 predux(
const Packet8bf& a) {
322 return static_cast<bfloat16
>(predux<Packet8f>(Bf16ToF32(a)));
326EIGEN_STRONG_INLINE bfloat16 predux_mul(
const Packet8bf& a) {
327 return static_cast<bfloat16
>(predux_mul<Packet8f>(Bf16ToF32(a)));
331EIGEN_STRONG_INLINE bfloat16 predux_min(
const Packet8bf& a) {
332 return static_cast<bfloat16
>(predux_min(Bf16ToF32(a)));
336EIGEN_STRONG_INLINE bfloat16 predux_min<PropagateNumbers>(
const Packet8bf& a) {
337 return static_cast<bfloat16
>(predux_min<PropagateNumbers>(Bf16ToF32(a)));
341EIGEN_STRONG_INLINE bfloat16 predux_min<PropagateNaN>(
const Packet8bf& a) {
342 return static_cast<bfloat16
>(predux_min<PropagateNaN>(Bf16ToF32(a)));
346EIGEN_STRONG_INLINE bfloat16 predux_max(
const Packet8bf& a) {
347 return static_cast<bfloat16
>(predux_max<Packet8f>(Bf16ToF32(a)));
351EIGEN_STRONG_INLINE bfloat16 predux_max<PropagateNumbers>(
const Packet8bf& a) {
352 return static_cast<bfloat16
>(predux_max<PropagateNumbers>(Bf16ToF32(a)));
356EIGEN_STRONG_INLINE bfloat16 predux_max<PropagateNaN>(
const Packet8bf& a) {
357 return static_cast<bfloat16
>(predux_max<PropagateNaN>(Bf16ToF32(a)));
361EIGEN_STRONG_INLINE
bool predux_any(
const Packet8bf& a) {
362 return _mm_movemask_epi8(a) != 0;