Commit 58768a49 authored by steinbac's avatar steinbac

added VC based detection of hardware

parent 2e289b88
*~
build
build/*
debug/*
*sln
*.vcxproj*
x64
x32
cmake
\ No newline at end of file
......@@ -226,6 +226,9 @@ ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Windows")
#as an alternative to wmic, use
#get_filename_component(_vendor_id "[HKEY_LOCAL_MACHINE\\Hardware\\Description\\System\\CentralProcessor\\0;VendorIdentifier]" NAME CACHE)
#get_filename_component(_cpu_id "[HKEY_LOCAL_MACHINE\\Hardware\\Description\\System\\CentralProcessor\\0;Identifier]" NAME CACHE)
wmic_get("Name" MODEL_NAME)
string(STRIP ${MODEL_NAME} MODEL_NAME)
......@@ -235,9 +238,57 @@ ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Windows")
set(CPU_VENDOR "${MODEL_VENDOR}" CACHE STRING "cpu model vendor")
wmic_get("L2CacheSize" L2_CACHE_SIZE)
wmic_get("NumberOfCores" CPU_NPHYS_CORES)
#dirty hack that I need to validate with other machines in Win7
if(${CPU_NPHYS_CORES} GREATER 1)
math(EXPR L2_CACHE_SIZE "${L2_CACHE_SIZE}/${CPU_NPHYS_CORES}")
endif()
set(CPU_L2_SIZE_KB "${L2_CACHE_SIZE}" CACHE STRING "cpu L2 cache size in kB")
#thanks to the wonderful VC project (https://github.com/VcDevel/Vc)
include (OptimizeForArchitecture)
OFA_AutodetectHostArchitecture()
OFA_HandleX86Options()
message("++ _available_vector_units_list = ${_available_vector_units_list}")
set(SSE_FOUND false CACHE BOOL "SSE available on host")
list(FIND _available_vector_units_list "sse" SSE_INDEX)
list(FIND _available_vector_units_list "sse2" SSE2_INDEX)
list(FIND _available_vector_units_list "sse3" SSE3_INDEX)
list(FIND _available_vector_units_list "ssse3" SSSE3_INDEX)
list(FIND _available_vector_units_list "sse4.1" SSE4_1_INDEX)
list(FIND _available_vector_units_list "sse4.2" SSE4_2_INDEX)
list(FIND _available_vector_units_list "avx" AVX_INDEX)
list(FIND _available_vector_units_list "avx2" AVX2_INDEX)
if(${SSE_INDEX} GREATER -1)
set(SSE_FOUND true CACHE BOOL "SSE available on host")
endif()
if(${SSE2_INDEX} GREATER -1)
set(SSE2_FOUND true CACHE BOOL "SSE2 available on host")
endif()
if(${SSE3_INDEX} GREATER -1)
set(SSE3_FOUND true CACHE BOOL "SSE3 available on host")
endif()
if(${SSSE3_INDEX} GREATER -1)
set(SSSE3_FOUND true CACHE BOOL "SSSE3 available on host")
endif()
if(${SSE4_1_INDEX} GREATER -1)
set(SSE4_1_FOUND true CACHE BOOL "SSE4.1 available on host")
endif()
if(${SSE4_2_INDEX} GREATER -1)
set(SSE4_2_FOUND true CACHE BOOL "SSE4.2 available on host")
endif()
if(${AVX_INDEX} GREATER -1)
set(AVX_FOUND true CACHE BOOL "AVX available on host")
endif()
if(${AVX2_INDEX} GREATER -1)
set(AVX2_FOUND true CACHE BOOL "AVX2 available on host")
endif()
set(SSE_FOUND true CACHE BOOL "SSE available on host")
set(SSE2_FOUND false CACHE BOOL "SSE2 available on host")
set(SSE3_FOUND false CACHE BOOL "SSE3 available on host")
set(SSSE3_FOUND false CACHE BOOL "SSSE3 available on host")
......@@ -245,11 +296,7 @@ ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Windows")
set(SSE4_2_FOUND false CACHE BOOL "SSE4.2 available on host")
set(AVX_FOUND false CACHE BOOL "AVX available on host")
set(AVX2_FOUND false CACHE BOOL "AVX2 available on host")
#ELSE(CMAKE_SYSTEM_NAME MATCHES "Linux")
# set(SSE2_FOUND true CACHE BOOL "SSE2 available on host")
# set(SSE3_FOUND false CACHE BOOL "SSE3 available on host")
# set(SSSE3_FOUND false CACHE BOOL "SSSE3 available on host")
# set(SSE4_1_FOUND false CACHE BOOL "SSE4.1 available on host")
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
message(STATUS "found hardware: ${CPU_VENDOR} ${CPU_MODEL_NAME}")
......
# Check if SSE instructions are available on the machine where
# the project is compiled.
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
EXEC_PROGRAM(cat ARGS "/proc/cpuinfo" OUTPUT_VARIABLE CPUINFO)
STRING(REGEX REPLACE "^.*(sse2).*$" "\\1" SSE_THERE ${CPUINFO})
STRING(COMPARE EQUAL "sse2" "${SSE_THERE}" SSE2_TRUE)
IF (SSE2_TRUE)
set(SSE2_FOUND true CACHE BOOL "SSE2 available on host")
ELSE (SSE2_TRUE)
set(SSE2_FOUND false CACHE BOOL "SSE2 available on host")
ENDIF (SSE2_TRUE)
# /proc/cpuinfo apparently omits sse3 :(
STRING(REGEX REPLACE "^.*[^s](sse3).*$" "\\1" SSE_THERE ${CPUINFO})
STRING(COMPARE EQUAL "sse3" "${SSE_THERE}" SSE3_TRUE)
IF (NOT SSE3_TRUE)
STRING(REGEX REPLACE "^.*(T2300).*$" "\\1" SSE_THERE ${CPUINFO})
STRING(COMPARE EQUAL "T2300" "${SSE_THERE}" SSE3_TRUE)
ENDIF (NOT SSE3_TRUE)
STRING(REGEX REPLACE "^.*(ssse3).*$" "\\1" SSE_THERE ${CPUINFO})
STRING(COMPARE EQUAL "ssse3" "${SSE_THERE}" SSSE3_TRUE)
IF (SSE3_TRUE OR SSSE3_TRUE)
set(SSE3_FOUND true CACHE BOOL "SSE3 available on host")
ELSE (SSE3_TRUE OR SSSE3_TRUE)
set(SSE3_FOUND false CACHE BOOL "SSE3 available on host")
ENDIF (SSE3_TRUE OR SSSE3_TRUE)
IF (SSSE3_TRUE)
set(SSSE3_FOUND true CACHE BOOL "SSSE3 available on host")
ELSE (SSSE3_TRUE)
set(SSSE3_FOUND false CACHE BOOL "SSSE3 available on host")
ENDIF (SSSE3_TRUE)
STRING(REGEX REPLACE "^.*(sse4_1).*$" "\\1" SSE_THERE ${CPUINFO})
STRING(COMPARE EQUAL "sse4_1" "${SSE_THERE}" SSE41_TRUE)
IF (SSE41_TRUE)
set(SSE4_1_FOUND true CACHE BOOL "SSE4.1 available on host")
ELSE (SSE41_TRUE)
set(SSE4_1_FOUND false CACHE BOOL "SSE4.1 available on host")
ENDIF (SSE41_TRUE)
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
EXEC_PROGRAM("/usr/sbin/sysctl -n machdep.cpu.features" OUTPUT_VARIABLE
CPUINFO)
STRING(REGEX REPLACE "^.*[^S](SSE2).*$" "\\1" SSE_THERE ${CPUINFO})
STRING(COMPARE EQUAL "SSE2" "${SSE_THERE}" SSE2_TRUE)
IF (SSE2_TRUE)
set(SSE2_FOUND true CACHE BOOL "SSE2 available on host")
ELSE (SSE2_TRUE)
set(SSE2_FOUND false CACHE BOOL "SSE2 available on host")
ENDIF (SSE2_TRUE)
STRING(REGEX REPLACE "^.*[^S](SSE3).*$" "\\1" SSE_THERE ${CPUINFO})
STRING(COMPARE EQUAL "SSE3" "${SSE_THERE}" SSE3_TRUE)
IF (SSE3_TRUE)
set(SSE3_FOUND true CACHE BOOL "SSE3 available on host")
ELSE (SSE3_TRUE)
set(SSE3_FOUND false CACHE BOOL "SSE3 available on host")
ENDIF (SSE3_TRUE)
STRING(REGEX REPLACE "^.*(SSSE3).*$" "\\1" SSE_THERE ${CPUINFO})
STRING(COMPARE EQUAL "SSSE3" "${SSE_THERE}" SSSE3_TRUE)
IF (SSSE3_TRUE)
set(SSSE3_FOUND true CACHE BOOL "SSSE3 available on host")
ELSE (SSSE3_TRUE)
set(SSSE3_FOUND false CACHE BOOL "SSSE3 available on host")
ENDIF (SSSE3_TRUE)
STRING(REGEX REPLACE "^.*(SSE4.1).*$" "\\1" SSE_THERE ${CPUINFO})
STRING(COMPARE EQUAL "SSE4.1" "${SSE_THERE}" SSE41_TRUE)
IF (SSE41_TRUE)
set(SSE4_1_FOUND true CACHE BOOL "SSE4.1 available on host")
ELSE (SSE41_TRUE)
set(SSE4_1_FOUND false CACHE BOOL "SSE4.1 available on host")
ENDIF (SSE41_TRUE)
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Windows")
# TODO
set(SSE2_FOUND true CACHE BOOL "SSE2 available on host")
set(SSE3_FOUND false CACHE BOOL "SSE3 available on host")
set(SSSE3_FOUND false CACHE BOOL "SSSE3 available on host")
set(SSE4_1_FOUND false CACHE BOOL "SSE4.1 available on host")
ELSE(CMAKE_SYSTEM_NAME MATCHES "Linux")
set(SSE2_FOUND true CACHE BOOL "SSE2 available on host")
set(SSE3_FOUND false CACHE BOOL "SSE3 available on host")
set(SSSE3_FOUND false CACHE BOOL "SSSE3 available on host")
set(SSE4_1_FOUND false CACHE BOOL "SSE4.1 available on host")
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
if(NOT SSE2_FOUND)
MESSAGE(STATUS "Could not find hardware support for SSE2 on this machine.")
endif(NOT SSE2_FOUND)
if(NOT SSE3_FOUND)
MESSAGE(STATUS "Could not find hardware support for SSE3 on this machine.")
endif(NOT SSE3_FOUND)
if(NOT SSSE3_FOUND)
MESSAGE(STATUS "Could not find hardware support for SSSE3 on this machine.")
endif(NOT SSSE3_FOUND)
if(NOT SSE4_1_FOUND)
MESSAGE(STATUS "Could not find hardware support for SSE4.1 on this machine.")
endif(NOT SSE4_1_FOUND)
mark_as_advanced(SSE2_FOUND SSE3_FOUND SSSE3_FOUND SSE4_1_FOUND)
## Determine the host CPU feature set and determine the best set of compiler
## flags to enable all supported SIMD relevant features. Alternatively, the
## target CPU can be explicitly selected (for generating more generic binaries
## or for targeting a different system).
## Compilers provide e.g. the -march=native flag to achieve a similar result.
## This fails to address the need for building for a different microarchitecture
## than the current host.
## The script tries to deduce all settings from the model and family numbers of
## the CPU instead of reading the CPUID flags from e.g. /proc/cpuinfo. This makes
## the detection more independent from the CPUID code in the kernel (e.g. avx2 is
# not listed on older kernels).
#
# Usage:
# OptimizeForArchitecture()
# If either of Vc_SSE_INTRINSICS_BROKEN, Vc_AVX_INTRINSICS_BROKEN,
# Vc_AVX2_INTRINSICS_BROKEN is defined and set, the OptimizeForArchitecture
# macro will consequently disable the relevant features via compiler flags.
#=============================================================================
# Copyright 2010-2016 Matthias Kretz <kretz@kde.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the names of contributing organizations nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
get_filename_component(_currentDir "${CMAKE_CURRENT_LIST_FILE}" PATH)
#include("${_currentDir}/AddCompilerFlag.cmake")
include(CheckIncludeFileCXX)
macro(_my_find _list _value _ret)
list(FIND ${_list} "${_value}" _found)
if(_found EQUAL -1)
set(${_ret} FALSE)
else(_found EQUAL -1)
set(${_ret} TRUE)
endif(_found EQUAL -1)
endmacro(_my_find)
macro(OFA_AutodetectX86)
set(_vendor_id)
set(_cpu_family)
set(_cpu_model)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
file(READ "/proc/cpuinfo" _cpuinfo)
string(REGEX REPLACE ".*vendor_id[ \t]*:[ \t]+([a-zA-Z0-9_-]+).*" "\\1" _vendor_id "${_cpuinfo}")
string(REGEX REPLACE ".*cpu family[ \t]*:[ \t]+([a-zA-Z0-9_-]+).*" "\\1" _cpu_family "${_cpuinfo}")
string(REGEX REPLACE ".*model[ \t]*:[ \t]+([a-zA-Z0-9_-]+).*" "\\1" _cpu_model "${_cpuinfo}")
string(REGEX REPLACE ".*flags[ \t]*:[ \t]+([^\n]+).*" "\\1" _cpu_flags "${_cpuinfo}")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
exec_program("/usr/sbin/sysctl -n machdep.cpu.vendor machdep.cpu.model machdep.cpu.family machdep.cpu.features" OUTPUT_VARIABLE _sysctl_output_string)
string(REPLACE "\n" ";" _sysctl_output ${_sysctl_output_string})
list(GET _sysctl_output 0 _vendor_id)
list(GET _sysctl_output 1 _cpu_model)
list(GET _sysctl_output 2 _cpu_family)
list(GET _sysctl_output 3 _cpu_flags)
string(TOLOWER "${_cpu_flags}" _cpu_flags)
string(REPLACE "." "_" _cpu_flags "${_cpu_flags}")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
get_filename_component(_vendor_id "[HKEY_LOCAL_MACHINE\\Hardware\\Description\\System\\CentralProcessor\\0;VendorIdentifier]" NAME CACHE)
get_filename_component(_cpu_id "[HKEY_LOCAL_MACHINE\\Hardware\\Description\\System\\CentralProcessor\\0;Identifier]" NAME CACHE)
mark_as_advanced(_vendor_id _cpu_id)
string(REGEX REPLACE ".* Family ([0-9]+) .*" "\\1" _cpu_family "${_cpu_id}")
string(REGEX REPLACE ".* Model ([0-9]+) .*" "\\1" _cpu_model "${_cpu_id}")
endif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
if(_vendor_id STREQUAL "GenuineIntel")
if(_cpu_family EQUAL 6)
# taken from the Intel ORM
# http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html
# CPUID Signature Values of Of Recent Intel Microarchitectures
# 4E 5E | Skylake microarchitecture
# 3D 47 56 | Broadwell microarchitecture
# 3C 45 46 3F | Haswell microarchitecture
# 3A 3E | Ivy Bridge microarchitecture
# 2A 2D | Sandy Bridge microarchitecture
# 25 2C 2F | Intel microarchitecture Westmere
# 1A 1E 1F 2E | Intel microarchitecture Nehalem
# 17 1D | Enhanced Intel Core microarchitecture
# 0F | Intel Core microarchitecture
#
# Intel SDM Vol. 3C 35-1 / December 2016:
# 57 | Xeon Phi 3200, 5200, 7200 [Knights Landing]
# 85 | Future Xeon Phi
# 8E 9E | 7th gen. Core [Kaby Lake]
# 55 | Future Xeon [Skylake w/ AVX512]
# 4E 5E | 6th gen. Core / E3 v5 [Skylake w/o AVX512]
# 56 | Xeon D-1500 [Broadwell]
# 4F | Xeon E5 v4, E7 v4, i7-69xx [Broadwell]
# 47 | 5th gen. Core / Xeon E3 v4 [Broadwell]
# 3D | M-5xxx / 5th gen. [Broadwell]
# 3F | Xeon E5 v3, E7 v3, i7-59xx [Haswell-E]
# 3C 45 46 | 4th gen. Core, Xeon E3 v3 [Haswell]
# 3E | Xeon E5 v2, E7 v2, i7-49xx [Ivy Bridge-E]
# 3A | 3rd gen. Core, Xeon E3 v2 [Ivy Bridge]
# 2D | Xeon E5, i7-39xx [Sandy Bridge]
# 2F | Xeon E7
# 2A | Xeon E3, 2nd gen. Core [Sandy Bridge]
# 2E | Xeon 7500, 6500 series
# 25 2C | Xeon 3600, 5600 series, Core i7, i5 and i3
#
# Values from the Intel SDE:
# 5C | Goldmont
# 5A | Silvermont
# 57 | Knights Landing
# 66 | Cannonlake
# 55 | Skylake Server
# 4E | Skylake Client
# 3C | Broadwell (likely a bug in the SDE)
# 3C | Haswell
if(_cpu_model EQUAL 87) # 57
set(TARGET_ARCHITECTURE "knl") # Knights Landing
elseif(_cpu_model EQUAL 92)
set(TARGET_ARCHITECTURE "goldmont")
elseif(_cpu_model EQUAL 90 OR _cpu_model EQUAL 76)
set(TARGET_ARCHITECTURE "silvermont")
elseif(_cpu_model EQUAL 102)
set(TARGET_ARCHITECTURE "cannonlake")
elseif(_cpu_model EQUAL 142 OR _cpu_model EQUAL 158) # 8E, 9E
set(TARGET_ARCHITECTURE "kaby-lake")
elseif(_cpu_model EQUAL 85) # 55
set(TARGET_ARCHITECTURE "skylake-avx512")
elseif(_cpu_model EQUAL 78 OR _cpu_model EQUAL 94) # 4E, 5E
set(TARGET_ARCHITECTURE "skylake")
elseif(_cpu_model EQUAL 61 OR _cpu_model EQUAL 71 OR _cpu_model EQUAL 79 OR _cpu_model EQUAL 86) # 3D, 47, 4F, 56
set(TARGET_ARCHITECTURE "broadwell")
elseif(_cpu_model EQUAL 60 OR _cpu_model EQUAL 69 OR _cpu_model EQUAL 70 OR _cpu_model EQUAL 63)
set(TARGET_ARCHITECTURE "haswell")
elseif(_cpu_model EQUAL 58 OR _cpu_model EQUAL 62)
set(TARGET_ARCHITECTURE "ivy-bridge")
elseif(_cpu_model EQUAL 42 OR _cpu_model EQUAL 45)
set(TARGET_ARCHITECTURE "sandy-bridge")
elseif(_cpu_model EQUAL 37 OR _cpu_model EQUAL 44 OR _cpu_model EQUAL 47)
set(TARGET_ARCHITECTURE "westmere")
elseif(_cpu_model EQUAL 26 OR _cpu_model EQUAL 30 OR _cpu_model EQUAL 31 OR _cpu_model EQUAL 46)
set(TARGET_ARCHITECTURE "nehalem")
elseif(_cpu_model EQUAL 23 OR _cpu_model EQUAL 29)
set(TARGET_ARCHITECTURE "penryn")
elseif(_cpu_model EQUAL 15)
set(TARGET_ARCHITECTURE "merom")
elseif(_cpu_model EQUAL 28)
set(TARGET_ARCHITECTURE "atom")
elseif(_cpu_model EQUAL 14)
set(TARGET_ARCHITECTURE "core")
elseif(_cpu_model LESS 14)
message(WARNING "Your CPU (family ${_cpu_family}, model ${_cpu_model}) is not known. Auto-detection of optimization flags failed and will use the generic CPU settings with SSE2.")
set(TARGET_ARCHITECTURE "generic")
else()
message(WARNING "Your CPU (family ${_cpu_family}, model ${_cpu_model}) is not known. Auto-detection of optimization flags failed and will use the 65nm Core 2 CPU settings.")
set(TARGET_ARCHITECTURE "merom")
endif()
elseif(_cpu_family EQUAL 7) # Itanium (not supported)
message(WARNING "Your CPU (Itanium: family ${_cpu_family}, model ${_cpu_model}) is not supported by OptimizeForArchitecture.cmake.")
elseif(_cpu_family EQUAL 15) # NetBurst
list(APPEND _available_vector_units_list "sse" "sse2")
if(_cpu_model GREATER 2) # Not sure whether this must be 3 or even 4 instead
list(APPEND _available_vector_units_list "sse" "sse2" "sse3")
endif(_cpu_model GREATER 2)
endif(_cpu_family EQUAL 6)
elseif(_vendor_id STREQUAL "AuthenticAMD")
if(_cpu_family EQUAL 23)
set(TARGET_ARCHITECTURE "zen")
elseif(_cpu_family EQUAL 22) # 16h
set(TARGET_ARCHITECTURE "AMD 16h")
elseif(_cpu_family EQUAL 21) # 15h
if(_cpu_model LESS 2)
set(TARGET_ARCHITECTURE "bulldozer")
else()
set(TARGET_ARCHITECTURE "piledriver")
endif()
elseif(_cpu_family EQUAL 20) # 14h
set(TARGET_ARCHITECTURE "AMD 14h")
elseif(_cpu_family EQUAL 18) # 12h
elseif(_cpu_family EQUAL 16) # 10h
set(TARGET_ARCHITECTURE "barcelona")
elseif(_cpu_family EQUAL 15)
set(TARGET_ARCHITECTURE "k8")
if(_cpu_model GREATER 64) # I don't know the right number to put here. This is just a guess from the hardware I have access to
set(TARGET_ARCHITECTURE "k8-sse3")
endif(_cpu_model GREATER 64)
endif()
endif(_vendor_id STREQUAL "GenuineIntel")
endmacro()
macro(OFA_AutodetectArm)
message(WARNING "Architecture auto-detection for CMAKE_SYSTEM_PROCESSOR '${CMAKE_SYSTEM_PROCESSOR}' is not supported by OptimizeForArchitecture.cmake")
endmacro()
macro(OFA_AutodetectHostArchitecture)
set(TARGET_ARCHITECTURE "generic")
set(Vc_ARCHITECTURE_FLAGS)
if("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(x86|AMD64)")
OFA_AutodetectX86()
elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(arm|aarch32|aarch64)")
OFA_AutodetectArm()
else()
message(FATAL_ERROR "OptimizeForArchitecture.cmake does not implement support for CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
endif()
endmacro()
macro(OFA_HandleX86Options)
set(_march_flag_list)
set(_available_vector_units_list)
macro(_nehalem)
list(APPEND _march_flag_list "nehalem")
list(APPEND _march_flag_list "corei7")
list(APPEND _march_flag_list "core2")
list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4.1" "sse4.2")
endmacro()
macro(_westmere)
list(APPEND _march_flag_list "westmere")
_nehalem()
endmacro()
macro(_sandybridge)
list(APPEND _march_flag_list "sandybridge")
list(APPEND _march_flag_list "corei7-avx")
_westmere()
list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4.1" "sse4.2" "avx")
endmacro()
macro(_ivybridge)
list(APPEND _march_flag_list "ivybridge")
list(APPEND _march_flag_list "core-avx-i")
_sandybridge()
list(APPEND _available_vector_units_list "rdrnd" "f16c")
endmacro()
macro(_haswell)
list(APPEND _march_flag_list "haswell")
list(APPEND _march_flag_list "core-avx2")
_ivybridge()
list(APPEND _available_vector_units_list "avx2" "fma" "bmi" "bmi2")
endmacro()
macro(_broadwell)
list(APPEND _march_flag_list "broadwell")
_haswell()
endmacro()
macro(_skylake)
list(APPEND _march_flag_list "skylake")
_broadwell()
endmacro()
macro(_skylake_avx512)
list(APPEND _march_flag_list "skylake-avx512")
_skylake()
list(APPEND _available_vector_units_list "avx512f" "avx512cd" "avx512dq" "avx512bw" "avx512vl")
endmacro()
macro(_cannonlake)
list(APPEND _march_flag_list "cannonlake")
_skylake_avx512()
list(APPEND _available_vector_units_list "avx512ifma" "avx512vbmi")
endmacro()
macro(_knightslanding)
list(APPEND _march_flag_list "knl")
_broadwell()
list(APPEND _available_vector_units_list "avx512f" "avx512pf" "avx512er" "avx512cd")
endmacro()
macro(_silvermont)
list(APPEND _march_flag_list "silvermont")
_westmere()
list(APPEND _available_vector_units_list "rdrnd")
endmacro()
macro(_goldmont)
list(APPEND _march_flag_list "goldmont")
_silvermont()
endmacro()
if(TARGET_ARCHITECTURE STREQUAL "core")
list(APPEND _march_flag_list "core2")
list(APPEND _available_vector_units_list "sse" "sse2" "sse3")
elseif(TARGET_ARCHITECTURE STREQUAL "merom")
list(APPEND _march_flag_list "merom")
list(APPEND _march_flag_list "core2")
list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3")
elseif(TARGET_ARCHITECTURE STREQUAL "penryn")
list(APPEND _march_flag_list "penryn")
list(APPEND _march_flag_list "core2")
list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3")
message(STATUS "Sadly the Penryn architecture exists in variants with SSE4.1 and without SSE4.1.")
if(_cpu_flags MATCHES "sse4_1")
message(STATUS "SSE4.1: enabled (auto-detected from this computer's CPU flags)")
list(APPEND _available_vector_units_list "sse4.1")
else()
message(STATUS "SSE4.1: disabled (auto-detected from this computer's CPU flags)")
endif()
elseif(TARGET_ARCHITECTURE STREQUAL "knl")
_knightslanding()
elseif(TARGET_ARCHITECTURE STREQUAL "cannonlake")
_cannonlake()
elseif(TARGET_ARCHITECTURE STREQUAL "kaby-lake")
_skylake()
elseif(TARGET_ARCHITECTURE STREQUAL "skylake-xeon" OR TARGET_ARCHITECTURE STREQUAL "skylake-avx512")
_skylake_avx512()
elseif(TARGET_ARCHITECTURE STREQUAL "skylake")
_skylake()
elseif(TARGET_ARCHITECTURE STREQUAL "broadwell")
_broadwell()
elseif(TARGET_ARCHITECTURE STREQUAL "haswell")
_haswell()
elseif(TARGET_ARCHITECTURE STREQUAL "ivy-bridge")
_ivybridge()
elseif(TARGET_ARCHITECTURE STREQUAL "sandy-bridge")
_sandybridge()
elseif(TARGET_ARCHITECTURE STREQUAL "westmere")
_westmere()
elseif(TARGET_ARCHITECTURE STREQUAL "nehalem")
_nehalem()
elseif(TARGET_ARCHITECTURE STREQUAL "goldmont")
_goldmont()
elseif(TARGET_ARCHITECTURE STREQUAL "silvermont")
_silvermont()
elseif(TARGET_ARCHITECTURE STREQUAL "atom")
list(APPEND _march_flag_list "atom")
list(APPEND _march_flag_list "core2")
list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3")
elseif(TARGET_ARCHITECTURE STREQUAL "k8")
list(APPEND _march_flag_list "k8")
list(APPEND _available_vector_units_list "sse" "sse2")
elseif(TARGET_ARCHITECTURE STREQUAL "k8-sse3")
list(APPEND _march_flag_list "k8-sse3")
list(APPEND _march_flag_list "k8")
list(APPEND _available_vector_units_list "sse" "sse2" "sse3")
elseif(TARGET_ARCHITECTURE STREQUAL "AMD 16h")
list(APPEND _march_flag_list "btver2")
list(APPEND _march_flag_list "btver1")
list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4a" "sse4.1" "sse4.2" "avx" "f16c")
elseif(TARGET_ARCHITECTURE STREQUAL "AMD 14h")
list(APPEND _march_flag_list "btver1")
list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4a")
elseif(TARGET_ARCHITECTURE STREQUAL "zen")
list(APPEND _march_flag_list "znver1")
_skylake()
list(APPEND _available_vector_units_list "sse4a")
elseif(TARGET_ARCHITECTURE STREQUAL "piledriver")
list(APPEND _march_flag_list "bdver2")
list(APPEND _march_flag_list "bdver1")
list(APPEND _march_flag_list "bulldozer")
list(APPEND _march_flag_list "barcelona")
list(APPEND _march_flag_list "core2")
list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4a" "sse4.1" "sse4.2" "avx" "xop" "fma4" "fma" "f16c")
elseif(TARGET_ARCHITECTURE STREQUAL "interlagos")
list(APPEND _march_flag_list "bdver1")
list(APPEND _march_flag_list "bulldozer")
list(APPEND _march_flag_list "barcelona")
list(APPEND _march_flag_list "core2")
list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4a" "sse4.1" "sse4.2" "avx" "xop" "fma4")
elseif(TARGET_ARCHITECTURE STREQUAL "bulldozer")
list(APPEND _march_flag_list "bdver1")
list(APPEND _march_flag_list "bulldozer")
list(APPEND _march_flag_list "barcelona")
list(APPEND _march_flag_list "core2")
list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4a" "sse4.1" "sse4.2" "avx" "xop" "fma4")
elseif(TARGET_ARCHITECTURE STREQUAL "barcelona")
list(APPEND _march_flag_list "barcelona")
list(APPEND _march_flag_list "core2")
list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "sse4a")
elseif(TARGET_ARCHITECTURE STREQUAL "istanbul")
list(APPEND _march_flag_list "barcelona")
list(APPEND _march_flag_list "core2")
list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "sse4a")
elseif(TARGET_ARCHITECTURE STREQUAL "magny-cours")
list(APPEND _march_flag_list "barcelona")
list(APPEND _march_flag_list "core2")
list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "sse4a")
elseif(TARGET_ARCHITECTURE STREQUAL "generic")
list(APPEND _march_flag_list "generic")
elseif(TARGET_ARCHITECTURE STREQUAL "none")
# add this clause to remove it from the else clause
else(TARGET_ARCHITECTURE STREQUAL "core")
message(FATAL_ERROR "Unknown target architecture: \"${TARGET_ARCHITECTURE}\". Please set TARGET_ARCHITECTURE to a supported value.")
endif(TARGET_ARCHITECTURE STREQUAL "core")
if(NOT TARGET_ARCHITECTURE STREQUAL "none")
set(_disable_vector_unit_list)
set(_enable_vector_unit_list)
if(DEFINED Vc_AVX_INTRINSICS_BROKEN AND Vc_AVX_INTRINSICS_BROKEN)
message(STATUS "AVX disabled because of old/broken toolchain")
set(_avx_broken true)
set(_avx2_broken true)
set(_fma4_broken true)
set(_xop_broken true)
else()
set(_avx_broken false)
if(DEFINED Vc_FMA4_INTRINSICS_BROKEN AND Vc_FMA4_INTRINSICS_BROKEN)
message(STATUS "FMA4 disabled because of old/broken toolchain")
set(_fma4_broken true)
else()
set(_fma4_broken false)
endif()
if(DEFINED Vc_XOP_INTRINSICS_BROKEN AND Vc_XOP_INTRINSICS_BROKEN)
message(STATUS "XOP disabled because of old/broken toolchain")
set(_xop_broken true)
else()
set(_xop_broken false)
endif()
if(DEFINED Vc_AVX2_INTRINSICS_BROKEN AND Vc_AVX2_INTRINSICS_BROKEN)
message(STATUS "AVX2 disabled because of old/broken toolchain")
set(_avx2_broken true)
else()
set(_avx2_broken false)
endif()
endif()
macro(_enable_or_disable _name _flag _documentation _broken)
if(_broken)
set(_found false)
else()
_my_find(_available_vector_units_list "${_flag}" _found)
endif()
set(USE_${_name} ${_found} CACHE BOOL "${documentation}" ${_force})
mark_as_advanced(USE_${_name})
if(USE_${_name})
list(APPEND _enable_vector_unit_list "${_flag}")
else()
list(APPEND _disable_vector_unit_list "${_flag}")
endif()
endmacro()
_enable_or_disable(SSE2 "sse2" "Use SSE2. If SSE2 instructions are not enabled the SSE implementation will be disabled." false)
_enable_or_disable(SSE3 "sse3" "Use SSE3. If SSE3 instructions are not enabled they will be emulated." false)
_enable_or_disable(SSSE3 "ssse3" "Use SSSE3. If SSSE3 instructions are not enabled they will be emulated." false)
_enable_or_disable(SSE4_1 "sse4.1" "Use SSE4.1. If SSE4.1 instructions are not enabled they will be emulated." false)
_enable_or_disable(SSE4_2 "sse4.2" "Use SSE4.2. If SSE4.2 instructions are not enabled they will be emulated." false)
_enable_or_disable(SSE4a "sse4a" "Use SSE4a. If SSE4a instructions are not enabled they will be emulated." false)