Reduction.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_SIMD_REDUCTION_H_
36 #define _BLAZE_MATH_SIMD_REDUCTION_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
44 #include <blaze/system/Inline.h>
46 
47 
48 namespace blaze {
49 
50 //=================================================================================================
51 //
52 // 8-BIT INTEGRAL SIMD TYPES
53 //
54 //=================================================================================================
55 
56 //*************************************************************************************************
63 BLAZE_ALWAYS_INLINE const complex<int8_t> sum( const SIMDcint8& a ) noexcept
64 {
65 #if BLAZE_AVX2_MODE
66  return complex<int8_t>( a[0] + a[1] + a[ 2] + a[ 3] + a[ 4] + a[ 5] + a[ 6] + a[ 7] +
67  a[8] + a[9] + a[10] + a[11] + a[12] + a[13] + a[14] + a[15] );
68 #elif BLAZE_SSE2_MODE
69  return complex<int8_t>( a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] );
70 #else
71  return a.value;
72 #endif
73 }
74 //*************************************************************************************************
75 
76 
77 
78 
79 //=================================================================================================
80 //
81 // 16-BIT INTEGRAL SIMD TYPES
82 //
83 //=================================================================================================
84 
85 //*************************************************************************************************
93 {
94 #if BLAZE_AVX2_MODE
95  const __m256i b( _mm256_hadd_epi16( a.value, a.value ) );
96  const __m256i c( _mm256_hadd_epi16( b, b ) );
97  const __m256i d( _mm256_hadd_epi16( c, c ) );
98  const __m128i e = _mm_add_epi16( _mm256_extracti128_si256( d, 1 )
99  , _mm256_castsi256_si128( d ) );
100  return _mm_extract_epi16( e, 0 );
101 #elif BLAZE_SSSE3_MODE
102  const __m128i b( _mm_hadd_epi16( a.value, a.value ) );
103  const __m128i c( _mm_hadd_epi16( b, b ) );
104  const __m128i d( _mm_hadd_epi16( c, c ) );
105  return _mm_extract_epi16( d, 0 );
106 #elif BLAZE_SSE2_MODE
107  return a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7];
108 #else
109  return a.value;
110 #endif
111 }
112 //*************************************************************************************************
113 
114 
115 //*************************************************************************************************
122 BLAZE_ALWAYS_INLINE const complex<int16_t> sum( const SIMDcint16& a ) noexcept
123 {
124 #if BLAZE_AVX2_MODE
125  return complex<int16_t>( a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] );
126 #elif BLAZE_SSE2_MODE
127  return complex<int16_t>( a[0] + a[1] + a[2] + a[3] );
128 #else
129  return a.value;
130 #endif
131 }
132 //*************************************************************************************************
133 
134 
135 
136 
137 //=================================================================================================
138 //
139 // 32-BIT INTEGRAL SIMD TYPES
140 //
141 //=================================================================================================
142 
143 //*************************************************************************************************
151 {
152 #if BLAZE_MIC_MODE
153  return _mm512_reduce_add_epi32( a.value );
154 #elif BLAZE_AVX2_MODE
155  const __m256i b( _mm256_hadd_epi32( a.value, a.value ) );
156  const __m256i c( _mm256_hadd_epi32( b, b ) );
157  const __m128i d = _mm_add_epi32( _mm256_extracti128_si256( c, 1 )
158  , _mm256_castsi256_si128( c ) );
159  return _mm_extract_epi32( d, 0 );
160 #elif BLAZE_SSSE3_MODE
161  const __m128i b( _mm_hadd_epi32( a.value, a.value ) );
162  const __m128i c( _mm_hadd_epi32( b, b ) );
163  return _mm_cvtsi128_si32( c );
164 #elif BLAZE_SSE2_MODE
165  return a[0] + a[1] + a[2] + a[3];
166 #else
167  return a.value;
168 #endif
169 }
170 //*************************************************************************************************
171 
172 
173 //*************************************************************************************************
180 BLAZE_ALWAYS_INLINE const complex<int32_t> sum( const SIMDcint32& a ) noexcept
181 {
182 #if BLAZE_MIC_MODE
183  return complex<int32_t>( a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] );
184 #elif BLAZE_AVX2_MODE
185  return complex<int32_t>( a[0] + a[1] + a[2] + a[3] );
186 #elif BLAZE_SSE2_MODE
187  return complex<int32_t>( a[0] + a[1] );
188 #else
189  return a.value;
190 #endif
191 }
192 //*************************************************************************************************
193 
194 
195 
196 
197 //=================================================================================================
198 //
199 // 64-BIT INTEGRAL SIMD TYPES
200 //
201 //=================================================================================================
202 
203 //*************************************************************************************************
211 {
212 #if BLAZE_MIC_MODE
213  return _mm512_reduce_add_epi64( a.value );
214 #elif BLAZE_AVX2_MODE
215  return a[0] + a[1] + a[2] + a[3];
216 #elif BLAZE_SSE2_MODE
217  return a[0] + a[1];
218 #else
219  return a.value;
220 #endif
221 }
222 //*************************************************************************************************
223 
224 
225 //*************************************************************************************************
232 BLAZE_ALWAYS_INLINE const complex<int64_t> sum( const SIMDcint64& a ) noexcept
233 {
234 #if BLAZE_MIC_MODE
235  return complex<int64_t>( a[0] + a[1] + a[2] + a[3] );
236 #elif BLAZE_AVX2_MODE
237  return complex<int64_t>( a[0] + a[1] );
238 #elif BLAZE_SSE2_MODE
239  return a[0];
240 #else
241  return a.value;
242 #endif
243 }
244 //*************************************************************************************************
245 
246 
247 
248 
249 //=================================================================================================
250 //
251 // 32-BIT FLOATING POINT SIMD TYPES
252 //
253 //=================================================================================================
254 
255 //*************************************************************************************************
262 BLAZE_ALWAYS_INLINE float sum( const SIMDfloat& a ) noexcept
263 {
264 #if BLAZE_MIC_MODE
265  return _mm512_reduce_add_ps( a.value );
266 #elif BLAZE_AVX_MODE
267  const __m256 b( _mm256_hadd_ps( a.value, a.value ) );
268  const __m256 c( _mm256_hadd_ps( b, b ) );
269  const __m128 d = _mm_add_ps( _mm256_extractf128_ps( c, 1 ), _mm256_castps256_ps128( c ) );
270  return _mm_cvtss_f32( d );
271 #elif BLAZE_SSE3_MODE
272  const __m128 b( _mm_hadd_ps( a.value, a.value ) );
273  const __m128 c( _mm_hadd_ps( b, b ) );
274  return _mm_cvtss_f32( c );
275 #elif BLAZE_SSE_MODE
276  return a[0] + a[1] + a[2] + a[3];
277 #else
278  return a.value;
279 #endif
280 }
281 //*************************************************************************************************
282 
283 
284 //*************************************************************************************************
291 BLAZE_ALWAYS_INLINE const complex<float> sum( const SIMDcfloat& a ) noexcept
292 {
293 #if BLAZE_MIC_MODE
294  return complex<float>( a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] );
295 #elif BLAZE_AVX_MODE
296  return complex<float>( a[0] + a[1] + a[2] + a[3] );
297 #elif BLAZE_SSE_MODE
298  return complex<float>( a[0] + a[1] );
299 #else
300  return a.value;
301 #endif
302 }
303 //*************************************************************************************************
304 
305 
306 
307 
308 //=================================================================================================
309 //
310 // 64-BIT FLOATING POINT SIMD TYPES
311 //
312 //=================================================================================================
313 
314 //*************************************************************************************************
321 BLAZE_ALWAYS_INLINE double sum( const SIMDdouble& a ) noexcept
322 {
323 #if BLAZE_MIC_MODE
324  return _mm512_reduce_add_pd( a.value );
325 #elif BLAZE_AVX_MODE
326  const __m256d b( _mm256_hadd_pd( a.value, a.value ) );
327  const __m128d c = _mm_add_pd( _mm256_extractf128_pd( b, 1 ), _mm256_castpd256_pd128( b ) );
328  return _mm_cvtsd_f64( c );
329 #elif BLAZE_SSE3_MODE
330  const __m128d b( _mm_hadd_pd( a.value, a.value ) );
331  return _mm_cvtsd_f64( b );
332 #elif BLAZE_SSE2_MODE
333  return a[0] + a[1];
334 #else
335  return a.value;
336 #endif
337 }
338 //*************************************************************************************************
339 
340 
341 //*************************************************************************************************
348 BLAZE_ALWAYS_INLINE const complex<double> sum( const SIMDcdouble& a ) noexcept
349 {
350 #if BLAZE_MIC_MODE
351  return complex<double>( a[0] + a[1] + a[2] + a[3] );
352 #elif BLAZE_AVX_MODE
353  return complex<double>( a[0] + a[1] );
354 #elif BLAZE_SSE2_MODE
355  return a[0];
356 #else
357  return a.value;
358 #endif
359 }
360 //*************************************************************************************************
361 
362 } // namespace blaze
363 
364 #endif
SIMD type for 16-bit signed integral data values.
BLAZE_ALWAYS_INLINE const complex< int8_t > sum(const SIMDcint8 &a) noexcept
Returns the sum of all elements in the 8-bit integral complex SIMD vector.
Definition: Reduction.h:63
SIMD type for 32-bit signed integral complex values.
SIMD type for 64-bit double precision floating point data values.
16-bit signed integer type of the Blaze library.
SIMD type for 16-bit signed integral complex values.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
SIMD type for 32-bit signed integral data values.
Header file for the basic SIMD types.
SIMD type for 8-bit signed integral complex values.
SIMD type for 32-bit single precision complex values.
SIMD type for 64-bit signed integral complex values.
SIMD type for 32-bit single precision floating point data values.
SIMD type for 64-bit integral data values.
SIMD type for 64-bit double precision complex values.
System settings for the SSE mode.
64-bit signed integer type of the Blaze library.
System settings for the inline keywords.
32-bit signed integer type of the Blaze library.