Loada.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_SIMD_LOADA_H_
36 #define _BLAZE_MATH_SIMD_LOADA_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/If.h>
55 
56 
57 namespace blaze {
58 
59 //=================================================================================================
60 //
61 // 8-BIT INTEGRAL SIMD TYPES
62 //
63 //=================================================================================================
64 
65 //*************************************************************************************************
76 template< typename T > // Type of the integral value
77 BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v<T> && HasSize_v<T,1UL>
78  , If_t< IsSigned_v<T>, SIMDint8, SIMDuint8 > >
79  loada( const T* address ) noexcept
80 {
81  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
82 
83 #if BLAZE_AVX512BW_MODE
84  return _mm512_load_si512( reinterpret_cast<const __m512i*>( address ) );
85 #elif BLAZE_AVX2_MODE
86  return _mm256_load_si256( reinterpret_cast<const __m256i*>( address ) );
87 #elif BLAZE_SSE2_MODE
88  return _mm_load_si128( reinterpret_cast<const __m128i*>( address ) );
89 #else
90  return *address;
91 #endif
92 }
93 //*************************************************************************************************
94 
95 
96 //*************************************************************************************************
107 template< typename T > // Type of the integral value
108 BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v<T> && HasSize_v<T,1UL>
109  , If_t< IsSigned_v<T>, SIMDcint8, SIMDcuint8 > >
110  loada( const complex<T>* address ) noexcept
111 {
112  BLAZE_STATIC_ASSERT( sizeof( complex<T> ) == 2UL*sizeof( T ) );
113  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
114 
115 #if BLAZE_AVX512BW_MODE
116  return _mm512_load_si512( reinterpret_cast<const __m512i*>( address ) );
117 #elif BLAZE_AVX2_MODE
118  return _mm256_load_si256( reinterpret_cast<const __m256i*>( address ) );
119 #elif BLAZE_SSE2_MODE
120  return _mm_load_si128( reinterpret_cast<const __m128i*>( address ) );
121 #else
122  return If_t< IsSigned_v<T>, SIMDcint8, SIMDcuint8 >( *address );
123 #endif
124 }
125 //*************************************************************************************************
126 
127 
128 
129 
130 //=================================================================================================
131 //
132 // 16-BIT INTEGRAL SIMD TYPES
133 //
134 //=================================================================================================
135 
136 //*************************************************************************************************
147 template< typename T > // Type of the integral value
148 BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v<T> && HasSize_v<T,2UL>
149  , If_t< IsSigned_v<T>, SIMDint16, SIMDuint16 > >
150  loada( const T* address ) noexcept
151 {
152  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
153 
154 #if BLAZE_AVX512BW_MODE
155  return _mm512_load_si512( reinterpret_cast<const __m512i*>( address ) );
156 #elif BLAZE_AVX2_MODE
157  return _mm256_load_si256( reinterpret_cast<const __m256i*>( address ) );
158 #elif BLAZE_SSE2_MODE
159  return _mm_load_si128( reinterpret_cast<const __m128i*>( address ) );
160 #else
161  return *address;
162 #endif
163 }
164 //*************************************************************************************************
165 
166 
167 //*************************************************************************************************
178 template< typename T > // Type of the integral value
179 BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v<T> && HasSize_v<T,2UL>
180  , If_t< IsSigned_v<T>, SIMDcint16, SIMDcuint16 > >
181  loada( const complex<T>* address ) noexcept
182 {
183  BLAZE_STATIC_ASSERT( sizeof( complex<T> ) == 2UL*sizeof( T ) );
184  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
185 
186 #if BLAZE_AVX512BW_MODE
187  return _mm512_load_si512( reinterpret_cast<const __m512i*>( address ) );
188 #elif BLAZE_AVX2_MODE
189  return _mm256_load_si256( reinterpret_cast<const __m256i*>( address ) );
190 #elif BLAZE_SSE2_MODE
191  return _mm_load_si128( reinterpret_cast<const __m128i*>( address ) );
192 #else
193  return If_t< IsSigned_v<T>, SIMDcint16, SIMDcuint16 >( *address );
194 #endif
195 }
196 //*************************************************************************************************
197 
198 
199 
200 
201 //=================================================================================================
202 //
203 // 32-BIT INTEGRAL SIMD TYPES
204 //
205 //=================================================================================================
206 
207 //*************************************************************************************************
218 template< typename T > // Type of the integral value
219 BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v<T> && HasSize_v<T,4UL>
220  , If_t< IsSigned_v<T>, SIMDint32, SIMDuint32 > >
221  loada( const T* address ) noexcept
222 {
223  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
224 
225 #if BLAZE_AVX512F_MODE || BLAZE_MIC_MODE
226  return _mm512_load_epi32( address );
227 #elif BLAZE_AVX2_MODE
228  return _mm256_load_si256( reinterpret_cast<const __m256i*>( address ) );
229 #elif BLAZE_SSE2_MODE
230  return _mm_load_si128( reinterpret_cast<const __m128i*>( address ) );
231 #else
232  return *address;
233 #endif
234 }
235 //*************************************************************************************************
236 
237 
238 //*************************************************************************************************
249 template< typename T > // Type of the integral value
250 BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v<T> && HasSize_v<T,4UL>
251  , If_t< IsSigned_v<T>, SIMDcint32, SIMDcuint32 > >
252  loada( const complex<T>* address ) noexcept
253 {
254  BLAZE_STATIC_ASSERT( sizeof( complex<T> ) == 2UL*sizeof( T ) );
255  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
256 
257 #if BLAZE_AVX512F_MODE || BLAZE_MIC_MODE
258  return _mm512_load_epi32( address );
259 #elif BLAZE_AVX2_MODE
260  return _mm256_load_si256( reinterpret_cast<const __m256i*>( address ) );
261 #elif BLAZE_SSE2_MODE
262  return _mm_load_si128( reinterpret_cast<const __m128i*>( address ) );
263 #else
264  return If_t< IsSigned_v<T>, SIMDcint32, SIMDcuint32 >( *address );
265 #endif
266 }
267 //*************************************************************************************************
268 
269 
270 
271 
272 //=================================================================================================
273 //
274 // 64-BIT INTEGRAL SIMD TYPES
275 //
276 //=================================================================================================
277 
278 //*************************************************************************************************
289 template< typename T > // Type of the integral value
290 BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v<T> && HasSize_v<T,8UL>
291  , If_t< IsSigned_v<T>, SIMDint64, SIMDuint64 > >
292  loada( const T* address ) noexcept
293 {
294  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
295 
296 #if BLAZE_AVX512F_MODE || BLAZE_MIC_MODE
297  return _mm512_load_epi64( address );
298 #elif BLAZE_AVX2_MODE
299  return _mm256_load_si256( reinterpret_cast<const __m256i*>( address ) );
300 #elif BLAZE_SSE2_MODE
301  return _mm_load_si128( reinterpret_cast<const __m128i*>( address ) );
302 #else
303  return *address;
304 #endif
305 }
306 //*************************************************************************************************
307 
308 
309 //*************************************************************************************************
320 template< typename T > // Type of the integral value
321 BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v<T> && HasSize_v<T,8UL>
322  , If_t< IsSigned_v<T>, SIMDcint64, SIMDcuint64 > >
323  loada( const complex<T>* address ) noexcept
324 {
325  BLAZE_STATIC_ASSERT( sizeof( complex<T> ) == 2UL*sizeof( T ) );
326  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
327 
328 #if BLAZE_AVX512F_MODE || BLAZE_MIC_MODE
329  return _mm512_load_epi64( address );
330 #elif BLAZE_AVX2_MODE
331  return _mm256_load_si256( reinterpret_cast<const __m256i*>( address ) );
332 #elif BLAZE_SSE2_MODE
333  return _mm_load_si128( reinterpret_cast<const __m128i*>( address ) );
334 #else
335  return If_t< IsSigned_v<T>, SIMDcint64, SIMDcuint64 >( *address );
336 #endif
337 }
338 //*************************************************************************************************
339 
340 
341 
342 
343 //=================================================================================================
344 //
345 // 32-BIT FLOATING POINT SIMD TYPES
346 //
347 //=================================================================================================
348 
349 //*************************************************************************************************
360 BLAZE_ALWAYS_INLINE const SIMDfloat loada( const float* address ) noexcept
361 {
362  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
363 
364 #if BLAZE_AVX512F_MODE || BLAZE_MIC_MODE
365  return _mm512_load_ps( address );
366 #elif BLAZE_AVX_MODE
367  return _mm256_load_ps( address );
368 #elif BLAZE_SSE_MODE
369  return _mm_load_ps( address );
370 #else
371  return *address;
372 #endif
373 }
374 //*************************************************************************************************
375 
376 
377 //*************************************************************************************************
388 BLAZE_ALWAYS_INLINE const SIMDcfloat loada( const complex<float>* address ) noexcept
389 {
390  BLAZE_STATIC_ASSERT ( sizeof( complex<float> ) == 2UL*sizeof( float ) );
391  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
392 
393 #if BLAZE_AVX512F_MODE || BLAZE_MIC_MODE
394  return _mm512_load_ps( reinterpret_cast<const float*>( address ) );
395 #elif BLAZE_AVX_MODE
396  return _mm256_load_ps( reinterpret_cast<const float*>( address ) );
397 #elif BLAZE_SSE_MODE
398  return _mm_load_ps( reinterpret_cast<const float*>( address ) );
399 #else
400  return *address;
401 #endif
402 }
403 //*************************************************************************************************
404 
405 
406 
407 
408 //=================================================================================================
409 //
410 // 64-BIT FLOATING POINT SIMD TYPES
411 //
412 //=================================================================================================
413 
414 //*************************************************************************************************
425 BLAZE_ALWAYS_INLINE const SIMDdouble loada( const double* address ) noexcept
426 {
427  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
428 
429 #if BLAZE_AVX512F_MODE || BLAZE_MIC_MODE
430  return _mm512_load_pd( address );
431 #elif BLAZE_AVX_MODE
432  return _mm256_load_pd( address );
433 #elif BLAZE_SSE2_MODE
434  return _mm_load_pd( address );
435 #else
436  return *address;
437 #endif
438 }
439 //*************************************************************************************************
440 
441 
442 //*************************************************************************************************
453 BLAZE_ALWAYS_INLINE const SIMDcdouble loada( const complex<double>* address ) noexcept
454 {
455  BLAZE_STATIC_ASSERT ( sizeof( complex<double> ) == 2UL*sizeof( double ) );
456  BLAZE_INTERNAL_ASSERT( checkAlignment( address ), "Invalid alignment detected" );
457 
458 #if BLAZE_AVX512F_MODE || BLAZE_MIC_MODE
459  return _mm512_load_pd( reinterpret_cast<const double*>( address ) );
460 #elif BLAZE_AVX_MODE
461  return _mm256_load_pd( reinterpret_cast<const double*>( address ) );
462 #elif BLAZE_SSE2_MODE
463  return _mm_load_pd( reinterpret_cast<const double*>( address ) );
464 #else
465  return *address;
466 #endif
467 }
468 //*************************************************************************************************
469 
470 } // namespace blaze
471 
472 #endif
SIMD type for 32-bit unsigned integral complex values.
typename If< Condition, T1, T2 >::Type If_t
Auxiliary alias declaration for the If class template.The If_t alias declaration provides a convenien...
Definition: If.h:109
SIMD type for 16-bit unsigned integral complex values.
SIMD type for 32-bit signed integral complex values.
Header file for the IsIntegral type trait.
SIMD type for 64-bit double precision floating point data values.
SIMD type for 64-bit unsigned integral complex values.
SIMD type for 16-bit signed integral complex values.
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
Header file for the If class template.
Compile time assertion.
Header file for the EnableIf class template.
Header file for the basic SIMD types.
Header file for run time assertion macros.
SIMD type for 8-bit signed integral complex values.
Header file for the HasSize type trait.
SIMD type for 32-bit single precision complex values.
SIMD type for 64-bit signed integral complex values.
Header file for the IsSigned type trait.
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:79
SIMD type for 32-bit single precision floating point data values.
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
SIMD type for 8-bit unsigned integral complex values.
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