Stream.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_SIMD_STREAM_H_
36 #define _BLAZE_MATH_SIMD_STREAM_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
44 #include <blaze/system/Inline.h>
47 #include <blaze/util/Assert.h>
48 #include <blaze/util/Complex.h>
49 #include <blaze/util/EnableIf.h>
50 #include <blaze/util/mpl/And.h>
54 
55 
56 namespace blaze {
57 
58 //=================================================================================================
59 //
60 // 8-BIT INTEGRAL SIMD TYPES
61 //
62 //=================================================================================================
63 
64 //*************************************************************************************************
72 template< typename T1 // Type of the integral value
73  , typename T2 > // Type of the SIMD data type
74 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,1UL> > >
75  stream( T1* address, const SIMDi8<T2>& value ) noexcept
76 {
77  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
78 
79 #if BLAZE_AVX2_MODE
80  _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
81 #elif BLAZE_SSE2_MODE
82  _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
83 #else
84  *address = (~value).value;
85 #endif
86 }
87 //*************************************************************************************************
88 
89 
90 //*************************************************************************************************
98 template< typename T1 // Type of the integral value
99  , typename T2 > // Type of the SIMD data type
100 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,1UL> > >
101  stream( complex<T1>* address, const SIMDci8<T2>& value ) noexcept
102 {
103  BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
104  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
105 
106 #if BLAZE_AVX2_MODE
107  _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
108 #elif BLAZE_SSE2_MODE
109  _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
110 #else
111  *address = (~value).value;
112 #endif
113 }
114 //*************************************************************************************************
115 
116 
117 
118 
119 //=================================================================================================
120 //
121 // 16-BIT INTEGRAL SIMD TYPES
122 //
123 //=================================================================================================
124 
125 //*************************************************************************************************
133 template< typename T1 // Type of the integral value
134  , typename T2 > // Type of the SIMD data type
135 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,2UL> > >
136  stream( T1* address, const SIMDi16<T2>& value ) noexcept
137 {
138  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
139 
140 #if BLAZE_AVX2_MODE
141  _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
142 #elif BLAZE_SSE2_MODE
143  _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
144 #else
145  *address = (~value).value;
146 #endif
147 }
148 //*************************************************************************************************
149 
150 
151 //*************************************************************************************************
159 template< typename T1 // Type of the integral value
160  , typename T2 > // Type of the SIMD data type
161 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,2UL> > >
162  stream( complex<T1>* address, const SIMDci16<T2>& value ) noexcept
163 {
164  BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
165  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
166 
167 #if BLAZE_AVX2_MODE
168  _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
169 #elif BLAZE_SSE2_MODE
170  _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
171 #else
172  *address = (~value).value;
173 #endif
174 }
175 //*************************************************************************************************
176 
177 
178 
179 
180 //=================================================================================================
181 //
182 // 32-BIT INTEGRAL SIMD TYPES
183 //
184 //=================================================================================================
185 
186 //*************************************************************************************************
194 template< typename T1 // Type of the integral value
195  , typename T2 > // Type of the SIMD data type
196 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,4UL> > >
197  stream( T1* address, const SIMDi32<T2>& value ) noexcept
198 {
199  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
200 
201 #if BLAZE_MIC_MODE
202  _mm512_store_epi32( address, (~value).value );
203 #elif BLAZE_AVX2_MODE
204  _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
205 #elif BLAZE_SSE2_MODE
206  _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
207 #else
208  *address = (~value).value;
209 #endif
210 }
211 //*************************************************************************************************
212 
213 
214 //*************************************************************************************************
222 template< typename T1 // Type of the integral value
223  , typename T2 > // Type of the SIMD data type
224 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,4UL> > >
225  stream( complex<T1>* address, const SIMDci32<T2>& value ) noexcept
226 {
227  BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
228  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
229 
230 #if BLAZE_MIC_MODE
231  _mm512_store_epi32( address, (~value).value );
232 #elif BLAZE_AVX2_MODE
233  _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
234 #elif BLAZE_SSE2_MODE
235  _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
236 #else
237  *address = (~value).value;
238 #endif
239 }
240 //*************************************************************************************************
241 
242 
243 
244 
245 //=================================================================================================
246 //
247 // 64-BIT INTEGRAL SIMD TYPES
248 //
249 //=================================================================================================
250 
251 //*************************************************************************************************
259 template< typename T1 // Type of the integral value
260  , typename T2 > // Type of the SIMD data type
261 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,8UL> > >
262  stream( T1* address, const SIMDi64<T2>& value ) noexcept
263 {
264  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
265 
266 #if BLAZE_MIC_MODE
267  _mm512_store_epi64( address, (~value).value );
268 #elif BLAZE_AVX2_MODE
269  _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
270 #elif BLAZE_SSE2_MODE
271  _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
272 #else
273  *address = (~value).value;
274 #endif
275 }
276 //*************************************************************************************************
277 
278 
279 //*************************************************************************************************
287 template< typename T1 // Type of the integral value
288  , typename T2 > // Type of the SIMD data type
289 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,8UL> > >
290  stream( complex<T1>* address, const SIMDci64<T2>& value ) noexcept
291 {
292  BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
293  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
294 
295 #if BLAZE_MIC_MODE
296  _mm512_store_epi64( address, (~value).value );
297 #elif BLAZE_AVX2_MODE
298  _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
299 #elif BLAZE_SSE2_MODE
300  _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
301 #else
302  *address = (~value).value;
303 #endif
304 }
305 //*************************************************************************************************
306 
307 
308 
309 
310 //=================================================================================================
311 //
312 // 32-BIT FLOATING POINT SIMD TYPES
313 //
314 //=================================================================================================
315 
316 //*************************************************************************************************
324 template< typename T > // Type of the operand
325 BLAZE_ALWAYS_INLINE void stream( float* address, const SIMDf32<T>& value ) noexcept
326 {
327  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
328 
329 #if BLAZE_MIC_MODE
330  _mm512_storenr_ps( address, (~value).eval().value );
331 #elif BLAZE_AVX_MODE
332  _mm256_stream_ps( address, (~value).eval().value );
333 #elif BLAZE_SSE_MODE
334  _mm_stream_ps( address, (~value).eval().value );
335 #else
336  *address = (~value).eval().value;
337 #endif
338 }
339 //*************************************************************************************************
340 
341 
342 //*************************************************************************************************
350 BLAZE_ALWAYS_INLINE void stream( complex<float>* address, const SIMDcfloat& value ) noexcept
351 {
352  BLAZE_STATIC_ASSERT ( sizeof( complex<float> ) == 2UL*sizeof( float ) );
353  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
354 
355 #if BLAZE_MIC_MODE
356  _mm512_storenr_ps( reinterpret_cast<float*>( address ), value.value );
357 #elif BLAZE_AVX_MODE
358  _mm256_stream_ps( reinterpret_cast<float*>( address ), value.value );
359 #elif BLAZE_SSE_MODE
360  _mm_stream_ps( reinterpret_cast<float*>( address ), value.value );
361 #else
362  *address = value.value;
363 #endif
364 }
365 //*************************************************************************************************
366 
367 
368 
369 
370 //=================================================================================================
371 //
372 // 64-BIT FLOATING POINT SIMD TYPES
373 //
374 //=================================================================================================
375 
376 //*************************************************************************************************
384 template< typename T > // Type of the operand
385 BLAZE_ALWAYS_INLINE void stream( double* address, const SIMDf64<T>& value ) noexcept
386 {
387  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
388 
389 #if BLAZE_MIC_MODE
390  _mm512_storenr_pd( address, (~value).eval().value );
391 #elif BLAZE_AVX_MODE
392  _mm256_stream_pd( address, (~value).eval().value );
393 #elif BLAZE_SSE2_MODE
394  _mm_stream_pd( address, (~value).eval().value );
395 #else
396  *address = (~value).eval().value;
397 #endif
398 }
399 //*************************************************************************************************
400 
401 
402 //*************************************************************************************************
410 BLAZE_ALWAYS_INLINE void stream( complex<double>* address, const SIMDcdouble& value ) noexcept
411 {
412  BLAZE_STATIC_ASSERT ( sizeof( complex<double> ) == 2UL*sizeof( double ) );
413  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
414 
415 #if BLAZE_MIC_MODE
416  _mm512_storenr_pd( reinterpret_cast<double*>( address ), value.value );
417 #elif BLAZE_AVX_MODE
418  _mm256_stream_pd( reinterpret_cast<double*>( address ), value.value );
419 #elif BLAZE_SSE2_MODE
420  _mm_stream_pd( reinterpret_cast<double*>( address ), value.value );
421 #else
422  *address = value.value;
423 #endif
424 }
425 //*************************************************************************************************
426 
427 } // namespace blaze
428 
429 #endif
Header file for the IsIntegral type trait.
Header file for the And class template.
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
Compile time assertion.
Header file for the EnableIf class template.
Header file for the basic SIMD types.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:75
Header file for run time assertion macros.
Header file for the HasSize type trait.
SIMD type for 32-bit single precision complex values.
const DMatEvalExpr< MT, SO > eval(const DenseMatrix< MT, SO > &dm)
Forces the evaluation of the given dense matrix expression dm.
Definition: DMatEvalExpr.h:705
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
Header file for the alignment check function.
SIMD type for 64-bit double precision complex values.
System settings for the SSE mode.
Header file for the complex data type.
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.In case of an invalid compile time expression, a compilation error is cr...
Definition: StaticAssert.h:112
System settings for the inline keywords.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101