diff --git a/CMakeLists.txt b/CMakeLists.txt index f7cbb5c793..bc6687e12b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ option(AV_BUILD_LAPACK "Enable building an embedded Lapack" ON) option(AV_BUILD_SUITESPARSE "Enable building an embedded SuiteSparse" ON) option(AV_BUILD_FFMPEG "Enable building an embedded FFMpeg" ON) option(AV_BUILD_ALICEVISION "Enable building of AliceVision" ON) +option(AV_EIGEN_MEMORY_ALIGNMENT "Enable Eigen memory alignment" OFF) option(AV_USE_CUDA "Enable CUDA" ON) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 31d28ddc51..fa0045cb5c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -201,6 +201,23 @@ if(CMAKE_COMPILER_IS_GNUCXX) AddCompilerFlag("-Werror=return-local-addr") endif() +# Eigen requires overaligned buffers for maximum efficiency (e.g. on AVX512 buffers may need to +# be aligned to 64 bytes). AliceVision currently does not support this. Fortunately this is fixed +# in C++17. While we can't upgrade to C++17 just yet, some compilers support overaligned +# allocation feature with a separate flag, so use it if alignment is enabled in Eigen. +# See https://eigen.tuxfamily.org/dox/group__TopicUnalignedArrayAssert.html +if(AV_EIGEN_MEMORY_ALIGNMENT) + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 7.1) + AddCompilerFlag("-faligned-new") + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0) + AddCompilerFlag("-faligned-new") + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.12) + AddCompilerFlag("/Zc:alignedNew") + else() + message(FATAL_ERROR "AV_EIGEN_MEMORY_ALIGNMENT is only supported starting GCC 7.1, Clang 6.0 and MSVC 2017 15.5") + endif() +endif() + # ============================================================================== # Enable code coverage generation (only with GCC) # ============================================================================== @@ -346,8 +363,11 @@ endif() find_package(Eigen3 3.3 REQUIRED) if(Eigen3_FOUND OR EIGEN3_FOUND) # message(STATUS "EIGEN_INCLUDE_DIR: ${EIGEN_INCLUDE_DIR}") - # See https://eigen.tuxfamily.org/dox/group__TopicUnalignedArrayAssert.html - set(AV_EIGEN_DEFINITIONS -DEIGEN_MAX_ALIGN_BYTES=0 -DEIGEN_MAX_STATIC_ALIGN_BYTES=0) + if(AV_EIGEN_MEMORY_ALIGNMENT) + set(AV_EIGEN_DEFINITIONS -DALICEVISION_EIGEN_REQUIRE_ALIGNMENT=1) + else() + set(AV_EIGEN_DEFINITIONS -DEIGEN_MAX_ALIGN_BYTES=0 -DEIGEN_MAX_STATIC_ALIGN_BYTES=0) + endif() else() message(FATAL_ERROR " EIGEN NOT FOUND. EIGEN_INCLUDE_DIR: ${EIGEN_INCLUDE_DIR}") endif() diff --git a/src/aliceVision/numeric/numeric.hpp b/src/aliceVision/numeric/numeric.hpp index 4f78e92151..00d13a5ed4 100644 --- a/src/aliceVision/numeric/numeric.hpp +++ b/src/aliceVision/numeric/numeric.hpp @@ -8,18 +8,20 @@ #pragma once -// AliceVision does not support Eigen with alignment, +// AliceVision does not support Eigen with alignment, unless C++17 aligned new feature is enabled. // So ensure Eigen is used with the correct flags. -#ifndef EIGEN_MAX_ALIGN_BYTES -#error "EIGEN_MAX_ALIGN_BYTES is not defined" -#elif EIGEN_MAX_ALIGN_BYTES != 0 -#error "EIGEN_MAX_ALIGN_BYTES is defined but not 0" -#endif - -#ifndef EIGEN_MAX_STATIC_ALIGN_BYTES -#error "EIGEN_MAX_STATIC_ALIGN_BYTES is not defined" -#elif EIGEN_MAX_STATIC_ALIGN_BYTES != 0 -#error "EIGEN_MAX_STATIC_ALIGN_BYTES is defined but not 0" +#ifndef ALICEVISION_EIGEN_REQUIRE_ALIGNMENT + #ifndef EIGEN_MAX_ALIGN_BYTES + #error "EIGEN_MAX_ALIGN_BYTES is not defined" + #elif EIGEN_MAX_ALIGN_BYTES != 0 + #error "EIGEN_MAX_ALIGN_BYTES is defined but not 0" + #endif + + #ifndef EIGEN_MAX_STATIC_ALIGN_BYTES + #error "EIGEN_MAX_STATIC_ALIGN_BYTES is not defined" + #elif EIGEN_MAX_STATIC_ALIGN_BYTES != 0 + #error "EIGEN_MAX_STATIC_ALIGN_BYTES is defined but not 0" + #endif #endif