cmake_minimum_required(VERSION 2.8) ##### Check GCC version ##### if(${CMAKE_C_COMPILER_VERSION} VERSION_LESS 7.0.0) message(FATAL_ERROR, "gcc >= 7.0.0 is required.") endif() if(${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 7.0.0) message(FATAL_ERROR, "g++ >= 7.0.0 is required.") endif() ##### Set default behavior ##### set(DEFAULT_USE_OMP Yes) set(DEFAULT_USE_GPU No) set(DEFAULT_USE_PYTHON Yes) set(DEFAULT_USE_TEST Yes) if(("${CMAKE_HOST_SYSTEM_PROCESSOR}" MATCHES "^x86.*") OR ("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "AMD64")) message(STATUS "SIMD SUPPORT: Yes") set(DEFAULT_OPT_FLAGS "-mtune=native -march=native -mfpmath=both") set(DEFAULT_USE_SIMD Yes) else() message(STATUS "SIMD SUPPORT: No") set(DEFAULT_OPT_FLAGS "-mtune=native -march=native") set(DEFAULT_USE_SIMD No) endif() if(NOT DEFINED USE_SIMD) set(USE_SIMD ${DEFAULT_USE_SIMD}) endif() if(NOT DEFINED USE_OMP) set(USE_OMP ${DEFAULT_USE_OMP}) endif() if(NOT DEFINED USE_GPU) set(USE_GPU ${DEFAULT_USE_GPU}) endif() if(NOT DEFINED USE_PYTHON) set(USE_PYTHON ${DEFAULT_USE_PYTHON}) endif() if(NOT DEFINED USE_TEST) set(USE_TEST ${DEFAULT_USE_TEST}) endif() if(NOT DEFINED OPT_FLAGS) set(OPT_FLAGS ${DEFAULT_OPT_FLAGS}) endif() message(STATUS "CMAKE_HOST_SYSTEM_PROCESSOR = ${CMAKE_HOST_SYSTEM_PROCESSOR}") message(STATUS "USE_SIMD = ${USE_SIMD}") message(STATUS "USE_OMP = ${USE_OMP}") message(STATUS "USE_GPU = ${USE_GPU}") message(STATUS "USE_TEST = ${USE_TEST}") message(STATUS "USE_PYTHON = ${USE_PYTHON}") message(STATUS "OPT_FLAGS = ${OPT_FLAGS}") ##### configure include files ##### file(GLOB_RECURSE header_files ${CMAKE_CURRENT_SOURCE_DIR}/src/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/src/*.h) foreach(path IN LISTS header_files) string(REPLACE ${CMAKE_CURRENT_SOURCE_DIR}/src/ ${CMAKE_CURRENT_SOURCE_DIR}/include/ path_dst ${path}) configure_file(${path} ${path_dst} COPYONLY) endforeach() include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) ##### set external projects ##### include(ExternalProject) include(${CMAKE_SOURCE_DIR}/FetchContent.cmake) # Eigen set(EIGEN_BUILD_DIR ${CMAKE_BINARY_DIR}/eigen) set(EIGEN_INSTALL_DIR ${CMAKE_SOURCE_DIR}/include) set(EIGEN_INCLUDE_DIR ${EIGEN_INSTALL_DIR}) ExternalProject_Add( eigen URL https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.tar.gz PREFIX ${EIGEN_BUILD_DIR} CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory ${EIGEN_BUILD_DIR}/src/eigen/Eigen ${EIGEN_INCLUDE_DIR}/Eigen && ${CMAKE_COMMAND} -E copy_directory ${EIGEN_BUILD_DIR}/src/eigen/unsupported ${EIGEN_INCLUDE_DIR}/unsupported TEST_COMMAND "" ) include_directories(SYSTEM ${EIGEN_INCLUDE_DIR}) # Google test if(USE_TEST) FetchContent_Declare( googletest_fetch GIT_REPOSITORY https://github.com/google/googletest GIT_TAG release-1.8.1 ) FetchContent_GetProperties(googletest_fetch) if(NOT googletest_fetch_POPULATED) message(STATUS "Fetch googletest for C++ testing") FetchContent_Populate(googletest_fetch) add_subdirectory(${googletest_fetch_SOURCE_DIR}) endif() else() message(STATUS "Skip downloding googletest") endif() # Pybind11 if(USE_PYTHON) if(MSYS OR MINGW OR CYGWIN) set(PYBIND11_BUILD_DIR ${CMAKE_BINARY_DIR}/pybind11) set(PYBIND11_INSTALL_DIR ${CMAKE_SOURCE_DIR}/python/pybind11) set(PYBIND11_INCLUDE_DIR ${PYBIND11_INSTALL_DIR}/include) ExternalProject_Add( pybind11_pop URL http://github.com/pybind/pybind11/archive/v2.5.0.tar.gz PREFIX ${PYBIND11_BUILD_DIR} CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory ${PYBIND11_BUILD_DIR}/src/pybind11_pop ${PYBIND11_INSTALL_DIR} TEST_COMMAND "" ) include_directories(SYSTEM ${PYBIND11_INCLUDE_DIR}) else() FetchContent_Declare( pybind11_fetch GIT_REPOSITORY https://github.com/pybind/pybind11 GIT_TAG v2.5.0 ) FetchContent_GetProperties(pybind11_fetch) if(NOT pybind11_fetch_POPULATED) message(STATUS "Fetch pybind11 for python-binding") FetchContent_Populate(pybind11_fetch) add_subdirectory(${pybind11_fetch_SOURCE_DIR}) endif() endif() else() message(STATUS "Skip downloding pybind11") endif() ##### set warnings ##### if(NOT USE_GPU) set(WARNING_C "-Wall -Wextra -Werror=undef -Wlogical-op -Wmissing-include-dirs \ -Wpointer-arith -Winit-self -Wfloat-equal -Wsuggest-attribute=noreturn \ -Werror=missing-prototypes -Werror=implicit-function-declaration -Werror=missing-declarations -Werror=return-type \ -Werror=incompatible-pointer-types -Werror=format=2 -Wredundant-decls -Wmissing-noreturn \ -Wimplicit-fallthrough=5 -Wshadow -Wendif-labels -Wstrict-aliasing=2 -Wwrite-strings -Werror=overflow -Wdate-time \ -Wnested-externs -fdiagnostics-color=auto") set(WARNING_CPP "-Wall -Wextra -Werror=undef -Wlogical-op -Wmissing-include-dirs \ -Wpointer-arith -Winit-self -Wfloat-equal -Wsuggest-attribute=noreturn \ -Werror=missing-prototypes -Werror=implicit-function-declaration -Werror=missing-declarations -Werror=return-type \ -Werror=incompatible-pointer-types -Werror=format=2 -Wredundant-decls -Wmissing-noreturn \ -Wimplicit-fallthrough=5 -Wshadow -Wendif-labels -Wstrict-aliasing=2 -Wwrite-strings -Werror=overflow -Wdate-time \ -fdiagnostics-color=auto") endif() ##### set output directory ##### if(NOT DEFINED PYTHON_SETUP_FLAG) message(STATUS "Install from cmakebuild") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../bin) if(MSVC) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/../lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/../bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/../bin) endif() else() message(STATUS "Install from pip") endif() message(STATUS "OUTDIR = ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") if(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../lib) endif() ##### set flags ##### if(MSYS OR MINGW OR UNIX OR APPLE) set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread") # GCC>=8.0.0 requires C++14 for building python if(8.0.0 VERSION_LESS ${CMAKE_CXX_COMPILER_VERSION}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") # set for literals of imaginary number if(NOT MINGW) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fext-numeric-literals") endif() if(USE_OMP) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp") endif() if(USE_GPU) add_compile_options("-D _USE_GPU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") add_compile_options("-fPIC") endif() if(USE_SIMD) add_compile_options("-D _USE_SIMD") endif() set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${OPT_FLAGS}") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${OPT_FLAGS}") if(8.0.0 VERSION_LESS ${CMAKE_CXX_COMPILER_VERSION}) set(PYBIND11_CPP_STANDARD -std=gnu++14) endif() elseif(MSVC) SET(CMAKE_C_COMPILER ${CMAKE_CXX_COMPILER}) # compile csim with cpp since VC not completely support C99 complex values add_compile_options("/TP") # ignore warning about template export add_compile_options(/wd4251) # ignore warning on non-Unicode files add_compile_options(/wd4819) # Check if AVX2 is supported include(${CMAKE_SOURCE_DIR}/FindAVX2.cmake) CHECK_AVX2_WINDOWS() #CHECK_AVX2_LINUX() message(STATUS "AVX2_FOUND = ${AVX2_FOUND}") if(USE_SIMD AND AVX2_FOUND) message(STATUS "AVX2 Enabled") add_compile_options("/D_USE_SIMD") else() message(STATUS "AVX2 Disabled") endif() if(USE_OMP) add_compile_options("/openmp") endif() if(USE_GPU) add_compile_options("/D_USE_GPU") endif() # static link to multithread runtimes set(variables CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS_MINSIZEREL ) foreach(variable ${variables}) if(${variable} MATCHES "/MD") string(REGEX REPLACE "/MD" "/MT" ${variable} "${${variable}}") endif() endforeach() endif() ##### show configurations ##### message(STATUS "CMAKE_SYSTEM_NAME = ${CMAKE_SYSTEM_NAME}") message(STATUS "CMAKE_C_COMPILER = ${CMAKE_C_COMPILER}") message(STATUS "CMAKE_CXX_COMPILER = ${CMAKE_CXX_COMPILER}") message(STATUS "CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}") message(STATUS "CMAKE_CXX_FLAGS = ${CMAKE_CXX_FLAGS}") message(STATUS "CMAKE_CXX_FLAGS_DEBUG = ${CMAKE_CXX_FLAGS_DEBUG}") message(STATUS "CMAKE_CXX_FLAGS_RELEASE = ${CMAKE_CXX_FLAGS_RELEASE}") ##### add make directories ##### add_subdirectory(src) if(USE_TEST) add_subdirectory(test) endif() if(USE_PYTHON) add_subdirectory(python) endif() add_subdirectory(benchmark) ##### custom target ##### # testing if(USE_TEST) if(USE_GPU) add_custom_target(test DEPENDS csim_test DEPENDS cppsim_test DEPENDS gpusim_test DEPENDS vqcsim_test COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/bin/csim_test COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/bin/cppsim_test COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/bin/gpusim_test COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/bin/vqcsim_test ) else() add_custom_target(test DEPENDS csim_test DEPENDS cppsim_test DEPENDS vqcsim_test COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/bin/csim_test COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/bin/cppsim_test COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/bin/vqcsim_test ) endif() endif() # benchmark add_custom_target(bench DEPENDS csim_benchmark DEPENDS cppsim_benchmark COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/bin/csim_benchmark #COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/bin/cppsim_benchmark ) # shared libs add_custom_target(shared DEPENDS csim_shared DEPENDS cppsim_shared DEPENDS vqcsim_shared ) # python binding if(USE_PYTHON) add_custom_target(python DEPENDS qulacs ) add_custom_target(pythontest DEPENDS qulacs COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/python/test/test_qulacs.py ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ) endif()