Tone down note about not pinning threads
[gromacs.git] / cmake / gmxManageSimd.cmake
blob12e25a7a6a723c3ba9281840b767256aa90f4e01
2 # This file is part of the GROMACS molecular simulation package.
4 # Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
5 # Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 # and including many others, as listed in the AUTHORS file in the
7 # top-level source directory and at http://www.gromacs.org.
9 # GROMACS is free software; you can redistribute it and/or
10 # modify it under the terms of the GNU Lesser General Public License
11 # as published by the Free Software Foundation; either version 2.1
12 # of the License, or (at your option) any later version.
14 # GROMACS is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 # Lesser General Public License for more details.
19 # You should have received a copy of the GNU Lesser General Public
20 # License along with GROMACS; if not, see
21 # http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
24 # If you want to redistribute modifications to GROMACS, please
25 # consider that scientific software is very special. Version
26 # control is crucial - bugs must be traceable. We will be happy to
27 # consider code for inclusion in the official distribution, but
28 # derived work must not be called official GROMACS. Details are found
29 # in the README & COPYING files - if they are missing, get the
30 # official version at http://www.gromacs.org.
32 # To help us fund GROMACS development, we humbly ask that you cite
33 # the research papers on the package. Check out http://www.gromacs.org.
35 include(gmxDetectCpu)
36 include(gmxSimdFlags)
38 # Issue a fatal error with an appropriate message, when the toolchain
39 # was not able to compile code for SIMD support.
41 # Inputs:
42 #  SIMD_STRING              A string describing the kind of SIMD support that didn't work.
43 #  ALTERNATIVE_SUGGESTION   A string describing anything the user could try other than getting a new compiler.
44 #  SUGGEST_BINUTILS_UPDATE  True when there's information that the compiler was OK, but something else was not.
45 function(gmx_give_fatal_error_when_simd_support_not_found SIMD_STRING ALTERNATIVE_SUGGESTION SUGGEST_BINUTILS_UPDATE)
46     if(SUGGEST_BINUTILS_UPDATE)
47         set(_msg "Found a compiler flag for ${SIMD_STRING} support, but some other problem exists. Update your assembler and/or linker, e.g. in the binutils package of your distribution.")
48     else()
49         set(_msg "Cannot find ${SIMD_STRING} compiler flag. Use a newer compiler, or ${ALTERNATIVE_SUGGESTION}.")
50     endif()
51     message(FATAL_ERROR ${_msg})
52 endfunction()
54 macro(gmx_manage_simd)
56 set(GMX_SIMD_ACCURACY_BITS_SINGLE 22 CACHE STRING "Target mantissa bits for SIMD single math")
58 # Note that we typically restrict double precision target accuracy to be twice that
59 # of single. This means we only need one more N-R iteration for 1/sqrt(x) and 1(x),
60 # and the first iteration can sometimes be done as a pair in single precision. This should
61 # be plenty enough for Molecular Dynamics applications. Many of our double precision math
62 # functions still achieve very close to full double precision, but we do not guarantee that
63 # they will be able to achieve higher accuracy if you set this beyond 44 bits. GROMACS will
64 # work - but some unit tests might fail.
66 set(GMX_SIMD_ACCURACY_BITS_DOUBLE 44 CACHE STRING "Target mantissa bits for SIMD double math")
67 mark_as_advanced(GMX_SIMD_ACCURACY_BITS_SINGLE)
68 mark_as_advanced(GMX_SIMD_ACCURACY_BITS_DOUBLE)
70 if(${GMX_SIMD_ACCURACY_BITS_SINGLE} GREATER 22)
71     message(STATUS "Note: Full mantissa accuracy (including least significant bit) requested for SIMD single math. Presently we cannot get the least significant bit correct since that would require different algorithms - reducing to 22 bits.")
72     set(GMX_SIMD_ACCURACY_BITS_SINGLE 22 CACHE STRING "Target mantissa bits for SIMD single math" FORCE)
73 endif()
75 if(${GMX_SIMD_ACCURACY_BITS_DOUBLE} GREATER 51)
76     message(STATUS "Note: Full mantissa accuracy (including least significant bit) requested for SIMD double math. Presently we cannot get the least significant bit correct since that would require different algorithms - reducing to 51 bits.")
77     set(GMX_SIMD_ACCURACY_BITS_DOUBLE 51 CACHE STRING "Target mantissa bits for SIMD double math" FORCE)
78 endif()
81 # Section to set (and test) compiler flags for SIMD.
83 # If the user chose the (default) automatic behaviour, then detection
84 # is run to suggest a SIMD choice suitable for the build
85 # host. Otherwise, the users's choice is always honoured. The compiler
86 # flags will be set based on that choice.
89 set(GMX_SIMD_ACTIVE ${GMX_SIMD})
90 if(GMX_SIMD STREQUAL "AUTO")
91     include(gmxDetectSimd)
92     gmx_detect_simd(GMX_SUGGESTED_SIMD)
93     set(GMX_SIMD_ACTIVE ${GMX_SUGGESTED_SIMD})
94 endif()
96 if(GMX_SIMD_ACTIVE STREQUAL "NONE")
97     # nothing to do configuration-wise
98     set(SIMD_STATUS_MESSAGE "SIMD instructions disabled")
99 elseif(GMX_SIMD_ACTIVE STREQUAL "SSE2")
101     gmx_find_simd_sse2_flags(SIMD_SSE2_C_SUPPORTED SIMD_SSE2_CXX_SUPPORTED
102                              SIMD_SSE2_C_FLAGS SIMD_SSE2_CXX_FLAGS)
104     if(NOT SIMD_SSE2_C_SUPPORTED OR NOT SIMD_SSE2_CXX_SUPPORTED)
105         gmx_give_fatal_error_when_simd_support_not_found("SSE2" "disable SIMD support (slow)" "${SUGGEST_BINUTILS_UPDATE}")
106     endif()
108     set(SIMD_C_FLAGS "${SIMD_SSE2_C_FLAGS}")
109     set(SIMD_CXX_FLAGS "${SIMD_SSE2_CXX_FLAGS}")
110     set(GMX_SIMD_X86_${GMX_SIMD_ACTIVE} 1)
111     set(SIMD_STATUS_MESSAGE "Enabling SSE2 SIMD instructions using CXX flags: ${SIMD_SSE2_CXX_FLAGS}")
113 elseif(GMX_SIMD_ACTIVE STREQUAL "SSE4.1")
115     gmx_find_simd_sse4_1_flags(SIMD_SSE4_1_C_SUPPORTED SIMD_SSE4_1_CXX_SUPPORTED
116                                SIMD_SSE4_1_C_FLAGS SIMD_SSE4_1_CXX_FLAGS)
118     if(NOT SIMD_SSE4_1_C_SUPPORTED OR NOT SIMD_SSE4_1_CXX_SUPPORTED)
119         gmx_give_fatal_error_when_simd_support_not_found("SSE4.1" "choose SSE2 SIMD (slower)" "${SUGGEST_BINUTILS_UPDATE}")
120     endif()
122     set(SIMD_C_FLAGS "${SIMD_SSE4_1_C_FLAGS}")
123     set(SIMD_CXX_FLAGS "${SIMD_SSE4_1_CXX_FLAGS}")
124     set(GMX_SIMD_X86_SSE4_1 1)
125     set(SIMD_STATUS_MESSAGE "Enabling SSE4.1 SIMD instructions using CXX flags: ${SIMD_SSE4_1_CXX_FLAGS}")
127 elseif(GMX_SIMD_ACTIVE STREQUAL "AVX_128_FMA")
129     gmx_find_simd_avx_128_fma_flags(SIMD_AVX_128_FMA_C_SUPPORTED SIMD_AVX_128_FMA_CXX_SUPPORTED
130                                     SIMD_AVX_128_FMA_C_FLAGS SIMD_AVX_128_FMA_CXX_FLAGS)
132     if(NOT SIMD_AVX_128_FMA_C_SUPPORTED OR NOT SIMD_AVX_128_FMA_CXX_SUPPORTED)
133         gmx_give_fatal_error_when_simd_support_not_found("128-bit AVX with FMA support" "choose SSE4.1 SIMD (slower)" "${SUGGEST_BINUTILS_UPDATE}")
134     endif()
136     set(SIMD_C_FLAGS "${SIMD_AVX_128_FMA_C_FLAGS}")
137     set(SIMD_CXX_FLAGS "${SIMD_AVX_128_FMA_CXX_FLAGS}")
138     set(GMX_SIMD_X86_${GMX_SIMD_ACTIVE} 1)
139     set(SIMD_STATUS_MESSAGE "Enabling 128-bit AMD FMA SIMD instructions using CXX flags: ${SIMD_AVX_128_FMA_CXX_FLAGS}")
141 elseif(GMX_SIMD_ACTIVE STREQUAL "AVX_256")
143     gmx_find_simd_avx_flags(SIMD_AVX_C_SUPPORTED SIMD_AVX_CXX_SUPPORTED
144                             SIMD_AVX_C_FLAGS SIMD_AVX_CXX_FLAGS)
146     if(NOT SIMD_AVX_C_SUPPORTED OR NOT SIMD_AVX_CXX_SUPPORTED)
147         gmx_give_fatal_error_when_simd_support_not_found("AVX" "choose SSE4.1 SIMD (slower)" "${SUGGEST_BINUTILS_UPDATE}")
148     endif()
150     set(SIMD_C_FLAGS "${SIMD_AVX_C_FLAGS}")
151     set(SIMD_CXX_FLAGS "${SIMD_AVX_CXX_FLAGS}")
152     set(GMX_SIMD_X86_${GMX_SIMD_ACTIVE} 1)
153     set(SIMD_STATUS_MESSAGE "Enabling 256-bit AVX SIMD instructions using CXX flags: ${SIMD_AVX_CXX_FLAGS}")
155 elseif(GMX_SIMD_ACTIVE MATCHES "AVX2_")
157     gmx_find_simd_avx2_flags(SIMD_AVX2_C_SUPPORTED SIMD_AVX2_CXX_SUPPORTED
158                              SIMD_AVX2_C_FLAGS SIMD_AVX2_CXX_FLAGS)
160     if(NOT SIMD_AVX2_C_SUPPORTED OR NOT SIMD_AVX2_CXX_SUPPORTED)
161         gmx_give_fatal_error_when_simd_support_not_found("AVX2" "choose AVX SIMD (slower)" "${SUGGEST_BINUTILS_UPDATE}")
162     endif()
164     set(SIMD_C_FLAGS "${SIMD_AVX2_C_FLAGS}")
165     set(SIMD_CXX_FLAGS "${SIMD_AVX2_CXX_FLAGS}")
166     set(GMX_SIMD_X86_${GMX_SIMD_ACTIVE} 1)
168     if(GMX_SIMD_ACTIVE STREQUAL "AVX2_128")
169         set(SIMD_STATUS_MESSAGE "Enabling 128-bit AVX2 SIMD instructions using CXX flags: ${SIMD_AVX2_CXX_FLAGS}")
170     else()
171         set(SIMD_STATUS_MESSAGE "Enabling 256-bit AVX2 SIMD instructions using CXX flags: ${SIMD_AVX2_CXX_FLAGS}")
172     endif()
174 elseif(GMX_SIMD_ACTIVE STREQUAL "MIC")
176     # No flags needed. Not testing.
177     set(GMX_SIMD_X86_MIC 1)
178     set(SIMD_STATUS_MESSAGE "Enabling MIC (Xeon Phi) SIMD instructions without special flags.")
180 elseif(GMX_SIMD_ACTIVE STREQUAL "AVX_512")
182     gmx_find_simd_avx_512_flags(SIMD_AVX_512_C_SUPPORTED SIMD_AVX_512_CXX_SUPPORTED
183                                 SIMD_AVX_512_C_FLAGS SIMD_AVX_512_CXX_FLAGS)
185     if(NOT SIMD_AVX_512_C_SUPPORTED OR NOT SIMD_AVX_512_CXX_SUPPORTED)
186         gmx_give_fatal_error_when_simd_support_not_found("AVX 512F" "choose a lower level of SIMD (slower)" "${SUGGEST_BINUTILS_UPDATE}")
187     endif()
189     set(SIMD_C_FLAGS "${SIMD_AVX_512_C_FLAGS}")
190     set(SIMD_CXX_FLAGS "${SIMD_AVX_512_CXX_FLAGS}")
191     set(GMX_SIMD_X86_${GMX_SIMD_ACTIVE} 1)
192     set(SIMD_STATUS_MESSAGE "Enabling 512-bit AVX-512 SIMD instructions using CXX flags: ${SIMD_AVX_512_CXX_FLAGS}")
194 elseif(GMX_SIMD_ACTIVE STREQUAL "AVX_512_KNL")
196     gmx_find_simd_avx_512_knl_flags(SIMD_AVX_512_KNL_C_SUPPORTED SIMD_AVX_512_KNL_CXX_SUPPORTED
197                                     SIMD_AVX_512_KNL_C_FLAGS SIMD_AVX_512_KNL_CXX_FLAGS)
199     if(NOT SIMD_AVX_512_KNL_C_SUPPORTED OR NOT SIMD_AVX_512_KNL_CXX_SUPPORTED)
200         gmx_give_fatal_error_when_simd_support_not_found("AVX 512ER" "choose a lower level of SIMD (slower)" "${SUGGEST_BINUTILS_UPDATE}")
201     endif()
203     set(SIMD_C_FLAGS "${SIMD_AVX_512_KNL_C_FLAGS}")
204     set(SIMD_CXX_FLAGS "${SIMD_AVX_512_KNL_CXX_FLAGS}")
205     set(GMX_SIMD_X86_${GMX_SIMD_ACTIVE} 1)
206     set(SIMD_STATUS_MESSAGE "Enabling 512-bit AVX-512-KNL SIMD instructions using CXX flags: ${SIMD_AVX_512_KNL_CXX_FLAGS}")
208 elseif(GMX_SIMD_ACTIVE STREQUAL "ARM_NEON")
210     if (GMX_DOUBLE)
211         message(FATAL_ERROR "ARM_NEON SIMD support is not available for a double precision build because the architecture lacks double-precision support")
212     endif()
214     gmx_find_simd_arm_neon_flags(SIMD_ARM_NEON_C_SUPPORTED SIMD_ARM_NEON_CXX_SUPPORTED
215                                  SIMD_ARM_NEON_C_FLAGS SIMD_ARM_NEON_CXX_FLAGS)
217     if(NOT SIMD_ARM_NEON_C_SUPPORTED OR NOT SIMD_ARM_NEON_CXX_SUPPORTED)
218         gmx_give_fatal_error_when_simd_support_not_found("ARM NEON" "disable SIMD support (slower)" "${SUGGEST_BINUTILS_UPDATE}")
219     endif()
221     set(SIMD_C_FLAGS "${SIMD_ARM_NEON_C_FLAGS}")
222     set(SIMD_CXX_FLAGS "${SIMD_ARM_NEON_CXX_FLAGS}")
223     set(GMX_SIMD_${GMX_SIMD_ACTIVE} 1)
224     set(SIMD_STATUS_MESSAGE "Enabling 32-bit ARM NEON SIMD instructions using CXX flags: ${SIMD_ARM_NEON_CXX_FLAGS}")
226 elseif(GMX_SIMD_ACTIVE STREQUAL "ARM_NEON_ASIMD")
228     gmx_find_simd_arm_neon_asimd_flags(SIMD_ARM_NEON_ASIMD_C_SUPPORTED SIMD_ARM_NEON_ASIMD_CXX_SUPPORTED
229                                        SIMD_ARM_NEON_ASIMD_C_FLAGS SIMD_ARM_NEON_ASIMD_CXX_FLAGS)
231     if(NOT SIMD_ARM_NEON_ASIMD_C_SUPPORTED OR NOT SIMD_ARM_NEON_ASIMD_CXX_SUPPORTED)
232         gmx_give_fatal_error_when_simd_support_not_found("ARM (AArch64) NEON Advanced SIMD" "particularly gcc version 4.9 or later, or disable SIMD support (slower)" "${SUGGEST_BINUTILS_UPDATE}")
233     endif()
235     set(SIMD_C_FLAGS "${SIMD_ARM_NEON_ASIMD_C_FLAGS}")
236     set(SIMD_CXX_FLAGS "${SIMD_ARM_NEON_ASIMD_CXX_FLAGS}")
237     set(GMX_SIMD_${GMX_SIMD_ACTIVE} 1)
238     set(SIMD_STATUS_MESSAGE "Enabling ARM (AArch64) NEON Advanced SIMD instructions using CXX flags: ${SIMD_ARM_NEON_ASIMD_CXX_FLAGS}")
240 elseif(GMX_SIMD_ACTIVE STREQUAL "IBM_QPX")
242     try_compile(TEST_QPX ${CMAKE_BINARY_DIR}
243         "${CMAKE_SOURCE_DIR}/cmake/TestQPX.c")
245     if (TEST_QPX)
246         set(GMX_SIMD_${GMX_SIMD_ACTIVE} 1)
247         set(SIMD_STATUS_MESSAGE "Enabling IBM QPX SIMD instructions without special flags.")
248     else()
249         gmx_give_fatal_error_when_simd_support_not_found("IBM QPX" "or 'cmake .. -DCMAKE_TOOLCHAIN_FILE=Platform/BlueGeneQ-static-bgclang-CXX' to set up the tool chain" "${SUGGEST_BINUTILS_UPDATE}")
250     endif()
252 elseif(GMX_SIMD_ACTIVE STREQUAL "IBM_VMX")
254     gmx_find_simd_ibm_vmx_flags(SIMD_IBM_VMX_C_SUPPORTED SIMD_IBM_VMX_CXX_SUPPORTED
255                                 SIMD_IBM_VMX_C_FLAGS SIMD_IBM_VMX_CXX_FLAGS)
257     if(NOT SIMD_IBM_VMX_C_SUPPORTED OR NOT SIMD_IBM_VMX_CXX_SUPPORTED)
258         gmx_give_fatal_error_when_simd_support_not_found("IBM VMX" "disable SIMD support (slower)" "${SUGGEST_BINUTILS_UPDATE}")
259     endif()
261     set(SIMD_C_FLAGS "${SIMD_IBM_VMX_C_FLAGS}")
262     set(SIMD_CXX_FLAGS "${SIMD_IBM_VMX_CXX_FLAGS}")
263     set(GMX_SIMD_${GMX_SIMD_ACTIVE} 1)
264     set(SIMD_STATUS_MESSAGE "Enabling IBM VMX SIMD instructions using CXX flags: ${SIMD_IBM_VMX_CXX_FLAGS}")
266 elseif(GMX_SIMD_ACTIVE STREQUAL "IBM_VSX")
268     gmx_find_simd_ibm_vsx_flags(SIMD_IBM_VSX_C_SUPPORTED SIMD_IBM_VSX_CXX_SUPPORTED
269                                 SIMD_IBM_VSX_C_FLAGS SIMD_IBM_VSX_CXX_FLAGS)
271     # Usually we check also for the C compiler here, but a C compiler
272     # is not required for SIMD support on this platform. cmake through
273     # at least version 3.7 cannot pass this check with the C compiler
274     # in the latest xlc 13.1.5, but the C++ compiler has different
275     # behaviour and is OK. See Redmine #2102.
276     if(NOT SIMD_IBM_VSX_CXX_SUPPORTED)
277         gmx_give_fatal_error_when_simd_support_not_found("IBM VSX" "disable SIMD support (slower)" "${SUGGEST_BINUTILS_UPDATE}")
278     endif()
280     set(SIMD_C_FLAGS "${SIMD_IBM_VSX_C_FLAGS}")
281     set(SIMD_CXX_FLAGS "${SIMD_IBM_VSX_CXX_FLAGS}")
282     set(GMX_SIMD_${GMX_SIMD_ACTIVE} 1)
283     set(SIMD_STATUS_MESSAGE "Enabling IBM VSX SIMD instructions using CXX flags: ${SIMD_IBM_VSX_CXX_FLAGS}")
285 elseif(GMX_SIMD_ACTIVE STREQUAL "SPARC64_HPC_ACE")
287     # Note that GMX_RELAXED_DOUBLE_PRECISION is enabled by default in the top-level CMakeLists.txt
289     set(GMX_SIMD_${GMX_SIMD_ACTIVE} 1)
290     set(SIMD_STATUS_MESSAGE "Enabling Sparc64 HPC-ACE SIMD instructions without special flags.")
292 elseif(GMX_SIMD_ACTIVE STREQUAL "REFERENCE")
294     # NB: This file handles settings for the SIMD module, so in the interest 
295     # of proper modularization, please do NOT put any verlet kernel settings in this file.
297     if(GMX_SIMD_REF_FLOAT_WIDTH)
298         add_definitions(-DGMX_SIMD_REF_FLOAT_WIDTH=${GMX_SIMD_REF_FLOAT_WIDTH})
299     endif()
300     if(GMX_SIMD_REF_DOUBLE_WIDTH)
301         add_definitions(-DGMX_SIMD_REF_DOUBLE_WIDTH=${GMX_SIMD_REF_DOUBLE_WIDTH})
302     endif()
304     set(GMX_SIMD_${GMX_SIMD_ACTIVE} 1)
305     set(SIMD_STATUS_MESSAGE "Enabling reference (emulated) SIMD instructions without special flags.")
307 else()
308     gmx_invalid_option_value(GMX_SIMD_ACTIVE)
309 endif()
312 gmx_check_if_changed(SIMD_CHANGED GMX_SIMD_ACTIVE)
313 if (SIMD_CHANGED AND DEFINED SIMD_STATUS_MESSAGE)
314     message(STATUS "${SIMD_STATUS_MESSAGE}")
315 endif()
317 # While AVX-512 is a more recent SIMD ISA than AVX2, some Intel CPUs only have
318 # a single AVX-512 FMA unit, but two AVX2 FMA units, and then it is better to
319 # use AVX2. The only way to test this is to execute a small timing loop.
320 # To be able to recommend the user whether s/he should try AVX-512 instead of
321 # AVX2, we need to compile a single file with AVX512 flags. We do this
322 # automatically, but this option provides a way to turn it off in case it
323 # breaks something. The actual test source file is built if
324 # SIMD_AVX_512_CXX_SUPPORTED is set, so it will always be included if we have
325 # GMX_SIMD=AVX_512.
326 set(GMX_ENABLE_AVX512_TESTS ON CACHE INTERNAL "Compile AVX512 code to test FMA units, even when not using AVX512 SIMD")
327 mark_as_advanced(GMX_ENABLE_AVX512_TESTS)
329 if(GMX_ENABLE_AVX512_TESTS AND
330     (GMX_SIMD_ACTIVE STREQUAL "AVX_256" OR GMX_SIMD_ACTIVE STREQUAL "AVX2_256" OR GMX_SIMD_ACTIVE STREQUAL "AVX2_128"))
331     if(NOT DEFINED SIMD_AVX_512_CXX_SUPPORTED)
332         message(STATUS "Detecting flags to enable runtime detection of AVX-512 units on newer CPUs")
333         set(SIMD_AVX_512_REPORT_STATUS 1)
334     endif()
335     gmx_find_simd_avx_512_flags(SIMD_AVX_512_C_SUPPORTED SIMD_AVX_512_CXX_SUPPORTED
336                                 SIMD_AVX_512_C_FLAGS SIMD_AVX_512_CXX_FLAGS)
337     if(SIMD_AVX_512_REPORT_STATUS)
338         if(SIMD_AVX_512_CXX_SUPPORTED)
339             message(STATUS "Detecting flags to enable runtime detection of AVX-512 units on newer CPUs - ${SIMD_AVX_512_CXX_FLAGS}")
340         else()
341             message(STATUS "Detecting flags to enable runtime detection of AVX-512 units on newer CPUs - not supported")
342         endif()
343     endif()
344 endif()
346 # By default, 32-bit windows cannot pass SIMD (SSE/AVX) arguments in registers,
347 # and even on 64-bit (all platforms) it is only used for a handful of arguments.
348 # The __vectorcall (MSVC, from MSVC2013) or __regcall (ICC) calling conventions
349 # enable this, which is critical to enable 32-bit SIMD and improves performance
350 # for 64-bit SIMD.
351 # Check if the compiler supports one of these, and in that case set gmx_simdcall
352 # to that string. If we do not have any such calling convention modifier, set it
353 # to an empty string.
355 # Update 2015-11-04: As of version 3.6, clang has added support for __vectorcall
356 # (also on Linux). This appears to be buggy for the reference SIMD
357 # implementation when using the Debug build (when functions are not inlined) 
358 # while it seems works fine for the actual SIMD implementations. This is likely
359 # because the reference build ends up passing lots of structures with arrays
360 # rather than actual vector data. For now we disable __vectorcall with clang
361 # when using the reference build.
363 # xlc 13.1.5 does not seem recognize any attribute, and warns about invalid ones
364 # so we avoid searching for any.
366 if(NOT DEFINED GMX_SIMD_CALLING_CONVENTION)
367     if(GMX_TARGET_BGQ)
368         set(CALLCONV_LIST " ")
369     elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND GMX_SIMD_ACTIVE STREQUAL "REFERENCE")
370         set(CALLCONV_LIST __regcall " ")
371    elseif(CMAKE_CXX_COMPILER_ID MATCHES "XL")
372         set(CALLCONV_LIST " ")
373     else()
374         set(CALLCONV_LIST __vectorcall __regcall " ")
375     endif()
376     foreach(callconv ${CALLCONV_LIST})
377         set(callconv_compile_var "_callconv_${callconv}")
378         # Some compilers warn about targets for which attributes are
379         # ignored (e.g. clang on ARM), and in such cases we want this
380         # check to lead to using no attribute in subsequent GROMACS
381         # compilation, to avoid issuing the warning for lots of files.
382         check_c_source_compiles("
383 #pragma GCC diagnostic error \"-Wignored-attributes\"
384 int ${callconv} f(int i) {return i;} int main(void) {return f(0);}
385 " ${callconv_compile_var})
386         if(${callconv_compile_var})
387             set(GMX_SIMD_CALLING_CONVENTION "${callconv}" CACHE INTERNAL "Calling convention for SIMD routines" FORCE)
388             break()
389         endif()
390     endforeach()
391 endif()
393 if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
394     # GCC bug 49001, 54412 on Windows (just warn, since it might be fixed in later versions)
395     if((CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9.0" OR CMAKE_SIZEOF_VOID_P EQUAL 8)
396             AND (WIN32 OR CYGWIN)
397             AND (GMX_SIMD_ACTIVE MATCHES "AVX") AND NOT (GMX_SIMD_ACTIVE STREQUAL "AVX_128_FMA"))
398         message(WARNING "GCC on Windows (GCC older than 4.9 in 32-bit mode, or any version in 64-bit mode) with 256-bit AVX will probably crash. You might want to choose a different GMX_SIMD or a different compiler.")
399     endif()
400 endif()
402 endmacro()