1 //=================================================================================================
2 /*!
3 //  \file blaze/system/Vectorization.h
4 //  \brief System settings for the SSE mode
5 //
6 //  Copyright (C) 2012-2020 Klaus Iglberger - All Rights Reserved
7 //
8 //  This file is part of the Blaze library. You can redistribute it and/or modify it under
9 //  the terms of the New (Revised) BSD License. Redistribution and use in source and binary
10 //  forms, with or without modification, are permitted provided that the following conditions
11 //  are met:
12 //
13 //  1. Redistributions of source code must retain the above copyright notice, this list of
14 //     conditions and the following disclaimer.
15 //  2. Redistributions in binary form must reproduce the above copyright notice, this list
16 //     of conditions and the following disclaimer in the documentation and/or other materials
17 //     provided with the distribution.
18 //  3. Neither the names of the Blaze development group nor the names of its contributors
19 //     may be used to endorse or promote products derived from this software without specific
20 //     prior written permission.
21 //
22 //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
23 //  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 //  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25 //  SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 //  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 //  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 //  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 //  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 //  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 //  DAMAGE.
32 */
33 //=================================================================================================
34 
35 #ifndef _BLAZE_SYSTEM_VECTORIZATION_H_
36 #define _BLAZE_SYSTEM_VECTORIZATION_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <blaze/config/Vectorization.h>
44 #include <blaze/util/StaticAssert.h>
45 
46 
47 
48 
49 //=================================================================================================
50 //
51 //  SSE/AVX MACRO DEFINITIONS
52 //
53 //=================================================================================================
54 
55 //*************************************************************************************************
56 /*! \cond BLAZE_INTERNAL */
57 #ifdef __AVX512F__
58 #  ifndef __AVX2__
59 #    define __AVX2__
60 #  endif
61 #endif
62 /*! \endcond */
63 //*************************************************************************************************
64 
65 
66 //*************************************************************************************************
67 /*! \cond BLAZE_INTERNAL */
68 #ifdef __AVX2__
69 #  ifndef __AVX__
70 #    define __AVX__
71 #  endif
72 #endif
73 /*! \endcond */
74 //*************************************************************************************************
75 
76 
77 //*************************************************************************************************
78 /*! \cond BLAZE_INTERNAL */
79 #ifdef __AVX__
80 #  ifndef __MMX__
81 #    define __MMX__
82 #  endif
83 #  ifndef __SSE__
84 #    define __SSE__
85 #  endif
86 #  ifndef __SSE2__
87 #    define __SSE2__
88 #  endif
89 #  ifndef __SSE3__
90 #    define __SSE3__
91 #  endif
92 #  ifndef __SSSE3__
93 #    define __SSSE3__
94 #  endif
95 #  ifndef __SSE4_1__
96 #    define __SSE4_1__
97 #  endif
98 #  ifndef __SSE4_2__
99 #    define __SSE4_2__
100 #  endif
101 #endif
102 /*! \endcond */
103 //*************************************************************************************************
104 
105 
106 
107 
108 //=================================================================================================
109 //
110 //  SSE/AVX/MIC MODE CONFIGURATION
111 //
112 //=================================================================================================
113 
114 //*************************************************************************************************
115 /*!\brief Compilation switch for the SSE mode.
116 // \ingroup system
117 //
118 // This compilation switch enables/disables the SSE mode. In case the SSE mode is enabled
119 // (i.e. in case SSE functionality is available) the Blaze library attempts to vectorize
120 // the linear algebra operations by SSE intrinsics. In case the SSE mode is disabled, the
121 // Blaze library chooses default, non-vectorized functionality for the operations.
122 */
123 #if BLAZE_USE_VECTORIZATION && ( defined(__SSE__) || ( _M_IX86_FP > 0 ) )
124 #  define BLAZE_SSE_MODE 1
125 #else
126 #  define BLAZE_SSE_MODE 0
127 #endif
128 //*************************************************************************************************
129 
130 
131 //*************************************************************************************************
132 /*!\brief Compilation switch for the SSE2 mode.
133 // \ingroup system
134 //
135 // This compilation switch enables/disables the SSE2 mode. In case the SSE2 mode is enabled
136 // (i.e. in case SSE2 functionality is available) the Blaze library attempts to vectorize
137 // the linear algebra operations by SSE2 intrinsics. In case the SSE2 mode is disabled, the
138 // Blaze library chooses default, non-vectorized functionality for the operations.
139 */
140 #if BLAZE_USE_VECTORIZATION && ( defined(__SSE2__) || ( _M_IX86_FP > 1 ) )
141 #  define BLAZE_SSE2_MODE 1
142 #else
143 #  define BLAZE_SSE2_MODE 0
144 #endif
145 //*************************************************************************************************
146 
147 
148 //*************************************************************************************************
149 /*!\brief Compilation switch for the SSE3 mode.
150 // \ingroup system
151 //
152 // This compilation switch enables/disables the SSE3 mode. In case the SSE3 mode is enabled
153 // (i.e. in case SSE3 functionality is available) the Blaze library attempts to vectorize
154 // the linear algebra operations by SSE3 intrinsics. In case the SSE3 mode is disabled, the
155 // Blaze library chooses default, non-vectorized functionality for the operations.
156 */
157 #if BLAZE_USE_VECTORIZATION && defined(__SSE3__)
158 #  define BLAZE_SSE3_MODE 1
159 #else
160 #  define BLAZE_SSE3_MODE 0
161 #endif
162 //*************************************************************************************************
163 
164 
165 //*************************************************************************************************
166 /*!\brief Compilation switch for the SSSE3 mode.
167 // \ingroup system
168 //
169 // This compilation switch enables/disables the SSSE3 mode. In case the SSSE3 mode is enabled
170 // (i.e. in case SSSE3 functionality is available) the Blaze library attempts to vectorize
171 // the linear algebra operations by SSSE3 intrinsics. In case the SSSE3 mode is disabled, the
172 // Blaze library chooses default, non-vectorized functionality for the operations.
173 */
174 #if BLAZE_USE_VECTORIZATION && defined(__SSSE3__)
175 #  define BLAZE_SSSE3_MODE 1
176 #else
177 #  define BLAZE_SSSE3_MODE 0
178 #endif
179 //*************************************************************************************************
180 
181 
182 //*************************************************************************************************
183 /*!\brief Compilation switch for the SSE4 mode.
184 // \ingroup system
185 //
186 // This compilation switch enables/disables the SSE4 mode. In case the SSE4 mode is enabled
187 // (i.e. in case SSE4 functionality is available) the Blaze library attempts to vectorize
188 // the linear algebra operations by SSE4 intrinsics. In case the SSE4 mode is disabled,
189 // the Blaze library chooses default, non-vectorized functionality for the operations.
190 */
191 #if BLAZE_USE_VECTORIZATION && ( defined(__SSE4_2__) || defined(__SSE4_1__) )
192 #  define BLAZE_SSE4_MODE 1
193 #else
194 #  define BLAZE_SSE4_MODE 0
195 #endif
196 //*************************************************************************************************
197 
198 
199 //*************************************************************************************************
200 /*!\brief Compilation switch for the AVX mode.
201 // \ingroup system
202 //
203 // This compilation switch enables/disables the AVX mode. In case the AVX mode is enabled
204 // (i.e. in case AVX functionality is available) the Blaze library attempts to vectorize
205 // the linear algebra operations by AVX intrinsics. In case the AVX mode is disabled,
206 // the Blaze library chooses default, non-vectorized functionality for the operations.
207 */
208 #if BLAZE_USE_VECTORIZATION && defined(__AVX__)
209 #  define BLAZE_AVX_MODE 1
210 #else
211 #  define BLAZE_AVX_MODE 0
212 #endif
213 //*************************************************************************************************
214 
215 
216 //*************************************************************************************************
217 /*!\brief Compilation switch for the AVX2 mode.
218 // \ingroup system
219 //
220 // This compilation switch enables/disables the AVX2 mode. In case the AVX2 mode is enabled
221 // (i.e. in case AVX2 functionality is available) the Blaze library attempts to vectorize
222 // the linear algebra operations by AVX2 intrinsics. In case the AVX2 mode is disabled,
223 // the Blaze library chooses default, non-vectorized functionality for the operations.
224 */
225 #if BLAZE_USE_VECTORIZATION && defined(__AVX2__)
226 #  define BLAZE_AVX2_MODE 1
227 #else
228 #  define BLAZE_AVX2_MODE 0
229 #endif
230 //*************************************************************************************************
231 
232 
233 //*************************************************************************************************
234 /*!\brief Compilation switch for the AVX512F mode.
235 // \ingroup system
236 //
237 // This compilation switch enables/disables the AVX512F mode. In case the AVX512F mode is
238 // enabled (i.e. in case AVX512F functionality is available) the Blaze library attempts to
239 // vectorize the linear algebra operations by AVX512F intrinsics. In case the AVX512F mode
240 // is disabled, the Blaze library chooses default, non-vectorized functionality for the
241 // operations.
242 */
243 #if BLAZE_USE_VECTORIZATION && defined(__AVX512F__)
244 #  define BLAZE_AVX512F_MODE 1
245 #else
246 #  define BLAZE_AVX512F_MODE 0
247 #endif
248 //*************************************************************************************************
249 
250 
251 //*************************************************************************************************
252 /*!\brief Compilation switch for the AVX512BW mode.
253 // \ingroup system
254 //
255 // This compilation switch enables/disables the AVX512BW mode. In case the AVX512BW mode is
256 // enabled (i.e. in case AVX512BW functionality is available) the Blaze library attempts to
257 // vectorize the linear algebra operations by AVX512BW intrinsics. In case the AVX512BW mode
258 // is disabled, the Blaze library chooses default, non-vectorized functionality for the
259 // operations.
260 */
261 #if BLAZE_USE_VECTORIZATION && defined(__AVX512BW__)
262 #  define BLAZE_AVX512BW_MODE 1
263 #else
264 #  define BLAZE_AVX512BW_MODE 0
265 #endif
266 //*************************************************************************************************
267 
268 
269 //*************************************************************************************************
270 /*!\brief Compilation switch for the AVX512DQ mode.
271 // \ingroup system
272 //
273 // This compilation switch enables/disables the AVX512DQ mode. In case the AVX512DQ mode is
274 // enabled (i.e. in case AVX512DQ functionality is available) the Blaze library attempts to
275 // vectorize the linear algebra operations by AVX512DQ intrinsics. In case the AVX512DQ mode
276 // is disabled, the Blaze library chooses default, non-vectorized functionality for the
277 // operations.
278 */
279 #if BLAZE_USE_VECTORIZATION && defined(__AVX512DQ__)
280 #  define BLAZE_AVX512DQ_MODE 1
281 #else
282 #  define BLAZE_AVX512DQ_MODE 0
283 #endif
284 //*************************************************************************************************
285 
286 
287 //*************************************************************************************************
288 /*!\brief Compilation switch for the MIC mode.
289 // \ingroup system
290 //
291 // This compilation switch enables/disables the MIC mode. In case the MIC mode is enabled
292 // (i.e. in case MIC functionality is available) the Blaze library attempts to vectorize
293 // the linear algebra operations by MIC intrinsics. In case the MIC mode is disabled,
294 // the Blaze library chooses default, non-vectorized functionality for the operations.
295 */
296 #if BLAZE_USE_VECTORIZATION && defined(__MIC__)
297 #  define BLAZE_MIC_MODE 1
298 #else
299 #  define BLAZE_MIC_MODE 0
300 #endif
301 //*************************************************************************************************
302 
303 
304 
305 
306 //=================================================================================================
307 //
308 //  FMA MODE CONFIGURATION
309 //
310 //=================================================================================================
311 
312 //*************************************************************************************************
313 /*!\brief Compilation switch for the FMA mode.
314 // \ingroup system
315 //
316 // This compilation switch enables/disables the FMA mode. In case the FMA mode is enabled
317 // (i.e. in case FMA functionality is available) the Blaze library attempts to vectorize
318 // the linear algebra operations by FMA intrinsics. In case the FMA mode is disabled,
319 // the Blaze library chooses default, non-vectorized functionality for the operations.
320 */
321 #if BLAZE_USE_VECTORIZATION && defined(__FMA__)
322 #  define BLAZE_FMA_MODE 1
323 #else
324 #  define BLAZE_FMA_MODE 0
325 #endif
326 //*************************************************************************************************
327 
328 
329 
330 
331 //=================================================================================================
332 //
333 //  SVML MODE CONFIGURATION
334 //
335 //=================================================================================================
336 
337 //*************************************************************************************************
338 /*!\brief Compilation switch for the SVML mode.
339 // \ingroup system
340 //
341 // This compilation switch enables/disables the SVML mode. In case the SVML mode is enabled
342 // (i.e. in case an Intel compiler is used) the Blaze library attempts to vectorize several
343 // linear algebra operations by SVML intrinsics. In case the SVML mode is disabled, the
344 // Blaze library chooses default, non-vectorized functionality for the operations.
345 */
346 #if BLAZE_USE_VECTORIZATION && ( defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) )
347 #  define BLAZE_SVML_MODE 1
348 #else
349 #  define BLAZE_SVML_MODE 0
350 #endif
351 //*************************************************************************************************
352 
353 
354 //*************************************************************************************************
355 /*!\brief Compilation switch for the Sleef mode.
356 // \ingroup system
357 //
358 // This compilation switch enables/disables the Sleef mode. In case the Sleef mode is enabled
359 // the Blaze library attempts to vectorize several linear algebra operations by Sleef intrinsics.
360 // In case the Sleef mode is disabled, the Blaze library chooses default, non-vectorized
361 // functionality for the operations.
362 */
363 #if BLAZE_USE_VECTORIZATION && BLAZE_USE_SLEEF
364 #  define BLAZE_SLEEF_MODE 1
365 #else
366 #  define BLAZE_SLEEF_MODE 0
367 #endif
368 //*************************************************************************************************
369 
370 
371 
372 
373 //=================================================================================================
374 //
375 //  COMPILE TIME CONSTRAINTS
376 //
377 //=================================================================================================
378 
379 //*************************************************************************************************
380 /*! \cond BLAZE_INTERNAL */
381 namespace {
382 
383 BLAZE_STATIC_ASSERT( !BLAZE_SSE2_MODE     || BLAZE_SSE_MODE     );
384 BLAZE_STATIC_ASSERT( !BLAZE_SSE3_MODE     || BLAZE_SSE2_MODE    );
385 BLAZE_STATIC_ASSERT( !BLAZE_SSSE3_MODE    || BLAZE_SSE3_MODE    );
386 BLAZE_STATIC_ASSERT( !BLAZE_SSE4_MODE     || BLAZE_SSSE3_MODE   );
387 BLAZE_STATIC_ASSERT( !BLAZE_AVX_MODE      || BLAZE_SSE4_MODE    );
388 BLAZE_STATIC_ASSERT( !BLAZE_AVX2_MODE     || BLAZE_AVX_MODE     );
389 BLAZE_STATIC_ASSERT( !BLAZE_AVX512F_MODE  || BLAZE_AVX2_MODE    );
390 BLAZE_STATIC_ASSERT( !BLAZE_AVX512BW_MODE || BLAZE_AVX512F_MODE );
391 BLAZE_STATIC_ASSERT( !BLAZE_AVX512DQ_MODE || BLAZE_AVX512F_MODE );
392 
393 }
394 /*! \endcond */
395 //*************************************************************************************************
396 
397 
398 
399 
400 //=================================================================================================
401 //
402 //  SSE/AVX/MIC INCLUDE FILE CONFIGURATION
403 //
404 //=================================================================================================
405 
406 #if BLAZE_AVX512F_MODE || BLAZE_MIC_MODE || BLAZE_AVX2_MODE || BLAZE_AVX_MODE
407 #  include <immintrin.h>
408 #elif BLAZE_SSE4_MODE
409 #  include <smmintrin.h>
410 #elif BLAZE_SSSE3_MODE
411 #  include <tmmintrin.h>
412 #elif BLAZE_SSE3_MODE
413 #  include <pmmintrin.h>
414 #elif BLAZE_SSE2_MODE
415 #  include <emmintrin.h>
416 #elif BLAZE_SSE_MODE
417 #  include <xmmintrin.h>
418 #endif
419 
420 #endif
421