293 lines
9.6 KiB
CMake
293 lines
9.6 KiB
CMake
cmake_minimum_required(VERSION 3.10)
|
|
|
|
# set the project name
|
|
set(CMAKE_PROJECT_NAME "TOMOATT")
|
|
project(${CMAKE_PROJECT_NAME} VERSION 1.1.2 LANGUAGES C CXX )
|
|
|
|
# set install directory
|
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
|
|
|
# check debug or release
|
|
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
message(STATUS "Build type: Debug")
|
|
else()
|
|
message(STATUS "Build type: Release")
|
|
endif()
|
|
|
|
# check compiler type
|
|
message(STATUS "Compiler type: ${CMAKE_CXX_COMPILER_ID}")
|
|
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
|
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
set(CXX_ADDITIONAL_FLAGS "-Wall -pedantic -g -O0")
|
|
else()
|
|
set(CXX_ADDITIONAL_FLAGS "-Wall -pedantic -O3 -funroll-loops -ffast-math -ftree-vectorize")
|
|
endif()
|
|
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
|
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
set(CXX_ADDITIONAL_FLAGS "-Wall -pedantic -g -O0 -lm -lstdc++fs")
|
|
else()
|
|
set(CXX_ADDITIONAL_FLAGS "-Wall -pedantic -lm -O3 -funroll-loops -ffast-math -ftree-vectorize -lstdc++fs")
|
|
endif()
|
|
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
|
|
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
set(CXX_ADDITIONAL_FLAGS "-diag-disable=10441,2012,2015,2017,2047,2304,2305,3868,10193,10315,11074,11076 -Wall -pedantic -g -O0 -lm -lstdc++fs")
|
|
else()
|
|
set(CXX_ADDITIONAL_FLAGS "-diag-disable=10441,2012,2015,2017,2047,2304,2305,3868,10193,10315,11074,11076 -Wall -pedantic -O3 -funroll-loops -ffast-math -lm -ftree-vectorize -lstdc++fs")
|
|
endif()
|
|
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Fujitsu")
|
|
MESSAGE(FATAL_ERROR "Fujitsu trad compiler is not supported. Please use clang mode.")
|
|
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "FujitsuClang")
|
|
MESSAGE("Compiler type: FujitsuClang")
|
|
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
set(CXX_ADDITIONAL_FLAGS "-Nclang -g -O0 -std=c++17 -mcpu=a64fx+sve -march=armv8-a+sve")
|
|
else()
|
|
set(CXX_ADDITIONAL_FLAGS "-Nclang -Ofast -std=c++17 -mcpu=a64fx+sve -march=armv8-a+sve")
|
|
endif()
|
|
else()
|
|
MESSAGE(FATAL_ERROR "Compiler type: Unknown")
|
|
endif()
|
|
# Default to C++17
|
|
if(NOT CMAKE_CXX_STANDARD)
|
|
set(CMAKE_CXX_STANDARD 17)
|
|
endif()
|
|
|
|
set(BUILD_TESTING OFF)
|
|
option(FORCE_DOWNLOAD_EXTERNAL_LIBS "Force download and use external libraries" OFF)
|
|
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_ADDITIONAL_FLAGS}")
|
|
|
|
# find installed MPI
|
|
message(STATUS "Running CMAKE FindMPI.cmake...")
|
|
find_package(MPI)
|
|
|
|
message(STATUS "MPI_FOUND: ${MPI_FOUND}")
|
|
message(STATUS "MPI_VERSION: ${MPI_VERSION}")
|
|
|
|
# find openmp ## WE DO NOT USE OPENMP BUT KEEP THIS FOR FUTURE USE
|
|
###find_package(OpenMP)
|
|
###if(OPENMP_FOUND)
|
|
### message(STATUS "OpenMP found")
|
|
### set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
|
|
### set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
|
### set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
|
|
### add_definitions(-DUSE_OMP)
|
|
###endif()
|
|
|
|
# find HDF5 parallel TODO: check parallel io is enable or not
|
|
message(STATUS "Running CMAKE FindHDF5.cmake...")
|
|
# set parallel HDF5 default
|
|
set(HDF5_PREFER_PARALLEL TRUE)
|
|
find_package(HDF5)
|
|
if(HDF5_FOUND)
|
|
message(STATUS "HDF5_FOUND: ${HDF5_FOUND}")
|
|
add_definitions(-DUSE_HDF5)
|
|
# check if HD5 PARALLEL is available
|
|
if(HDF5_IS_PARALLEL)
|
|
message(STATUS "HDF5 parallel is available.")
|
|
else()
|
|
message(FATAL "TomoATT requires HDF5 compiled with parallel IO option.")
|
|
endif()
|
|
endif()
|
|
|
|
# use collective io for HDF5: should be faster than independent io,
|
|
#but there will be a memory overhead and may not work on some systems.
|
|
#If you have a problem, please comment out this line.
|
|
add_definitions(-DUSE_HDF5_IO_COLLECTIVE)
|
|
|
|
# precision setting (uncomment for single precision. default is double precision.)
|
|
#add_definitions(-DSINGLE_PRECISION)
|
|
|
|
# use SIMD (SSE/AVX/AVX2/AVX512) for vectorization, which is faster than the default but use a little more memory.
|
|
if (USE_SIMD)
|
|
message(STATUS "TomoATT is compiled with SIMD.")
|
|
add_definitions(-DUSE_SIMD)
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -mfma")
|
|
endif()
|
|
|
|
# find cuda package if USE_CUDA is defined
|
|
if(USE_CUDA)
|
|
message(STATUS "Running CMAKE FindCUDA.cmake...")
|
|
enable_language(CUDA)
|
|
find_package(CUDA)
|
|
else()
|
|
message(STATUS "TomoATT is compiled without cuda, because -DUSE_CUDA=True is not defined")
|
|
endif()
|
|
|
|
if(CUDA_FOUND) # TODO : add HIP here in the future
|
|
message(STATUS "CUDA_FOUND: ${CUDA_FOUND}")
|
|
add_definitions(-DUSE_CUDA)
|
|
set(CUDA_LIBRARY_NAME "TOMOATT_CUDA")
|
|
|
|
# list of source and header files for cuda
|
|
file(GLOB SOURCES_CUDA "cuda/*.cu")
|
|
file(GLOB HEADERS_CUDA "cuda/*.cuh")
|
|
|
|
# cuda flag
|
|
#
|
|
# for production
|
|
set(CMAKE_CUDA_FLAGS "-fPIC -O3 -use_fast_math -extra-device-vectorization -gencode arch=compute_61,code=sm_61")
|
|
#
|
|
# for debugging
|
|
#set(CMAKE_CUDA_FLAGS "-fPIC -lineinfo -g -G -O0 -gencode arch=compute_61,code=sm_61")
|
|
set(CMAKE_CUDA_STANDARD "11")
|
|
message(STATUS, "TomoATT will be compiled with cuda.")
|
|
else()
|
|
message(STATUS "TomoATT will be compiled without cuda, because cuda is not found or -DUSE_CUDA=True was not specified.")
|
|
endif()
|
|
|
|
# synchronize the adjuscent ghost layers for each direction oft the sweep
|
|
# which is more frequent than the referred paper but necessary
|
|
add_definitions(-DFREQ_SYNC_GHOST)
|
|
|
|
# find BLAS # WE DO NOT USE BLAS BUT KEEP THIS FOR FUTURE USE
|
|
#find_package(BLAS)
|
|
#if(BLAS_FOUND)
|
|
# message(STATUS "BLAS_FOUND: ${BLAS_FOUND} at ${BLAS_LIBRARIES}, ${BLAS_INCLUDE_DIRS}")
|
|
# add_definitions(-DUSE_BLAS)
|
|
# find_path(BLAS_INCLUDE_DIRS cblas.h
|
|
# /usr/include
|
|
# /usr/local/include
|
|
# /usr/local/include/openblas)
|
|
#endif()
|
|
|
|
# submodules
|
|
# yaml parser
|
|
find_package(yaml-cpp 0.8 QUIET)
|
|
if (yaml-cpp_FOUND AND NOT ${FORCE_DOWNLOAD_EXTERNAL_LIBS})
|
|
message(STATUS "yaml-cpp found")
|
|
message(STATUS "YAML_CPP_INCLUDE_DIR: ${YAML_CPP_INCLUDE_DIR}")
|
|
message(STATUS "YAML_CPP_LIBRARIES: ${YAML_CPP_LIBRARIES}")
|
|
else()
|
|
message(STATUS "yaml-cpp not found. Using external_libs/yaml-cpp ...")
|
|
add_subdirectory(external_libs)
|
|
set(YAML_CPP_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/external_libs/yaml-cpp/include)
|
|
set(YAML_CPP_LIBRARIES yaml-cpp)
|
|
endif()
|
|
|
|
# add include directory
|
|
include_directories(include cuda)
|
|
|
|
execute_process(
|
|
COMMAND git rev-parse --short HEAD
|
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
|
OUTPUT_VARIABLE GIT_COMMIT_HASH
|
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
)
|
|
|
|
configure_file(
|
|
${PROJECT_SOURCE_DIR}/include/version.h.in
|
|
${PROJECT_SOURCE_DIR}/include/version.h
|
|
)
|
|
|
|
# list of source files
|
|
file(GLOB SOURCES "src/*.cpp")
|
|
if(CUDA_FOUND)
|
|
file(GLOB HEADERS "include/*.h" "cuda/*.cuh")
|
|
else()
|
|
file(GLOB HEADERS "include/*.h")
|
|
endif()
|
|
file(GLOB SOURCES_EXT_XML "external_libs/tinyxml2/*.cpp")
|
|
|
|
# compile cuda code
|
|
if (CUDA_FOUND)
|
|
include_directories(${CUDA_INCLUDE_DIRS})
|
|
add_library(${CUDA_LIBRARY_NAME} STATIC ${SOURCES_CUDA} ${HEADERS_CUDA} )
|
|
target_include_directories(${CUDA_LIBRARY_NAME} PUBLIC ${YAML_CPP_INCLUDE_DIR})
|
|
target_include_directories(${CUDA_LIBRARY_NAME} PUBLIC ${HDF5_INCLUDE_DIRS})
|
|
target_include_directories(${CUDA_LIBRARY_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/external_libs/tinyxml2)
|
|
endif()
|
|
|
|
|
|
#
|
|
# compile the executables
|
|
# all the files with the name *.cxx is compiled as an executable
|
|
#
|
|
#file( GLOB APP_SOURCES src/*.cxx )
|
|
|
|
# add one by one
|
|
set(APP_SOURCES
|
|
src/TOMOATT.cxx
|
|
#src/TOMOATT_solver_only.cxx
|
|
#src/TOMOATT_2d_precalc.cxx
|
|
#src/SrcRecWeight.cxx
|
|
)
|
|
|
|
# if BUILD_TESTING is defined, make APP_TEST and append to APP_SOURCES list
|
|
if(BUILD_TESTING)
|
|
# use all the cxx files in tests/ directory
|
|
file( GLOB APP_TEST tests/*.cxx)
|
|
# or you can specify the test files one by one
|
|
#set(APP_TEST
|
|
# tests/read_write_srcrec.cxx
|
|
#)
|
|
list(APPEND APP_SOURCES ${APP_TEST})
|
|
endif()
|
|
|
|
foreach( execsourcefile ${APP_SOURCES} )
|
|
# get app name from file name
|
|
get_filename_component(EXEC_NAME ${execsourcefile} NAME_WE)
|
|
|
|
# add the executable
|
|
add_executable(${EXEC_NAME} ${execsourcefile} ${SOURCES} ${HEADERS} ${SOURCES_EXT_XML})
|
|
|
|
# set include path
|
|
target_include_directories(${EXEC_NAME} PRIVATE
|
|
${PROJECT_SOURCE_DIR}/include
|
|
${PROJECT_SOURCE_DIR}/cuda
|
|
${PROJECT_SOURCE_DIR}/external_libs/tinyxml2)
|
|
|
|
# link mpi
|
|
target_link_libraries(${EXEC_NAME} PUBLIC MPI::MPI_CXX)
|
|
|
|
# link yaml-app:
|
|
target_link_libraries(${EXEC_NAME} PUBLIC ${YAML_CPP_LIBRARIES})
|
|
target_include_directories(${EXEC_NAME} PUBLIC ${YAML_CPP_INCLUDE_DIR})
|
|
|
|
# link HDF5
|
|
if(HDF5_FOUND)
|
|
target_link_libraries(${EXEC_NAME} PUBLIC ${HDF5_LIBRARIES})
|
|
target_include_directories(${EXEC_NAME} PUBLIC ${HDF5_INCLUDE_DIRS})
|
|
endif()
|
|
|
|
# link blas
|
|
if(BLAS_FOUND)
|
|
target_link_libraries(${EXEC_NAME} PUBLIC ${BLAS_LIBRARIES})
|
|
target_include_directories(${EXEC_NAME} PUBLIC ${BLAS_INCLUDE_DIRS})
|
|
endif()
|
|
|
|
# link cuda
|
|
if (CUDA_FOUND)
|
|
|
|
#set_target_properties(${CUDA_LIBRARY_NAME} PROPERTIES CUDA_ARCHITECTURES "35;50;72")
|
|
set_target_properties(${CUDA_LIBRARY_NAME} PROPERTIES CUDA_ARCHITECTURES "61")
|
|
set_property(TARGET ${CUDA_LIBRARY_NAME} PROPERTY CUDA_ARCHITECTURES 61)
|
|
|
|
target_link_libraries(${EXEC_NAME} PRIVATE ${CUDA_LIBRARY_NAME})
|
|
target_link_libraries(${CUDA_LIBRARY_NAME} PUBLIC MPI::MPI_CXX)
|
|
target_link_libraries(${CUDA_LIBRARY_NAME} PUBLIC yaml-cpp)
|
|
target_link_libraries(${CUDA_LIBRARY_NAME} PUBLIC ${HDF5_LIBRARIES})
|
|
|
|
endif()
|
|
|
|
|
|
endforeach( execsourcefile ${APP_SOURCES} )
|
|
|
|
# install
|
|
install(TARGETS TOMOATT DESTINATION bin)
|
|
|
|
# test
|
|
|
|
# We check if this is the main file
|
|
# you don't usually want users of your library to
|
|
# execute tests as part of their build
|
|
if (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR} AND BUILD_TESTING)
|
|
include(CTest)
|
|
|
|
# loop over APP_TEST
|
|
foreach( execsourcefile ${APP_TEST} )
|
|
add_test(NAME ${execsourcefile} COMMAND ${EXEC_NAME} ${execsourcefile})
|
|
endforeach( execsourcefile ${APP_TEST} )
|
|
endif ()
|
|
|
|
enable_testing()
|