diff --git a/CMakeLists.txt b/CMakeLists.txt index c759ed3..3eff15b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ -# +# # CMake options -# +# # CMake version cmake_minimum_required(VERSION 3.0 FATAL_ERROR) @@ -30,9 +30,9 @@ include(cmake/HealthCheck.cmake) include(cmake/GenerateTemplateExportHeader.cmake) -# +# # Project description and (meta) information -# +# # Get git revision get_git_head_revision(GIT_REFSPEC GIT_SHA1) @@ -59,9 +59,9 @@ string(MAKE_C_IDENTIFIER ${META_PROJECT_NAME} META_PROJECT_ID) string(TOUPPER ${META_PROJECT_ID} META_PROJECT_ID) -# +# # Project configuration options -# +# # Project options option(BUILD_SHARED_LIBS "Build shared instead of static libraries." ON) @@ -72,9 +72,9 @@ option(OPTION_BUILD_EXAMPLES "Build examples." option(OPTION_BUILD_WITH_STD_REGEX "Use std::regex instead of boost" ON) -# +# # Declare project -# +# # Generate folders for IDE targets (e.g., VisualStudio solutions) set_property(GLOBAL PROPERTY USE_FOLDERS ON) @@ -92,12 +92,12 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) file(WRITE "${PROJECT_BINARY_DIR}/VERSION" "${META_NAME_VERSION}") -# +# # Compiler settings and options -# +# include(cmake/CompileOptions.cmake) - +include(cmake/CheckSimd.cmake) # # Project Health Check Setup @@ -111,9 +111,9 @@ enable_cppcheck(On) enable_clang_tidy(On) -# +# # Deployment/installation setup -# +# # Get project name set(project ${META_PROJECT_NAME}) @@ -163,23 +163,23 @@ if(NOT SYSTEM_DIR_INSTALL) if(APPLE) set(CMAKE_INSTALL_RPATH "@loader_path/../../../${INSTALL_LIB}") else() - set(CMAKE_INSTALL_RPATH "$ORIGIN/${INSTALL_LIB}") + set(CMAKE_INSTALL_RPATH "$ORIGIN/${INSTALL_LIB}") endif() endif() -# +# # Project modules -# +# add_subdirectory(source) add_subdirectory(docs) add_subdirectory(deploy) -# +# # Deployment (global project files) -# +# # Install version file install(FILES "${PROJECT_BINARY_DIR}/VERSION" DESTINATION ${INSTALL_ROOT} COMPONENT runtime) diff --git a/cmake/CheckSimd.cmake b/cmake/CheckSimd.cmake new file mode 100644 index 0000000..8e16024 --- /dev/null +++ b/cmake/CheckSimd.cmake @@ -0,0 +1,87 @@ + +include(CheckCXXSourceRuns) + +# save old configuration +set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) + +# set flags +set(AVX_FLAGS) +set(AVX2_FLAGS) +set(AVX512_FLAGS) +if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC") + set(AVX_FLAGS "/arch:AVX") + set(AVX2_FLAGS "/arch:AVX2") + # set(AVX512_FLAGS "/arch:AVX512") found no option for msvc +endif() +if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + set(AVX_FLAGS "-mavx") + set(AVX2_FLAGS "-mavx2") + set(AVX512_FLAGS "-mavx512f" "-mavx512cd") # xeon processors have more flags +endif() + + +# check for AVX +set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS} ${AVX_FLAGS}) +CHECK_CXX_SOURCE_RUNS(" + #include + int main(){ + const float src[8] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f }; + float dst[8]; + __m256 a = _mm256_loadu_ps( src ); + __m256 b = _mm256_add_ps( a, a ); + _mm256_storeu_ps( dst, b ); + for( int i = 0; i < 8; i++ ) + if( ( src[i] + src[i] ) != dst[i] ) return -1; + return 0; + }" + AVX_ENABLED) +# remove flags if cpu does not support AVX +if(NOT AVX_ENABLED) + set(AVX_FLAGS "") +endif() + + +# check for AVX2 +set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS} ${AVX2_FLAGS}) +CHECK_CXX_SOURCE_RUNS(" + #include + int main(){ + const int src[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + int dst[8]; + __m256i a = _mm256_loadu_si256( (__m256i*)src ); + __m256i b = _mm256_add_epi32( a, a ); + _mm256_storeu_si256( (__m256i*)dst, b ); + for( int i = 0; i < 8; i++ ) + if( ( src[i] + src[i] ) != dst[i] ) return -1; + return 0; + }" + AVX2_ENABLED) +# remove flags if cpu does not support AVX +if(NOT AVX2_ENABLED) + set(AVX2_FLAGS "") +endif() + + +# check for AVX512 +set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS} ${AVX512_FLAGS}) +CHECK_CXX_SOURCE_RUNS(" + #include + int main(){ + const int src[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 }; + int dst[16]; + __m512i a = _mm512_loadu_si512( (__m512i*)src ); + __m512i b = _mm512_add_epi32( a, a ); + _mm512_storeu_si512( (__m512i*)dst, b ); + for( int i = 0; i < 16; i++ ) + if( ( src[i] + src[i] ) != dst[i] ) return -1; + return 0; + }" + AVX512_ENABLED) +# remove flags if cpu does not support AVX +if(NOT AVX512_ENABLED) + set(AVX512_FLAGS "") +endif() + + +# restore previous state of cmake variable +set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) diff --git a/source/examples/simd/CMakeLists.txt b/source/examples/simd/CMakeLists.txt index f4ee332..8899534 100644 --- a/source/examples/simd/CMakeLists.txt +++ b/source/examples/simd/CMakeLists.txt @@ -1,12 +1,12 @@ -# +# # External dependencies -# +# -# +# # Executable name and options -# +# # Target name set(target simd-example) @@ -15,18 +15,18 @@ set(target simd-example) message(STATUS "Example ${target}") -# +# # Sources -# +# set(sources main.cpp ) -# +# # Create executable -# +# # Build executable add_executable(${target} @@ -37,9 +37,9 @@ add_executable(${target} add_executable(${META_PROJECT_NAME}::${target} ALIAS ${target}) -# +# # Project options -# +# set_target_properties(${target} PROPERTIES @@ -48,9 +48,9 @@ set_target_properties(${target} ) -# +# # Include directories -# +# target_include_directories(${target} PRIVATE @@ -60,9 +60,9 @@ target_include_directories(${target} ) -# +# # Libraries -# +# target_link_libraries(${target} PRIVATE @@ -71,30 +71,36 @@ target_link_libraries(${target} ) -# +# # Compile definitions -# +# target_compile_definitions(${target} PRIVATE ${DEFAULT_COMPILE_DEFINITIONS} SSE_ENABLED + $<$:AVX_ENABLED> + $<$:AVX2_ENABLED> + $<$:AVX512_ENABLED> ) -# +# # Compile options -# +# target_compile_options(${target} PRIVATE ${DEFAULT_COMPILE_OPTIONS} + ${AVX_FLAGS} + ${AVX2_FLAGS} + ${AVX512_FLAGS} ) -# +# # Linker options -# +# target_link_libraries(${target} PRIVATE @@ -112,9 +118,9 @@ perform_health_checks( ) -# +# # Deployment -# +# # Executable install(TARGETS ${target}