Blaze 3.9
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>
53
54
55namespace blaze {
56
57//=================================================================================================
58//
59// 8-BIT INTEGRAL SIMD TYPES
60//
61//=================================================================================================
62
63//*************************************************************************************************
71template< typename T1 // Type of the integral value
72 , typename T2 > // Type of the SIMD data type
73BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v<T1> && HasSize_v<T1,1UL> >
74 stream( T1* address, const SIMDi8<T2>& value ) noexcept
75{
76 BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
77
78#if BLAZE_AVX512BW_MODE
79 _mm512_stream_si512( reinterpret_cast<__m512i*>( address ), (*value).value );
80#elif BLAZE_AVX2_MODE
81 _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (*value).value );
82#elif BLAZE_SSE2_MODE
83 _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (*value).value );
84#else
85 *address = (*value).value;
86#endif
87}
88//*************************************************************************************************
89
90
91//*************************************************************************************************
99template< typename T1 // Type of the integral value
100 , typename T2 > // Type of the SIMD data type
101BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v<T1> && HasSize_v<T1,1UL> >
102 stream( complex<T1>* address, const SIMDci8<T2>& value ) noexcept
103{
104 BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
105 BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
106
107#if BLAZE_AVX512BW_MODE
108 _mm512_stream_si512( reinterpret_cast<__m512i*>( address ), (*value).value );
109#elif BLAZE_AVX2_MODE
110 _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (*value).value );
111#elif BLAZE_SSE2_MODE
112 _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (*value).value );
113#else
114 *address = (*value).value;
115#endif
116}
117//*************************************************************************************************
118
119
120
121
122//=================================================================================================
123//
124// 16-BIT INTEGRAL SIMD TYPES
125//
126//=================================================================================================
127
128//*************************************************************************************************
136template< typename T1 // Type of the integral value
137 , typename T2 > // Type of the SIMD data type
138BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v<T1> && HasSize_v<T1,2UL> >
139 stream( T1* address, const SIMDi16<T2>& value ) noexcept
140{
141 BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
142
143#if BLAZE_AVX512BW_MODE
144 _mm512_stream_si512( reinterpret_cast<__m512i*>( address ), (*value).value );
145#elif BLAZE_AVX2_MODE
146 _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (*value).value );
147#elif BLAZE_SSE2_MODE
148 _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (*value).value );
149#else
150 *address = (*value).value;
151#endif
152}
153//*************************************************************************************************
154
155
156//*************************************************************************************************
164template< typename T1 // Type of the integral value
165 , typename T2 > // Type of the SIMD data type
166BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v<T1> && HasSize_v<T1,2UL> >
167 stream( complex<T1>* address, const SIMDci16<T2>& value ) noexcept
168{
169 BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
170 BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
171
172#if BLAZE_AVX512BW_MODE
173 _mm512_stream_si512( reinterpret_cast<__m512i*>( address ), (*value).value );
174#elif BLAZE_AVX2_MODE
175 _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (*value).value );
176#elif BLAZE_SSE2_MODE
177 _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (*value).value );
178#else
179 *address = (*value).value;
180#endif
181}
182//*************************************************************************************************
183
184
185
186
187//=================================================================================================
188//
189// 32-BIT INTEGRAL SIMD TYPES
190//
191//=================================================================================================
192
193//*************************************************************************************************
201template< typename T1 // Type of the integral value
202 , typename T2 > // Type of the SIMD data type
203BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v<T1> && HasSize_v<T1,4UL> >
204 stream( T1* address, const SIMDi32<T2>& value ) noexcept
205{
206 BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
207
208#if BLAZE_AVX512F_MODE
209 _mm512_stream_si512( reinterpret_cast<__m512i*>( address ), (*value).value );
210#elif BLAZE_MIC_MODE
211 _mm512_store_epi32( address, (*value).value );
212#elif BLAZE_AVX2_MODE
213 _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (*value).value );
214#elif BLAZE_SSE2_MODE
215 _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (*value).value );
216#else
217 *address = (*value).value;
218#endif
219}
220//*************************************************************************************************
221
222
223//*************************************************************************************************
231template< typename T1 // Type of the integral value
232 , typename T2 > // Type of the SIMD data type
233BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v<T1> && HasSize_v<T1,4UL> >
234 stream( complex<T1>* address, const SIMDci32<T2>& value ) noexcept
235{
236 BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
237 BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
238
239#if BLAZE_AVX512F_MODE
240 _mm512_stream_si512( reinterpret_cast<__m512i*>( address ), (*value).value );
241#elif BLAZE_MIC_MODE
242 _mm512_store_epi32( address, (*value).value );
243#elif BLAZE_AVX2_MODE
244 _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (*value).value );
245#elif BLAZE_SSE2_MODE
246 _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (*value).value );
247#else
248 *address = (*value).value;
249#endif
250}
251//*************************************************************************************************
252
253
254
255
256//=================================================================================================
257//
258// 64-BIT INTEGRAL SIMD TYPES
259//
260//=================================================================================================
261
262//*************************************************************************************************
270template< typename T1 // Type of the integral value
271 , typename T2 > // Type of the SIMD data type
272BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v<T1> && HasSize_v<T1,8UL> >
273 stream( T1* address, const SIMDi64<T2>& value ) noexcept
274{
275 BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
276
277#if BLAZE_AVX512F_MODE
278 _mm512_stream_si512( reinterpret_cast<__m512i*>( address ), (*value).value );
279#elif BLAZE_MIC_MODE
280 _mm512_store_epi64( address, (*value).value );
281#elif BLAZE_AVX2_MODE
282 _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (*value).value );
283#elif BLAZE_SSE2_MODE
284 _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (*value).value );
285#else
286 *address = (*value).value;
287#endif
288}
289//*************************************************************************************************
290
291
292//*************************************************************************************************
300template< typename T1 // Type of the integral value
301 , typename T2 > // Type of the SIMD data type
302BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v<T1> && HasSize_v<T1,8UL> >
303 stream( complex<T1>* address, const SIMDci64<T2>& value ) noexcept
304{
305 BLAZE_STATIC_ASSERT( sizeof( complex<T1> ) == 2UL*sizeof( T1 ) );
306 BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
307
308#if BLAZE_AVX512F_MODE
309 _mm512_stream_si512( reinterpret_cast<__m512i*>( address ), (*value).value );
310#elif BLAZE_MIC_MODE
311 _mm512_store_epi64( address, (*value).value );
312#elif BLAZE_AVX2_MODE
313 _mm256_stream_si256( reinterpret_cast<__m256i*>( address ), (*value).value );
314#elif BLAZE_SSE2_MODE
315 _mm_stream_si128( reinterpret_cast<__m128i*>( address ), (*value).value );
316#else
317 *address = (*value).value;
318#endif
319}
320//*************************************************************************************************
321
322
323
324
325//=================================================================================================
326//
327// 32-BIT FLOATING POINT SIMD TYPES
328//
329//=================================================================================================
330
331//*************************************************************************************************
339template< typename T > // Type of the operand
340BLAZE_ALWAYS_INLINE void stream( float* address, const SIMDf32<T>& value ) noexcept
341{
342 BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
343
344#if BLAZE_AVX512F_MODE
345 _mm512_stream_ps( address, (*value).value );
346#elif BLAZE_MIC_MODE
347 _mm512_storenr_ps( address, (*value).eval().value );
348#elif BLAZE_AVX_MODE
349 _mm256_stream_ps( address, (*value).eval().value );
350#elif BLAZE_SSE_MODE
351 _mm_stream_ps( address, (*value).eval().value );
352#else
353 *address = (*value).eval().value;
354#endif
355}
356//*************************************************************************************************
357
358
359//*************************************************************************************************
367BLAZE_ALWAYS_INLINE void stream( complex<float>* address, const SIMDcfloat& value ) noexcept
368{
369 BLAZE_STATIC_ASSERT ( sizeof( complex<float> ) == 2UL*sizeof( float ) );
370 BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
371
372#if BLAZE_AVX512F_MODE
373 _mm512_stream_ps( reinterpret_cast<float*>( address ), (*value).value );
374#elif BLAZE_MIC_MODE
375 _mm512_storenr_ps( reinterpret_cast<float*>( address ), value.value );
376#elif BLAZE_AVX_MODE
377 _mm256_stream_ps( reinterpret_cast<float*>( address ), value.value );
378#elif BLAZE_SSE_MODE
379 _mm_stream_ps( reinterpret_cast<float*>( address ), value.value );
380#else
381 *address = value.value;
382#endif
383}
384//*************************************************************************************************
385
386
387
388
389//=================================================================================================
390//
391// 64-BIT FLOATING POINT SIMD TYPES
392//
393//=================================================================================================
394
395//*************************************************************************************************
403template< typename T > // Type of the operand
404BLAZE_ALWAYS_INLINE void stream( double* address, const SIMDf64<T>& value ) noexcept
405{
406 BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
407
408#if BLAZE_AVX512F_MODE
409 _mm512_stream_pd( address, (*value).value );
410#elif BLAZE_MIC_MODE
411 _mm512_storenr_pd( address, (*value).eval().value );
412#elif BLAZE_AVX_MODE
413 _mm256_stream_pd( address, (*value).eval().value );
414#elif BLAZE_SSE2_MODE
415 _mm_stream_pd( address, (*value).eval().value );
416#else
417 *address = (*value).eval().value;
418#endif
419}
420//*************************************************************************************************
421
422
423//*************************************************************************************************
431BLAZE_ALWAYS_INLINE void stream( complex<double>* address, const SIMDcdouble& value ) noexcept
432{
433 BLAZE_STATIC_ASSERT ( sizeof( complex<double> ) == 2UL*sizeof( double ) );
434 BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
435
436#if BLAZE_AVX512F_MODE
437 _mm512_stream_pd( reinterpret_cast<double*>( address ), (*value).value );
438#elif BLAZE_MIC_MODE
439 _mm512_storenr_pd( reinterpret_cast<double*>( address ), value.value );
440#elif BLAZE_AVX_MODE
441 _mm256_stream_pd( reinterpret_cast<double*>( address ), value.value );
442#elif BLAZE_SSE2_MODE
443 _mm_stream_pd( reinterpret_cast<double*>( address ), value.value );
444#else
445 *address = value.value;
446#endif
447}
448//*************************************************************************************************
449
450} // namespace blaze
451
452#endif
Header file for the alignment check function.
Header file for run time assertion macros.
Header file for the basic SIMD types.
Header file for the complex data type.
Header file for the EnableIf class template.
Header file for the HasSize type trait.
Header file for the IsIntegral type trait.
Compile time assertion.
SIMD type for 64-bit double precision complex values.
SIMD type for 32-bit single precision complex values.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
BLAZE_ALWAYS_INLINE void stream(complex< double > *address, const SIMDcdouble &value) noexcept
Aligned, non-temporal store of a vector of 'complex<double>' values.
Definition: Stream.h:431
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.
Definition: StaticAssert.h:112
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
System settings for the inline keywords.
System settings for the SSE mode.