CMakeLists.txt 9.33 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
###########################################################################
# Inastemp - Berenger Bramas MPCDF - 2016
# Under MIT Licence, please you must read the LICENCE file.
###########################################################################
cmake_minimum_required (VERSION 2.8.3 FATAL_ERROR)

set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)

#===========================================================================
# Project Declaration
#===========================================================================
project(INASTEMP C CXX)

# check if compiling into source directories
string(COMPARE EQUAL "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" insource)
if(insource)
  message(FATAL_ERROR "${PROJECT_NAME} requires an out of source build. Goto ./Build and tapes cmake ../")
endif(insource)

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/)
set(INASTEMP_CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules)

# Adds the CMAKE_DEPENDENT_OPTION command
INCLUDE(CMakeDependentOption)

# Release by default
if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE "RELEASE" CACHE STRING
      "Choose the type of build, options are: Debug Release RelWithDebInfo" FORCE)
30
endif()
31 32 33 34 35

if($ENV{VERBOSE})
    MESSAGE(STATUS "Main -- CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}")
endif()

36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
# Test if inastemp is included as a subproject
if(${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME})
    set(INASTEMP_AS_SUBPROJECT FALSE)
else()
    set(INASTEMP_AS_SUBPROJECT TRUE)
endif()

if($ENV{VERBOSE})
    MESSAGE(STATUS "Main -- INASTEMP_AS_SUBPROJECT ${INASTEMP_AS_SUBPROJECT}")
endif()

# Build only the lib if subproject
if(NOT DEFINED INASTEMP_JUST_LIB)
    set(INASTEMP_JUST_LIB ${INASTEMP_AS_SUBPROJECT} CACHE BOOL
        "Set to on to build the lib for external use (without test and extra flags)" FORCE)
endif()

53 54 55 56 57
if(NOT DEFINED INASTEMP_DO_INSTALL)
    set(INASTEMP_DO_INSTALL OFF CACHE BOOL
        "Set to on to install the headers file of inastemp" FORCE)
endif()

58 59
if($ENV{VERBOSE})
    MESSAGE(STATUS "Main -- INASTEMP_JUST_LIB ${INASTEMP_JUST_LIB}")
60
    MESSAGE(STATUS "Main -- INASTEMP_DO_INSTALL ${INASTEMP_DO_INSTALL}")
61 62
endif()

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
#===========================================================================
# Version Number
#===========================================================================

set(INASTEMP_MAJOR_VERSION 0)
set(INASTEMP_MINOR_VERSION 1)
set(INASTEMP_PATCH_VERSION 0)
set(INASTEMP_VERSION  "${INASTEMP_MAJOR_VERSION}.${INASTEMP_MINOR_VERSION}.${INASTEMP_PATCH_VERSION}" )

#===========================================================================
# Options
#===========================================================================
#  Ask CPU capacities
include(GetCpuInfos)
GetCpuInfos()

#  Ask compiler capacities
include(GetCompilerInfos)
GetCompilerInfos()

# All types from worse to best (ADD-NEW-HERE)
84
set(ALL_TYPES "SSE3;SSSE3;SSE41;SSE42;AVX;AVX2;AVX512COMMON;AVX512KNL;AVX512SKL")
85 86 87 88
set(INASTEMP_USE_SCALAR ON)
set(INASTEMP_CXX_FLAGS "-std=c++11")

# Set custom cpu <=> vec rules (maybe ADD-NEW-HERE if needed)
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
set(AVX512COMMON_CPU_RULES "AVX512F;AVX512ER")
set(AVX512KNL_CPU_RULES "AVX512F;AVX512ER;AVX512PF")
set(AVX512SKL_CPU_RULES "AVX512F;AVX512ER;AVX512VL;AVX512BW;AVX512DQ")


# Dependencies between types (maybe ADD-NEW-HERE if needed)
set(SSSE3_DEP "SSE3")
set(SSE41_DEP "SSSE3")
set(SSE42_DEP "SSE41")
set(AVX2_DEP "AVX")
set(AVX512KNL_DEP "AVX512COMMON")
set(AVX512SKL_DEP "AVX512COMMON")

# Enforce rules
set(ALL_TYPES_REVERSE ${ALL_TYPES})
list(REVERSE ALL_TYPES_REVERSE)
foreach(TYPE ${ALL_TYPES_REVERSE})   
106 107 108 109 110
    if( COMPILER_INFO_${TYPE} )
        if(NOT DEFINED ${TYPE}_CPU_RULES)
            set( ${TYPE}_CPU_RULES "${TYPE}")
        endif()

111
        # Value by default is based on CPU capacities
112 113 114
        set(${TYPE}_SUPPORTED_BY_CPU TRUE)
        foreach(RULE ${${TYPE}_CPU_RULES})
            if(NOT DEFINED CPU_INFO_${RULE})
115 116 117 118
                MESSAGE(WARNING "Main -- The variable CPU_INFO_${RULE} cannot be read from the current CPU which might be too old. It turns off ${TYPE}.")
                set(${TYPE}_SUPPORTED_BY_CPU FALSE)                
                break()
            elseif(NOT ${CPU_INFO_${RULE}})
119 120 121 122 123
                set(${TYPE}_SUPPORTED_BY_CPU FALSE)                
                break()
            endif()
        endforeach()

124
        OPTION( INASTEMP_USE_${TYPE} "Set to ON to compile with ${TYPE} support (default based on CPU capacities)" ${${TYPE}_SUPPORTED_BY_CPU} )
125 126 127

        if(${INASTEMP_USE_${TYPE}})
            set(INASTEMP_CXX_FLAGS "${INASTEMP_CXX_FLAGS} ${${TYPE}_FLAGS}")
128
            list(APPEND ALL_USED_TYPES "${TYPE}")
129 130 131 132 133 134

            if(COMPILER_INFO_${TYPE}_NOOP)
                set(INASTEMP_USE_${TYPE}_OPERATORS ON)
            else()
                set(INASTEMP_USE_${TYPE}_OPERATORS OFF)
            endif()
135 136 137 138 139 140 141 142 143 144 145 146 147

            # We turn it on if it is needed by another type
            foreach(DEPTYPE ${${TYPE}_DEP})
                if( NOT COMPILER_INFO_${TYPE} )
                    MESSAGE(ERROR "Main -- Type ${TYPE} depends on type ${DEPTYPE} which is not supported by the compiler.")
                endif()
                if( NOT INASTEMP_USE_${DEPTYPE} )
                    if($ENV{VERBOSE})
                        MESSAGE(STATUS "Main -- ${DEPTYPE} is turn on because it is needed by ${TYPE}")
                    endif()
                    set(INASTEMP_USE_${DEPTYPE} ON)
                endif()
            endforeach() 
148 149 150 151 152 153 154
        endif()
    else()
        if($ENV{VERBOSE})
            MESSAGE(STATUS "Main -- The compiler cannot compile ${TYPE} intrinsics")
        endif()
    endif()
endforeach()
155
# The original order should be used as slow-to-fast types
156
list(APPEND ALL_USED_TYPES "SCALAR")
157
list(REVERSE ALL_USED_TYPES)
158 159 160
list(LENGTH ALL_USED_TYPES INASTEMP_NB_USED_TYPES)
if($ENV{VERBOSE})
    MESSAGE(STATUS "Main -- INASTEMP_NB_USED_TYPES ${INASTEMP_NB_USED_TYPES}")
161
    MESSAGE(STATUS "Main -- ALL_USED_TYPES ${ALL_USED_TYPES}")
162 163 164 165 166 167 168
endif()
list(GET ALL_USED_TYPES -1 INASTEMP_BESTTYPE )

# Extra-flags
SET( INASTEMP_EXTRA_CXX_FLAGS "-funroll-loops" CACHE STRING "These flags are used for all configurations"  )
set(INASTEMP_CXX_FLAGS  "${INASTEMP_CXX_FLAGS} ${INASTEMP_EXTRA_CXX_FLAGS}")

169 170 171 172
# Options
if(NOT INASTEMP_AS_SUBPROJECT)
    SET( INASTEMP_EXTRA_CXX_FLAGS_RELEASE "-O3" CACHE STRING "These flags are added to the usual ones for RELEASE"  )
    set(CMAKE_CXX_FLAGS_RELEASE  "${CMAKE_CXX_FLAGS_RELEASE} ${INASTEMP_EXTRA_CXX_FLAGS_RELEASE}")
173

174 175
    SET( INASTEMP_EXTRA_CXX_FLAGS_DEBUG "-O0" CACHE STRING "These flags are added to the usual ones for DEBUG"  )
    set(CMAKE_CXX_FLAGS_DEBUG  "${CMAKE_CXX_FLAGS_DEBUG} ${INASTEMP_EXTRA_CXX_FLAGS_DEBUG}")
176

177
    set(INASTEMP_CXX_FLAGS "${INASTEMP_CXX_FLAGS} -fpic -Wextra -Wnon-virtual-dtor -Wshadow -Wpointer-arith -Wcast-qual -Wconversion  -Wall -Wno-sign-conversion -pedantic -Woverloaded-virtual -Wpointer-arith -Wcast-qual -Wconversion -Wno-error")
178

179 180 181
    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
        set(INASTEMP_CXX_FLAGS  "${INASTEMP_CXX_FLAGS} -m64")
    endif()
182

183 184 185 186
    OPTION( INASTEMP_ATTACHE_SOURCE "Set to on to add -g flag" OFF )
    if( INASTEMP_ATTACHE_SOURCE )
        set(INASTEMP_CXX_FLAGS  "${INASTEMP_CXX_FLAGS} -g")
    endif(INASTEMP_ATTACHE_SOURCE)
187 188
endif()

189 190 191 192 193 194
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "icpc.*$")
  set(INASTEMP_CXX_FLAGS "${INASTEMP_CXX_FLAGS} -diag-disable 2304 -diag-disable 10121 -diag-disable 10120")
else()
  set(INASTEMP_CXX_FLAGS "${INASTEMP_CXX_FLAGS} -Wold-style-cast")
endif()

195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
#===========================================================================
# Generate config
#===========================================================================
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/Src/InastempConfig.h.cmake
        ${CMAKE_CURRENT_BINARY_DIR}/Src/InastempConfig.h  )

#===========================================================================
# Build lib
#===========================================================================
add_subdirectory(Src)


if(NOT INASTEMP_JUST_LIB)
    #===========================================================================
    # Build patterns
    #===========================================================================
    add_subdirectory(Patterns)

    #===========================================================================
    # Build unit tests
    #===========================================================================
    enable_testing()
    add_subdirectory(UTests)

    #===========================================================================
    # Build examples
    #===========================================================================
    add_subdirectory(Examples)
endif()

#===========================================================================
# Export cmake info
#===========================================================================
configure_file(${INASTEMP_SOURCE_DIR}/CMakeModules/InastempInfo.cmake.in
    ${INASTEMP_BINARY_DIR}/InastempInfo.cmake
    @ONLY IMMEDIATE
)
232 233 234
if(INASTEMP_DO_INSTALL)
    install(FILES  ${INASTEMP_BINARY_DIR}/InastempInfo.cmake  DESTINATION lib/  )
endif()
235

236
if(INASTEMP_AS_SUBPROJECT)
237 238 239 240
    set(INASTEMP_CXX_FLAGS  "${INASTEMP_CXX_FLAGS}" PARENT_SCOPE)
    set(INASTEMP_BINARY_DIR  "${INASTEMP_BINARY_DIR}" PARENT_SCOPE)
    set(INASTEMP_SOURCE_DIR  "${INASTEMP_SOURCE_DIR}" PARENT_SCOPE)
    set(INASTEMP_INCLUDE_DIR  "${INASTEMP_INCLUDE_DIR}" PARENT_SCOPE)
241 242
else()
    # nothing - we are not used by another lib here
243
endif()
244 245 246