LAL  7.5.0.1-08ee4f4
simd_dispatch.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Reinhard Prix, Karl Wette
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with with program; see the file COPYING. If not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17  * MA 02110-1301 USA
18  */
19 
20 #if !defined(HAVE_SIMD_COMPILER)
21 #error "simd_dispatch.h must be included after config.h"
22 #endif
23 
24 #include <lal/LALSIMD.h>
25 #include <lal/XLALError.h>
26 
27 /*
28  * Helper macros for performing runtime dispatch using function pointers
29  * Sample usage:
30  *
31  * int SIMDFunction(...);
32  *
33  * int SIMDFunction_GEN(...);
34  * int SIMDFunction_SSE(...);
35  * int SIMDFunction_AVX(...);
36  * ...
37  *
38  * static int SIMDFunction_DISPATCH(...);
39  * static int (*SIMDFunctionPtr)(...) = SIMDFunction_DISPATCH;
40  *
41  * int SIMDFunction(...) {
42  * return (SIMDFunctionPtr)(...);
43  * }
44  *
45  * static int SIMDFunction_DISPATCH(...) {
46  * DISPATCH_SELECT_BEGIN();
47  * DISPATCH_SELECT_AVX(SIMDFunctionPtr = SIMDFunction_AVX);
48  * DISPATCH_SELECT_SSE(SIMDFunctionPtr = SIMDFunction_SSE);
49  * DISPATCH_SELECT_END(SIMDFunctionPtr = SIMDFunction_GEN);
50  * return SIMDFunction(...);
51  * }
52  */
53 #define DISPATCH_SELECT_BEGIN() do { do { } while(0)
54 #define DISPATCH_SELECT_END(...) (__VA_ARGS__); } while (0)
55 #define DISPATCH_SELECT_NONE(...) do { } while(0)
56 
57 #if defined(HAVE_SSE_COMPILER) /* set by config.h if compiler supports SSE */
58 #define DISPATCH_SELECT_SSE(...) if (LAL_HAVE_SSE_RUNTIME()) { (__VA_ARGS__); break; } do { } while(0)
59 #else
60 #define DISPATCH_SELECT_SSE(...) DISPATCH_SELECT_NONE()
61 #endif
62 
63 #if defined(HAVE_SSE2_COMPILER) /* set by config.h if compiler supports SSE2 */
64 #define DISPATCH_SELECT_SSE2(...) if (LAL_HAVE_SSE2_RUNTIME()) { (__VA_ARGS__); break; } do { } while(0)
65 #else
66 #define DISPATCH_SELECT_SSE2(...) DISPATCH_SELECT_NONE()
67 #endif
68 
69 #if defined(HAVE_SSE3_COMPILER) /* set by config.h if compiler supports SSE3 */
70 #define DISPATCH_SELECT_SSE3(...) if (LAL_HAVE_SSE3_RUNTIME()) { (__VA_ARGS__); break; } do { } while(0)
71 #else
72 #define DISPATCH_SELECT_SSE3(...) DISPATCH_SELECT_NONE()
73 #endif
74 
75 #if defined(HAVE_SSSE3_COMPILER) /* set by config.h if compiler supports SSSE3 */
76 #define DISPATCH_SELECT_SSSE3(...) if (LAL_HAVE_SSSE3_RUNTIME()) { (__VA_ARGS__); break; } do { } while(0)
77 #else
78 #define DISPATCH_SELECT_SSSE3(...) DISPATCH_SELECT_NONE()
79 #endif
80 
81 #if defined(HAVE_SSE4_1_COMPILER) /* set by config.h if compiler supports SSE4_1 */
82 #define DISPATCH_SELECT_SSE4_1(...) if (LAL_HAVE_SSE4_1_RUNTIME()) { (__VA_ARGS__); break; } do { } while(0)
83 #else
84 #define DISPATCH_SELECT_SSE4_1(...) DISPATCH_SELECT_NONE()
85 #endif
86 
87 #if defined(HAVE_SSE4_2_COMPILER) /* set by config.h if compiler supports SSE4_2 */
88 #define DISPATCH_SELECT_SSE4_2(...) if (LAL_HAVE_SSE4_2_RUNTIME()) { (__VA_ARGS__); break; } do { } while(0)
89 #else
90 #define DISPATCH_SELECT_SSE4_2(...) DISPATCH_SELECT_NONE()
91 #endif
92 
93 #if defined(HAVE_AVX_COMPILER) /* set by config.h if compiler supports AVX */
94 #define DISPATCH_SELECT_AVX(...) if (LAL_HAVE_AVX_RUNTIME()) { (__VA_ARGS__); break; } do { } while(0)
95 #else
96 #define DISPATCH_SELECT_AVX(...) DISPATCH_SELECT_NONE()
97 #endif
98 
99 #if defined(HAVE_AVX2_COMPILER) /* set by config.h if compiler supports AVX2 */
100 #define DISPATCH_SELECT_AVX2(...) if (LAL_HAVE_AVX2_RUNTIME()) { (__VA_ARGS__); break; } do { } while(0)
101 #else
102 #define DISPATCH_SELECT_AVX2(...) DISPATCH_SELECT_NONE()
103 #endif