50 #include <lal/LALSIMD.h>
51 #include <lal/LALConfig.h>
52 #include <lal/LALError.h>
53 #include <lal/XLALError.h>
54 #include <lal/LALString.h>
57 #if defined(__x86_64__) || defined(_M_X64)
59 #elif defined(__i386) || defined(_M_IX86)
65 #if HAVE_X86 && ( defined(__GNUC__) || defined(__clang__) ) && defined(HAVE_CPUID_H)
67 #define HAVE__GET_CPUID 1
71 #define UNUSED __attribute__ ((unused))
93 #ifdef LAL_PTHREAD_LOCK
95 static pthread_once_t
lalOnce = PTHREAD_ONCE_INIT;
96 #define LAL_ONCE(init) pthread_once(&lalOnce, (init))
99 #define LAL_ONCE(init) (lalOnce ? (init)(), lalOnce = 0 : 0)
107 static inline UNUSED
void cpuid( uint32_t
output[4], UNUSED
int functionnumber ) {
115 #elif defined(__GNUC__) || defined(__clang__)
123 mov eax, functionnumber
148 static inline UNUSED int64_t
xgetbv( UNUSED
int ctr ) {
152 #if defined(__GNUC__) || defined(__clang__)
156 __asm__(
".byte 0x0f,0x01,0xd0" \
160 return a | (((uint64_t) d) << 32);
174 return a | (((uint64_t) d) << 32);
192 uint32_t abcd[4] = {0, 0, 0, 0};
197 if (abcd[0] == 0)
return iset;
199 if ((abcd[3] & (1 << 0)) == 0)
return iset;
200 if ((abcd[3] & (1 << 23)) == 0)
return iset;
201 if ((abcd[3] & (1 << 15)) == 0)
return iset;
202 if ((abcd[3] & (1 << 24)) == 0)
return iset;
203 if ((abcd[3] & (1 << 25)) == 0)
return iset;
206 if ((abcd[3] & (1 << 26)) == 0)
return iset;
209 if ((abcd[2] & (1 << 0)) == 0)
return iset;
212 if ((abcd[2] & (1 << 9)) == 0)
return iset;
215 if ((abcd[2] & (1 << 19)) == 0)
return iset;
218 if ((abcd[2] & (1 << 23)) == 0)
return iset;
219 if ((abcd[2] & (1 << 20)) == 0)
return iset;
222 if ((abcd[2] & (1 << 27)) == 0)
return iset;
223 if ((
xgetbv(0) & 6) != 6)
return iset;
224 if ((abcd[2] & (1 << 28)) == 0)
return iset;
227 #if HAVE_X86 && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
229 if (!__builtin_cpu_supports(
"avx2"))
return iset;
232 if ((abcd[1] & (1 << 5)) == 0)
return iset;
248 lalAbortHook(
"%s: SIMD instruction set detection failed!!\n", __func__);
253 const char *env = getenv(
"LAL_SIMD_ISET");
254 if (env == NULL || *env ==
'\0') {
267 lalAbortHook(
"%s: LAL_SIMD_ISET='%s' does not match a SIMD instruction set\n", __func__, env);
273 lalAbortHook(
"%s: LAL_SIMD_ISET='%s' is not available on this machine\n", __func__, env);
void(* lalAbortHook)(const char *,...)
static UNUSED void cpuid(uint32_t output[4], UNUSED int functionnumber)
static UNUSED int64_t xgetbv(UNUSED int ctr)
static LAL_SIMD_ISET detect_instruction_set(void)
static void select_instruction_set(void)
static const char *const iset_names[LAL_SIMD_ISET_MAX]
static LAL_SIMD_ISET selected_iset
const char * XLALSIMDInstructionSetName(LAL_SIMD_ISET iset)
Return the name of a given instruction set as a string.
int XLALHaveSIMDInstructionSet(LAL_SIMD_ISET iset)
Return true if the executing machine supports the given instruction set.
LAL_SIMD_ISET
SIMD instruction sets this module can detect.
@ LAL_SIMD_ISET_SSE4_1
SSE version 4.1.
@ LAL_SIMD_ISET_SSE3
SSE version 3.
@ LAL_SIMD_ISET_SSE
SSE (Streaming SIMD Extensions)
@ LAL_SIMD_ISET_AVX2
AVX version 2.
@ LAL_SIMD_ISET_SSE4_2
SSE version 4.2.
@ LAL_SIMD_ISET_SSE2
SSE version 2.
@ LAL_SIMD_ISET_GEN
GENeric floating-point unit.
@ LAL_SIMD_ISET_AVX
AVX (Advanced Vector Extensions)
@ LAL_SIMD_ISET_SSSE3
Supplemental SSE version 3.
int XLALStringCaseCompare(const char *s1, const char *s2)
Compare two strings, ignoring case and without using locale-dependent functions.
#define XLAL_CHECK_NULL(assertion,...)
Macro to test an assertion and invoke a failure if it is not true in a function that returns a pointe...
@ XLAL_EINVAL
Invalid argument.
void output(int gps_sec, int output_type)