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_AVX512BW_MODE
80  _mm512_stream_si512( address, (~value).value );
81 #elif BLAZE_AVX2_MODE
82  _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
83 #elif BLAZE_SSE2_MODE
84  _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
85 #else
86  *address = (~value).value;
87 #endif
88 }
89 //*************************************************************************************************
90 
91 
92 //*************************************************************************************************
100 template< typename T1 // Type of the integral value
101  , typename T2 > // Type of the SIMD data type
102 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,1UL> > >
103  stream( complex<T1>* address, const SIMDci8<T2>& value ) noexcept
104 {
105  BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
106  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
107 
108 #if BLAZE_AVX512BW_MODE
109  _mm512_stream_si512( address, (~value).value );
110 #elif BLAZE_AVX2_MODE
111  _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
112 #elif BLAZE_SSE2_MODE
113  _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
114 #else
115  *address = (~value).value;
116 #endif
117 }
118 //*************************************************************************************************
119 
120 
121 
122 
123 //=================================================================================================
124 //
125 // 16-BIT INTEGRAL SIMD TYPES
126 //
127 //=================================================================================================
128 
129 //*************************************************************************************************
137 template< typename T1 // Type of the integral value
138  , typename T2 > // Type of the SIMD data type
139 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,2UL> > >
140  stream( T1* address, const SIMDi16<T2>& value ) noexcept
141 {
142  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
143 
144 #if BLAZE_AVX512BW_MODE
145  _mm512_stream_si512( address, (~value).value );
146 #elif BLAZE_AVX2_MODE
147  _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
148 #elif BLAZE_SSE2_MODE
149  _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
150 #else
151  *address = (~value).value;
152 #endif
153 }
154 //*************************************************************************************************
155 
156 
157 //*************************************************************************************************
165 template< typename T1 // Type of the integral value
166  , typename T2 > // Type of the SIMD data type
167 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,2UL> > >
168  stream( complex<T1>* address, const SIMDci16<T2>& value ) noexcept
169 {
170  BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
171  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
172 
173 #if BLAZE_AVX512BW_MODE
174  _mm512_stream_si512( address, (~value).value );
175 #elif BLAZE_AVX2_MODE
176  _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
177 #elif BLAZE_SSE2_MODE
178  _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
179 #else
180  *address = (~value).value;
181 #endif
182 }
183 //*************************************************************************************************
184 
185 
186 
187 
188 //=================================================================================================
189 //
190 // 32-BIT INTEGRAL SIMD TYPES
191 //
192 //=================================================================================================
193 
194 //*************************************************************************************************
202 template< typename T1 // Type of the integral value
203  , typename T2 > // Type of the SIMD data type
204 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,4UL> > >
205  stream( T1* address, const SIMDi32<T2>& value ) noexcept
206 {
207  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
208 
209 #if BLAZE_AVX512F_MODE
210  _mm512_stream_si512( reinterpret_cast<__m512i*>( address ), (~value).value );
211 #elif BLAZE_MIC_MODE
212  _mm512_store_epi32( address, (~value).value );
213 #elif BLAZE_AVX2_MODE
214  _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
215 #elif BLAZE_SSE2_MODE
216  _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
217 #else
218  *address = (~value).value;
219 #endif
220 }
221 //*************************************************************************************************
222 
223 
224 //*************************************************************************************************
232 template< typename T1 // Type of the integral value
233  , typename T2 > // Type of the SIMD data type
234 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,4UL> > >
235  stream( complex<T1>* address, const SIMDci32<T2>& value ) noexcept
236 {
237  BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
238  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
239 
240 #if BLAZE_AVX512F_MODE
241  _mm512_stream_si512( address, (~value).value );
242 #elif BLAZE_MIC_MODE
243  _mm512_store_epi32( address, (~value).value );
244 #elif BLAZE_AVX2_MODE
245  _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
246 #elif BLAZE_SSE2_MODE
247  _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
248 #else
249  *address = (~value).value;
250 #endif
251 }
252 //*************************************************************************************************
253 
254 
255 
256 
257 //=================================================================================================
258 //
259 // 64-BIT INTEGRAL SIMD TYPES
260 //
261 //=================================================================================================
262 
263 //*************************************************************************************************
271 template< typename T1 // Type of the integral value
272  , typename T2 > // Type of the SIMD data type
273 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,8UL> > >
274  stream( T1* address, const SIMDi64<T2>& value ) noexcept
275 {
276  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
277 
278 #if BLAZE_AVX512F_MODE
279  _mm512_stream_si512( address, (~value).value );
280 #elif BLAZE_MIC_MODE
281  _mm512_store_epi64( address, (~value).value );
282 #elif BLAZE_AVX2_MODE
283  _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
284 #elif BLAZE_SSE2_MODE
285  _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
286 #else
287  *address = (~value).value;
288 #endif
289 }
290 //*************************************************************************************************
291 
292 
293 //*************************************************************************************************
301 template< typename T1 // Type of the integral value
302  , typename T2 > // Type of the SIMD data type
303 BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral<T1>, HasSize<T1,8UL> > >
304  stream( complex<T1>* address, const SIMDci64<T2>& value ) noexcept
305 {
306  BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
307  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
308 
309 #if BLAZE_AVX512F_MODE
310  _mm512_stream_si512( address, (~value).value );
311 #elif BLAZE_MIC_MODE
312  _mm512_store_epi64( address, (~value).value );
313 #elif BLAZE_AVX2_MODE
314  _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (~value).value );
315 #elif BLAZE_SSE2_MODE
316  _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (~value).value );
317 #else
318  *address = (~value).value;
319 #endif
320 }
321 //*************************************************************************************************
322 
323 
324 
325 
326 //=================================================================================================
327 //
328 // 32-BIT FLOATING POINT SIMD TYPES
329 //
330 //=================================================================================================
331 
332 //*************************************************************************************************
340 template< typename T > // Type of the operand
341 BLAZE_ALWAYS_INLINE void stream( float* address, const SIMDf32<T>& value ) noexcept
342 {
343  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
344 
345 #if BLAZE_AVX512F_MODE
346  _mm512_stream_ps( address, (~value).value );
347 #elif BLAZE_MIC_MODE
348  _mm512_storenr_ps( address, (~value).eval().value );
349 #elif BLAZE_AVX_MODE
350  _mm256_stream_ps( address, (~value).eval().value );
351 #elif BLAZE_SSE_MODE
352  _mm_stream_ps( address, (~value).eval().value );
353 #else
354  *address = (~value).eval().value;
355 #endif
356 }
357 //*************************************************************************************************
358 
359 
360 //*************************************************************************************************
368 BLAZE_ALWAYS_INLINE void stream( complex<float>* address, const SIMDcfloat& value ) noexcept
369 {
370  BLAZE_STATIC_ASSERT ( sizeof( complex<float> ) == 2UL*sizeof( float ) );
371  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
372 
373 #if BLAZE_AVX512F_MODE
374  _mm512_stream_ps( reinterpret_cast<float*>( address ), (~value).value );
375 #elif BLAZE_MIC_MODE
376  _mm512_storenr_ps( reinterpret_cast<float*>( address ), value.value );
377 #elif BLAZE_AVX_MODE
378  _mm256_stream_ps( reinterpret_cast<float*>( address ), value.value );
379 #elif BLAZE_SSE_MODE
380  _mm_stream_ps( reinterpret_cast<float*>( address ), value.value );
381 #else
382  *address = value.value;
383 #endif
384 }
385 //*************************************************************************************************
386 
387 
388 
389 
390 //=================================================================================================
391 //
392 // 64-BIT FLOATING POINT SIMD TYPES
393 //
394 //=================================================================================================
395 
396 //*************************************************************************************************
404 template< typename T > // Type of the operand
405 BLAZE_ALWAYS_INLINE void stream( double* address, const SIMDf64<T>& value ) noexcept
406 {
407  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
408 
409 #if BLAZE_AVX512F_MODE
410  _mm512_stream_pd( address, (~value).value );
411 #elif BLAZE_MIC_MODE
412  _mm512_storenr_pd( address, (~value).eval().value );
413 #elif BLAZE_AVX_MODE
414  _mm256_stream_pd( address, (~value).eval().value );
415 #elif BLAZE_SSE2_MODE
416  _mm_stream_pd( address, (~value).eval().value );
417 #else
418  *address = (~value).eval().value;
419 #endif
420 }
421 //*************************************************************************************************
422 
423 
424 //*************************************************************************************************
432 BLAZE_ALWAYS_INLINE void stream( complex<double>* address, const SIMDcdouble& value ) noexcept
433 {
434  BLAZE_STATIC_ASSERT ( sizeof( complex<double> ) == 2UL*sizeof( double ) );
435  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
436 
437 #if BLAZE_AVX512F_MODE
438  _mm512_stream_pd( reinterpret_cast<double*>( address ), (~value).value );
439 #elif BLAZE_MIC_MODE
440  _mm512_storenr_pd( reinterpret_cast<double*>( address ), value.value );
441 #elif BLAZE_AVX_MODE
442  _mm256_stream_pd( reinterpret_cast<double*>( address ), value.value );
443 #elif BLAZE_SSE2_MODE
444  _mm_stream_pd( reinterpret_cast<double*>( address ), value.value );
445 #else
446  *address = value.value;
447 #endif
448 }
449 //*************************************************************************************************
450 
451 } // namespace blaze
452 
453 #endif
Compile time size check.This class offers the possibility to test the size of a type at compile time...
Definition: HasSize.h:75
Header file for the IsIntegral type trait.
Header file for the And class template.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Compile time assertion.
decltype(auto) eval(const DenseMatrix< MT, SO > &dm)
Forces the evaluation of the given dense matrix expression dm.
Definition: DMatEvalExpr.h:794
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.
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