#
# Copyright (C) 2022-2023 The ESPResSo project
#
# This file is part of ESPResSo.
#
# ESPResSo is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ESPResSo is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#
function(espresso_enable_avx2_support callback)
set(COMPILER_AVX2_FLAG "")
foreach(FLAG_NAME "-mavx2" "/arch:AVX2")
string(REGEX REPLACE "[^0-9A-Za-z_]" "_" FLAG_VARIABLE "${FLAG_NAME}")
check_cxx_compiler_flag("${flag_name}"
COMPILER_HAS_${FLAG_VARIABLE}_FLAG_RESULT)
if(COMPILER_HAS_${FLAG_VARIABLE}_FLAG_RESULT)
set(COMPILER_AVX2_FLAG "${FLAG_NAME}")
cmake_language(CALL ${callback} "${COMPILER_AVX2_FLAG}")
break()
endif()
endforeach()
if(COMPILER_AVX2_FLAG STREQUAL "")
message(
FATAL_ERROR
"${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION} doesn't support AVX2-specific compiler flags."
)
endif()
if(NOT COMPILER_AVX2_FLAG STREQUAL "/arch:AVX2")
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -march=native -E -v - INPUT_FILE /dev/null
OUTPUT_VARIABLE MARCH_NATIVE_OUTPUT_STRING
ERROR_VARIABLE MARCH_NATIVE_OUTPUT_STRING)
if(NOT "${MARCH_NATIVE_OUTPUT_STRING}" MATCHES "[ \n](\\+avx2|-mavx2|-D__AVX2__)[ \n]")
message(
FATAL_ERROR
"AVX2 not supported on this CPU architecture according to ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}. While ESPResSo will still compile, you will trigger SIGILL when calling AVX functions."
)
endif()
endif()
set(CMAKE_REQUIRED_FLAGS_BACKUP "${CMAKE_REQUIRED_FLAGS}")
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${COMPILER_AVX2_FLAG}")
check_cxx_source_compiles(
"#include
__m256i xi_i = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8);
__m256 xi_s = _mm256_set_ps(0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f);
__m256d xi_d = _mm256_set_pd(0.0, 1.0, 2.0, 3.0);
int main() {}
" COMPILER_HAS_AVX2_SUPPORT)
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS_BACKUP}")
if(NOT COMPILER_HAS_AVX2_SUPPORT)
message(
FATAL_ERROR
"Cannot execute a simple AVX2 program compiled by ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}."
)
endif()
endfunction()