diff --git a/cmake/3rdPartyTools.cmake b/cmake/3rdPartyTools.cmake index 875369671..ba961c93b 100644 --- a/cmake/3rdPartyTools.cmake +++ b/cmake/3rdPartyTools.cmake @@ -8,14 +8,15 @@ message(STATUS "Checking whether to use built-in libraries...") set(3RDPARTY_TOOLS blas lapack -arpack +arpack ucpp +readline c9x-complex netcdf netcdf-fortran pnetcdf +protobuf fftw -readline xblas lio apbs @@ -25,39 +26,52 @@ libbz2 plumed libm mkl +kmmd mpi4py perlmol boost nccl mbx -mirp) +tng_io +nlopt +libtorch +xtb +dftbplus +deepmd-kit) set(3RDPARTY_TOOL_USES -"for fundamental linear algebra calculations" -"for fundamental linear algebra calculations" -"for fundamental linear algebra calculations" -"used as a preprocessor for the NAB compiler" -"used as a support library on systems that do not have C99 complex.h support" -"for creating trajectory data files" -"for creating trajectory data files from Fortran" -"used by cpptraj for parallel trajectory output" -"used to do Fourier transforms very quickly" -"used for the console functionality of cpptraj" -"used for high-precision linear algebra calculations" -"used by Sander to run certain QM routines on the GPU" -"used by Sander as an alternate Poisson-Boltzmann equation solver" -"used by Sander as an alternate user interface" -"for various compression and decompression tasks" -"for bzip2 compression in cpptraj" -"used as an alternate MD backend for Sander" +"for fundamental linear algebra calculations" +"for fundamental linear algebra calculations" +"for fundamental linear algebra calculations" +"used as a preprocessor for the NAB compiler" +"enables an interactive terminal in cpptraj" +"used as a support library on systems that do not have C99 complex.h support" +"for creating trajectory data files" +"for creating trajectory data files from Fortran" +"used by cpptraj for parallel trajectory output" +"protocol buffers library, used for communication with external software in QM/MM" +"used to do Fourier transforms very quickly" +"used for high-precision linear algebra calculations" +"used by Sander to run certain QM routines on the GPU" +"used by Sander as an alternate Poisson-Boltzmann equation solver" +"used by Sander as an alternate user interface" +"for various compression and decompression tasks" +"for bzip2 compression in cpptraj" +"used as an alternate MD backend for Sander" "for fundamental math routines if they are not contained in the C library" -"alternate implementation of lapack and blas that is tuned for speed" -"MPI support library for MMPBSA.py" +"alternate implementation of lapack and blas that is tuned for speed" +"Machine-learning molecular dynamics" +"MPI support library for MMPBSA.py" "chemistry library used by FEW" "C++ support library" "NVIDIA parallel GPU communication library" "computes energies and forces for pmemd with the MB-pol model" -"MolSSI Integral Reference Project library for computing the Boys function in QUICK") +"enables GROMACS tng trajectory input in cpptraj" +"used to perform nonlinear optimizations" +"enables libtorch C++ library for tensor computation and dynamic neural networks" +"enables the QM/MM interface with the external xtb software" +"enables the QM/MM interface with the external dftbplus software" +"enables DPRc machine learning potential with the external deepmd-kit software") # Logic to disable tools set(3RDPARTY_SUBDIRS "") @@ -69,12 +83,12 @@ macro(set_3rdparty TOOL STATUS) set(${TOOL}_EXTERNAL FALSE) set(${TOOL}_DISABLED FALSE) set(${TOOL}_ENABLED TRUE) - - + + if(${STATUS} STREQUAL EXTERNAL) set(${TOOL}_EXTERNAL TRUE) elseif(${STATUS} STREQUAL INTERNAL) - + #the only way to get this message would be to use FORCE_INTERNAL_LIBS incorrectly, unless someone messed up somewhere if("${BUNDLED_3RDPARTY_TOOLS}" MATCHES ${TOOL}) set(${TOOL}_INTERNAL TRUE) @@ -89,21 +103,21 @@ macro(set_3rdparty TOOL STATUS) # we're in a submodule, and it's not required, so it's OK that the tool is not bundled set(${TOOL}_DISABLED TRUE) set(${TOOL}_ENABLED FALSE) - + endif() endif() - + else() list_contains(TOOL_REQUIRED ${TOOL} ${REQUIRED_3RDPARTY_TOOLS}) - + if(TOOL_REQUIRED) message(FATAL_ERROR "3rd party program ${TOOL} is required to build ${PROJECT_NAME}, but it is disabled (likely because it was not found).") endif() - + set(${TOOL}_DISABLED TRUE) set(${TOOL}_ENABLED FALSE) - - endif() + + endif() endmacro(set_3rdparty) #------------------------------------------------------------------------------ @@ -126,14 +140,14 @@ endif() # suspicious 3rd party tools: tools where there are often problems with the system install if(NOT DEFINED SUSPICIOUS_3RDPARTY_TOOLS) - set(SUSPICIOUS_3RDPARTY_TOOLS "") + set(SUSPICIOUS_3RDPARTY_TOOLS "mkl,boost") endif() option(TRUST_SYSTEM_LIBS "If true, Amber will use all found system libraries, even if they are considered problematic by the Amber developers" FALSE) foreach(TOOL ${3RDPARTY_TOOLS}) list(FIND NEEDED_3RDPARTY_TOOLS ${TOOL} TOOL_INDEX) - + test(NEED_${TOOL} NOT "${TOOL_INDEX}" EQUAL -1) endforeach() @@ -168,11 +182,11 @@ endif() #------------------------------------------------------------------------------ if(NEED_ucpp) find_program(UCPP_LOCATION ucpp) - + if(UCPP_LOCATION) set_3rdparty(ucpp EXTERNAL) else() - set_3rdparty(ucpp INTERNAL) + set_3rdparty(ucpp INTERNAL) endif() endif() @@ -182,21 +196,13 @@ endif() if(NEED_readline) find_package(Readline) - + if(READLINE_FOUND) set_3rdparty(readline EXTERNAL) + elseif(NOT TARGET_WINDOWS) + set_3rdparty(readline INTERNAL) else() - #check if the internal readline has the dependencies it needs - find_package(Termcap) - - if(${CMAKE_SYSTEM_NAME} STREQUAL Windows OR Termcap_FOUND) - #internal readline WILL be able to build - set_3rdparty(readline INTERNAL) - else() - #internal readline will NOT be able to build - message(STATUS "Cannot use internal readline because its dependency (libtermcap/libtinfo/libncurses) was not found.") - set_3rdparty(readline DISABLED) - endif() + set_3rdparty(readline DISABLED) endif() endif() @@ -208,10 +214,10 @@ if(NEED_mkl) set(MKL_NEEDINCLUDES FALSE) set(MKL_NEEDEXTRA FALSE) - + # Static MKL is not the default at this time. # - # MKL has a fftw3 compatibility interface. Wierdly enough, this interface is spread out between several different libraries: the main interface library, the + # MKL has a fftw3 compatibility interface. Wierdly enough, this interface is spread out between several different libraries: the main interface library, the # cdft library, and the actual fftw3 interface library (which is distributed as source code, not a binary). # So, even though we don't use the fftw3 interface, there are symbols in the main MKL libraries which conflict with the symbols from fftw3. # Oddly, on many platforms, the linker handles this fine. However, in at least one case (the SDSC supercomputer Comet, running a derivative of CentOS), @@ -222,10 +228,10 @@ if(NEED_mkl) option(MKL_STATIC "Whether to prefer MKL's static libraries" FALSE) option(MKL_MULTI_THREADED "Whether to link MKL in OpenMP mode to parallelize singlethreaded calls to MKL functions" TRUE) - + set(MKL_STATIC FALSE) find_package(MKL) - + if(MKL_FOUND) set_3rdparty(mkl EXTERNAL) else() @@ -233,6 +239,18 @@ if(NEED_mkl) endif() endif() +if(NEED_kmmd) + find_package(KMMD) + if(KMMD_FOUND) + set_3rdparty(kmmd EXTERNAL) + else() + set_3rdparty(kmmd INTERNAL) + set(KMMD_LIB kmmd) + endif() + +endif() + + #------------------------------------------------------------------------------ # FFTW @@ -241,13 +259,13 @@ if(NEED_fftw) if(DEFINED USE_FFT AND NOT USE_FFT) set_3rdparty(fftw DISABLED) - else() + else() if(MPI) find_package(FFTW COMPONENTS MPI Fortran) else() find_package(FFTW COMPONENTS Fortran) endif() - + if(FFTW_FOUND) set_3rdparty(fftw EXTERNAL) else() @@ -280,6 +298,27 @@ if(NEED_netcdf-fortran) endif() endif() +#------------------------------------------------------------------------------ +# Protobuf +#------------------------------------------------------------------------------ + +if(NEED_protobuf) + find_package(Protobuf) + + if(Protobuf_FOUND) + if(BUILD_PROTOBUF) + set_3rdparty(protobuf EXTERNAL) + else() + set_3rdparty(protobuf DISABLED) + endif() + else() + if(BUILD_PROTOBUF) + set_3rdparty(protobuf INTERNAL) + else() + set_3rdparty(protobuf DISABLED) + endif() + endif() +endif() #------------------------------------------------------------------------------ # XBlas @@ -288,10 +327,10 @@ endif() if(NEED_xblas) find_package(XBLAS) - + if(XBLAS_FOUND) set_3rdparty(xblas EXTERNAL) - else() + else() if(EXISTS "${M4}") set_3rdparty(xblas INTERNAL) else() @@ -309,13 +348,13 @@ if(NEED_blas) # because of the earlier check, we can be sure that NEED_blas == N # this calls FindBLAS find_package(LAPACKFixed) - + if(BLAS_FOUND) set_3rdparty(blas EXTERNAL) else() set_3rdparty(blas INTERNAL) endif() - + if(LAPACK_FOUND) set_3rdparty(lapack EXTERNAL) else() @@ -326,7 +365,7 @@ endif() if(NEED_arpack) # ARPACK find_package(ARPACK) - + if(ARPACK_FOUND) set_3rdparty(arpack EXTERNAL) else() @@ -340,7 +379,7 @@ endif() if(NEED_pnetcdf) find_package(PnetCDF) - + if(PnetCDF_FOUND) set_3rdparty(pnetcdf EXTERNAL) else() @@ -354,8 +393,8 @@ endif() if(NEED_apbs) - find_package(APBS) - + find_package(APBS) + if(APBS_FOUND) set_3rdparty(apbs EXTERNAL) else() @@ -383,10 +422,10 @@ endif() if(NEED_lio) find_package(LIO) - - if(LIO_FOUND) + + if(LIO_FOUND) set_3rdparty(lio EXTERNAL) - else() + else() set_3rdparty(lio DISABLED) endif() endif() @@ -398,7 +437,7 @@ endif() if(NEED_plumed) # PLUMED changed its C API in version 2.5. - # We can only build-time-link to versions >=2.5, though + # We can only build-time-link to versions >=2.5, though # runtime linking should work with all versions find_package(PLUMED 2.5) if(PLUMED_FOUND) @@ -414,7 +453,7 @@ endif() if(NEED_zlib) find_package(ZLIB) - + if(ZLIB_FOUND) set_3rdparty(zlib EXTERNAL) else() @@ -427,8 +466,8 @@ endif() #------------------------------------------------------------------------------ if(NEED_libbz2) find_package(BZip2) - - + + if(BZIP2_FOUND) set_3rdparty(libbz2 EXTERNAL) else() @@ -438,7 +477,7 @@ endif() #------------------------------------------------------------------------------ # Math library -#------------------------------------------------------------------------------ +#------------------------------------------------------------------------------ if(NEED_libm) # figure out if we need a math library @@ -473,10 +512,10 @@ endif() # PerlMol #------------------------------------------------------------------------------ if(NEED_perlmol) - + if(BUILD_PERL) find_package(PerlModules COMPONENTS Chemistry::Mol ExtUtils::MakeMaker) - + if(EXISTS "${PERLMODULES_CHEMISTRY_MOL_MODULE}") set_3rdparty(perlmol EXTERNAL) else() @@ -493,7 +532,7 @@ if(NEED_perlmol) set_3rdparty(perlmol DISABLED) endif() endif() - + else() set_3rdparty(perlmol DISABLED) endif() @@ -503,9 +542,9 @@ endif() # Boost #------------------------------------------------------------------------------ if(NEED_boost) - + set(Boost_DETAILED_FAILURE_MSG TRUE) - find_package(Boost COMPONENTS thread system program_options iostreams regex timer chrono filesystem graph) + find_package(Boost COMPONENTS thread system program_options iostreams regex timer chrono filesystem graph) set(EXT_BOOST_OK ${Boost_FOUND}) @@ -547,7 +586,7 @@ endif() #------------------------------------------------------------------------------ # NVIDIA NCCL -#------------------------------------------------------------------------------ +#------------------------------------------------------------------------------ if(NEED_nccl) find_package(NCCL) @@ -562,7 +601,7 @@ endif() #------------------------------------------------------------------------------ # MBX # (http://paesanigroup.ucsd.edu/software/mbx.html) -#------------------------------------------------------------------------------ +#------------------------------------------------------------------------------ if(NEED_mbx) find_package(MBX 0.2.3 CONFIG) @@ -576,28 +615,155 @@ if(NEED_mbx) endif() #------------------------------------------------------------------------------ -# MIRP -# (https://github.com/MolSSI/MIRP) -#------------------------------------------------------------------------------ +# tng_io +#------------------------------------------------------------------------------ + +if(NEED_tng_io) + find_package(tng_io CONFIG) -if(NEED_mirp) - find_package(mirp 1.0.1 CONFIG) + if(NOT tng_io_FOUND) + message(STATUS "Could not find tng_io. To locate it, add its install dir to the prefix path.") + endif() - if(mirp_FOUND) - set_3rdparty(mirp EXTERNAL) + if(tng_io_FOUND) + set_3rdparty(tng_io EXTERNAL) + elseif(zlib_ENABLED) # tng io requires zlib + set_3rdparty(tng_io INTERNAL) else() - message(STATUS "Could not find mirp. To locate it, add its install dir to the prefix path.") - set_3rdparty(mirp DISABLED) + set_3rdparty(tng_io DISABLED) + endif() +endif() + +#------------------------------------------------------------------------------ +# libtorch +#------------------------------------------------------------------------------ + +if(NEED_libtorch AND LIBTORCH) + if (DEFINED TORCH_HOME) + # use external libtorch + if(NOT CUDA OR (CUDA AND CUDNN AND DEFINED CUDNN_INCLUDE_PATH AND DEFINED CUDNN_LIBRARY_PATH)) + set(CONTAIN_INSTALL_PREFIX FALSE) + if(CMAKE_INSTALL_PREFIX) + execute_process(COMMAND mkdir -p ${CMAKE_INSTALL_PREFIX}/lib COMMAND_ERROR_IS_FATAL ANY) + execute_process(COMMAND cp -r ${TORCH_HOME} ${CMAKE_INSTALL_PREFIX}/lib/libtorch COMMAND_ERROR_IS_FATAL ANY) + set(CONTAIN_INSTALL_PREFIX TRUE) + else() + execute_process(COMMAND cp -r ${TORCH_HOME} ${CMAKE_CURRENT_BINARY_DIR}/libtorch COMMAND_ERROR_IS_FATAL ANY) + endif() + + if(CONTAIN_INSTALL_PREFIX) + set(TORCH_HOME ${CMAKE_INSTALL_PREFIX}/lib/libtorch) + else() + set(TORCH_HOME ${CMAKE_CURRENT_BINARY_DIR}/libtorch) + endif() + + # edit cuda.cmake to config with amber and refind + execute_process(COMMAND python ${CMAKE_SOURCE_DIR}/AmberTools/src/libtorch/fix_cuda.py ${TORCH_HOME}/share/cmake/Caffe2/public/cuda.cmake) + + # stack mkl from amber to protect libtorch env + list(REMOVE_ITEM CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/hanjianwei") + set(OLD_MKL_INCLUDE_DIR ${MKL_INCLUDE_DIR}) + set(OLD_MKL_LIBRARIES ${MKL_LIBRARIES}) + set(MKL_INCLUDE_DIR "") + set(MKL_LIBRARIES "") + + # find libtorch + find_package(Torch REQUIRED PATHS ${TORCH_HOME} NO_DEFAULT_PATH) + + # recover original mkl vars for further amber configuration + set(MKL_INCLUDE_DIR ${OLD_MKL_INCLUDE_DIR}) + set(MKL_LIBRARIES ${OLD_MKL_LIBRARIES}) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/hanjianwei") + + message(STATUS "Libtorch: ${TORCH_HOME}") + + # set export variable + set(libtorch_ENABLED TRUE CACHE INTERNAL "whether libtorch is enabled") + set(LIBTORCH_INCLUDE_DIRS ${TORCH_INCLUDE_DIRS} CACHE INTERNAL "Libtorch header paths") + set(LIBTORCH_LIBRARIES ${TORCH_LIBRARIES} CACHE INTERNAL "Libtorch library paths") + + set_3rdparty(libtorch EXTERNAL) + else() + message(FATAL_ERROR "Libtorch with CUDA requires CUDNN. To find and configure it, define CUDNN, CUDNN_INCLUDE_PATH, and CUDNN_LIBRARY_PATH.") + endif() + else() + # use internal libtorch + set_3rdparty(libtorch INTERNAL) + endif() +else() + set(libtorch_ENABLED FALSE CACHE INTERNAL "whether libtorch is enabled") + set_3rdparty(libtorch DISABLED) +endif() + +#------------------------------------------------------------------------------ +# nlopt +#------------------------------------------------------------------------------ + +if(NEED_nlopt) + # + # the nlopt headers depend on the nlopt configuration + # because we are relying on the internal headers, our + # only option is to use the internal nlopt + # + set_3rdparty(nlopt INTERNAL) + + # + # In principle, we could search for external or use internal + # + #find_package(nlopt CONFIG) + #if(NOT nlopt_FOUND) + # message(STATUS "Could not find nlopt. To locate it, add its install dir to the prefix path.") + #endif() + #if(nlopt_FOUND) + # set_3rdparty(nlopt EXTERNAL) + #else() + # set_3rdparty(nlopt INTERNAL) + #endif() +endif() + + +if(NEED_xtb) + #set(CMAKE_FIND_DEBUG_MODE TRUE) + find_package(XTB REQUIRED) + #set(CMAKE_FIND_DEBUG_MODE FALSE) + if(XTB_FOUND) + set_3rdparty(xtb EXTERNAL) + else() + set_3rdparty(xtb DISABLED) + endif() +endif() + +if(NEED_dftbplus) + #set(CMAKE_FIND_DEBUG_MODE TRUE) + find_package(DFTBPLUS CONFIG REQUIRED) + #set(CMAKE_FIND_DEBUG_MODE FALSE) + if(DFTBPLUS_FOUND) + set_3rdparty(dftbplus EXTERNAL) + else() + set_3rdparty(dftbplus DISABLED) + endif() +endif() + +if(NEED_deepmd-kit) + # J. Zeng: idealy, libdeepmd.tar.gz should contain a cmake config + # However, it's not ready in the current version... + # so I manually add FindDeePMD.cmake + find_package(DeePMD REQUIRED) + if(DeePMD_FOUND) + set_3rdparty(deepmd-kit EXTERNAL) + else() + set_3rdparty(deepmd-kit DISABLED) endif() endif() -# we can now reset this back to the default behavior -- targets will be made PIC as needed in the individual CMake scripts -unset(CMAKE_POSITION_INDEPENDENT_CODE) # Apply overrides # ------------------------------------------------------------------------------------------------------------------------------------------------------- +# we can now reset this back to the default behavior -- targets will be made PIC as needed in the individual CMake scripts +unset(CMAKE_POSITION_INDEPENDENT_CODE) + set(FORCE_EXTERNAL_LIBS "" CACHE STRING "3rd party libraries to force using the system version of. Accepts a semicolon-seperated list of library names from the 3rd Party Libraries section of the build report.") set(FORCE_INTERNAL_LIBS "" CACHE STRING "3rd party libraries to force to build inside Amber. Accepts a semicolon-seperated list of library names from the 3rd Party Libraries section of the build report.") set(FORCE_DISABLE_LIBS "" CACHE STRING "3rd party libraries to force Amber to not use at all. Accepts a semicolon-seperated list of library names from the 3rd Party Libraries section of the build report.") @@ -632,54 +798,56 @@ foreach(TOOL ${FORCE_EXTERNAL_LIBS}) colormsg(YELLOW "Forcing ${TOOL} to be sourced externally") list_contains(VALID_TOOL ${TOOL} ${3RDPARTY_TOOLS}) - + if(NOT VALID_TOOL) message(FATAL_ERROR "${TOOL} is not a valid 3rd party library name.") endif() - + set_3rdparty(${TOOL} EXTERNAL) endforeach() -foreach(TOOL ${FORCE_INTERNAL_LIBS}) - colormsg(GREEN "Forcing ${TOOL} to be built internally") +if(INSIDE_AMBER) + foreach(TOOL ${FORCE_INTERNAL_LIBS}) + colormsg(GREEN "Forcing ${TOOL} to be built internally") - list_contains(VALID_TOOL ${TOOL} ${3RDPARTY_TOOLS}) - - if(NOT VALID_TOOL) - message(FATAL_ERROR "${TOOL} is not a valid 3rd party library name.") - endif() - - set_3rdparty(${TOOL} INTERNAL) -endforeach() + list_contains(VALID_TOOL ${TOOL} ${3RDPARTY_TOOLS}) + + if(NOT VALID_TOOL) + message(FATAL_ERROR "${TOOL} is not a valid 3rd party library name.") + endif() + + set_3rdparty(${TOOL} INTERNAL) + endforeach() +endif() foreach(TOOL ${FORCE_DISABLE_LIBS}) colormsg(HIRED "Forcing ${TOOL} to be disabled") list_contains(VALID_TOOL ${TOOL} ${3RDPARTY_TOOLS}) - + if(NOT VALID_TOOL) message(FATAL_ERROR "${TOOL} is not a valid 3rd party library name.") endif() - + set_3rdparty(${TOOL} DISABLED) endforeach() # force all unneeded tools to be disabled foreach(TOOL ${3RDPARTY_TOOLS}) list(FIND NEEDED_3RDPARTY_TOOLS ${TOOL} TOOL_INDEX) - + if(${TOOL_INDEX} EQUAL -1) set_3rdparty(${TOOL} DISABLED) endif() - + endforeach() -# check math library configurations +# check math library configuration if(LINALG_LIBS_REQUIRED AND NOT (mkl_ENABLED OR (blas_ENABLED AND lapack_ENABLED))) message(FATAL_ERROR "You must enable a linear algebra library -- either blas and lapack, or mkl") endif() -if(mkl_ENABLED AND (blas_ENABLED OR lapack_ENABLED)) +if(mkl_ENABLED AND (blas_ENABLED AND lapack_ENABLED)) # prefer MKL to BLAS set_3rdparty(blas DISABLED) set_3rdparty(lapack DISABLED) @@ -712,11 +880,13 @@ endif() if(readline_EXTERNAL) # rename target - import_libraries(readline - LIBRARIES readline::readline - INCLUDES ${READLINE_INCLUDE_DIR}/readline) + import_libraries(readline + LIBRARIES readline::readline + INCLUDES ${READLINE_INCLUDE_DIR}/readline) elseif(readline_INTERNAL) - list(APPEND 3RDPARTY_SUBDIRS readline) + + list(APPEND 3RDPARTY_SUBDIRS cpptraj/src/readline) + endif() #------------------------------------------------------------------------------ @@ -728,15 +898,15 @@ if(mkl_ENABLED) if(NOT MKL_FOUND) message(FATAL_ERROR "You enabled MKL, but it was not found.") endif() - + if(MIXING_COMPILERS AND OPENMP) message(WARNING "You are using different compilers from different vendors together. This may cause link errors with MKL and OpenMP. There is no way around this.") endif() - + if(mkl_ENABLED AND (blas_ENABLED OR lapack_ENABLED)) message(FATAL_ERROR "MKL replaces blas and lapack! They can't be enabled when MKL is in use!") endif() - + # add to library tracker import_libraries(mkl LIBRARIES ${MKL_FORTRAN_LIBRARIES} INCLUDES ${MKL_INCLUDE_DIRS}) endif() @@ -746,7 +916,7 @@ endif() #------------------------------------------------------------------------------ if(fftw_EXTERNAL) - + if(NOT FFTW_FOUND) message(FATAL_ERROR "Could not find FFTW, but it was set so be sourced externally!") endif() @@ -756,33 +926,55 @@ if(fftw_EXTERNAL) if(MPI) import_libraries(fftw_mpi LIBRARIES fftw::mpi_l) - endif() - + endif() + elseif(fftw_INTERNAL) list(APPEND 3RDPARTY_SUBDIRS fftw-3.3) endif() +#------------------------------------------------------------------------------ +# KMMD +#------------------------------------------------------------------------------ + +if(kmmd_EXTERNAL) + + if(NOT KMMD_FOUND) + message(FATAL_ERROR "Could not find KMMD, but it was set so be sourced externally!") + endif() + + # rename targets + using_library_targets(kmmd::kmmd) + import_libraries(kmmd LIBRARIES kmmd::kmmd) + +elseif(kmmd_INTERNAL) + + message(STATUS "KMMD not added to 3RDPARTY_SUBDIRS :") +#- list(APPEND 3RDPARTY_SUBDIRS kmmd) + message(STATUS " : " "${3RDPARTY_SUBDIRS}") + +endif() + #------------------------------------------------------------------------------ # NetCDF #------------------------------------------------------------------------------ if(netcdf_EXTERNAL) - + if(NOT NetCDF_FOUND) message(FATAL_ERROR "netcdf was set to be sourced externally, but it was not found!") endif() - + # Import the system netcdf as a library import_library(netcdf ${NetCDF_LIBRARIES_C} ${NetCDF_INCLUDES}) - + elseif(netcdf_INTERNAL) if(${COMPILER} STREQUAL CRAY) message(FATAL_ERROR "Bundled NetCDF cannot be used with cray compilers. Please reconfigure with -DFORCE_EXTERNAL_LIBS=netcdf. \ On cray systems you can usually load the system NetCDF with 'module load cray-netcdf' or 'module load netcdf'.") endif() - + list(APPEND 3RDPARTY_SUBDIRS netcdf-4.6.1) endif() @@ -795,14 +987,14 @@ if(netcdf-fortran_EXTERNAL) if(netcdf_INTERNAL) message(FATAL_ERROR "Cannot use internal netcdf with external netcdf-fortran!") endif() - + # Import the system netcdf as a library import_library(netcdff ${NetCDF_LIBRARIES_F90} ${NetCDF_INCLUDES_F90}) set_property(TARGET netcdff PROPERTY INTERFACE_LINK_LIBRARIES netcdf) - + # This is really for symmetry with the other MOD_DIRs more than anything. set(NETCDF_FORTRAN_MOD_DIR ${NetCDF_INCLUDES_F90}) - + elseif(netcdf-fortran_INTERNAL) #TODO on Cray systems a static netcdf may be required @@ -814,6 +1006,27 @@ elseif(netcdf-fortran_INTERNAL) list(APPEND 3RDPARTY_SUBDIRS netcdf-fortran-4.4.4) endif() +#------------------------------------------------------------------------------ +# Protobuf +#------------------------------------------------------------------------------ + +if(protobuf_EXTERNAL) + + if(NOT Protobuf_FOUND) + message(FATAL_ERROR "protobuf was set to be sourced externally, but it was not found!") + endif() + + # Import the system protobuf as a library + import_library(protobuf ${Protobuf_LIBRARIES} ${Protobuf_INCLUDES}) + +elseif(protobuf_INTERNAL) + + #if(${COMPILER} STREQUAL CRAY) + # message(FATAL_ERROR "Bundled protobuf cannot be used with cray compilers. Please reconfigure with -DFORCE_EXTERNAL_LIBS=protobuf.") + #endif() + + list(APPEND 3RDPARTY_SUBDIRS protobuf-3.14.0/cmake) +endif() #------------------------------------------------------------------------------ # XBlas @@ -823,11 +1036,11 @@ if(xblas_EXTERNAL) # rename target import_libraries(xblas LIBRARIES xblas::xblas) - + elseif(xblas_INTERNAL) - + list(APPEND 3RDPARTY_SUBDIRS xblas) - + endif() #------------------------------------------------------------------------------ @@ -854,7 +1067,7 @@ if(arpack_EXTERNAL) if(NOT EXISTS "${ARPACK_LIBRARY}") message(FATAL_ERROR "arpack was set to be sourced externally, but it was not found!") endif() - + import_library(arpack ${ARPACK_LIBRARY}) if(NOT ARPACK_HAS_ARSECOND) @@ -864,7 +1077,7 @@ if(arpack_EXTERNAL) elseif(arpack_INTERNAL) list(APPEND 3RDPARTY_SUBDIRS arpack) endif() - + # -------------------------------------------------------------------- # Parallel NetCDF # -------------------------------------------------------------------- @@ -875,10 +1088,10 @@ elseif(pnetcdf_EXTERNAL) if(NOT PnetCDF_FOUND) message(FATAL_ERROR "You requested to use an external pnetcdf, but no installation was found.") endif() - + # rename target import_libraries(pnetcdf LIBRARIES pnetcdf::pnetcdf) - + endif() #------------------------------------------------------------------------------ @@ -913,13 +1126,13 @@ endif() # PLUMED #------------------------------------------------------------------------------ if(plumed_EXTERNAL) - set(PLUMED_RUNTIME_LINK FALSE) + set(PLUMED_RUNTIME_LINK FALSE) else() if(HAVE_LIBDL AND NEED_plumed) message(STATUS "Cannot find PLUMED. You will still be able to load it at runtime. If you want to link it at build time, set PLUMED_ROOT to where you installed it.") - + set(PLUMED_RUNTIME_LINK TRUE) - else() + else() set(PLUMED_RUNTIME_LINK FALSE) endif() endif() @@ -941,14 +1154,14 @@ endif() #------------------------------------------------------------------------------ # mpi4py -#------------------------------------------------------------------------------ +#------------------------------------------------------------------------------ if(mpi4py_EXTERNAL) if(NOT MPI4PY_FOUND) message(FATAL_ERROR "mpi4py was set to be sourced externally, but the mpi4py package was not found.") endif() elseif(mpi4py_INTERNAL) - list(APPEND 3RDPARTY_SUBDIRS mpi4py-3.0.3) + list(APPEND 3RDPARTY_SUBDIRS mpi4py-3.1.4) endif() #------------------------------------------------------------------------------ @@ -960,7 +1173,7 @@ if(perlmol_EXTERNAL) message(FATAL_ERROR "The Chemistry::Mol perl package was set to be sourced externally, but it was not found.") endif() elseif(perlmol_INTERNAL) - + if(NOT HAVE_PERL_MAKE) message(FATAL_ERROR "A perl-compatible make program is required to build Chemistry::Mol") endif() @@ -987,7 +1200,7 @@ if(boost_EXTERNAL) import_libraries(boost_${BOOST_LIB} LIBRARIES ${Boost_${BOOST_LIB_UCASE}_LIBRARY} INCLUDES ${Boost_INCLUDE_DIRS}) endforeach() - + # header interface library add_library(boost_headers INTERFACE) set_property(TARGET boost_headers PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIRS}) @@ -1008,24 +1221,57 @@ endif() #------------------------------------------------------------------------------ # NCCL -#------------------------------------------------------------------------------ +#------------------------------------------------------------------------------ if(nccl_EXTERNAL) using_library_targets(nccl) endif() #------------------------------------------------------------------------------ -# pmemd -#------------------------------------------------------------------------------ +# mbx +#------------------------------------------------------------------------------ if(mbx_EXTERNAL) using_library_targets(MBX::mbx) endif() +# -------------------------------------------------------------------- +# tng_io +# -------------------------------------------------------------------- + +if(tng_io_INTERNAL) + list(APPEND 3RDPARTY_SUBDIRS cpptraj/src/tng) +elseif(tng_io_EXTERNAL) + if(NOT tng_io_FOUND) + message(FATAL_ERROR "You requested to use an external libtng_io, but no installation was found.") + endif() + + # rename target + import_libraries(tng_io LIBRARIES tng_io::tng_io) +endif() + +#------------------------------------------------------------------------------ +# libtorch #------------------------------------------------------------------------------ -# mirp + +if(libtorch_INTERNAL) + list(APPEND 3RDPARTY_SUBDIRS libtorch) +elseif(libtorch_EXTERNAL) + if(NOT Torch_FOUND) + message(FATAL_ERROR "You requested to use an external libtorch, but no installation was found.") + endif() +endif() + +#------------------------------------------------------------------------------ +# nlopt #------------------------------------------------------------------------------ -if(mirp_EXTERNAL) - using_library_targets(mirp::mirp) -endif() \ No newline at end of file +if(nlopt_INTERNAL) + list(APPEND 3RDPARTY_SUBDIRS nlopt) +elseif(nlopt_EXTERNAL) + if(NOT nlopt_FOUND) + message(FATAL_ERROR "You requested to use an external nlopt, but no installation was found.") + endif() + + using_library_targets(nlopt LIBRARIES nlopt::nlopt) +endif() diff --git a/cmake/AmberBuildSystem2ndInit.cmake b/cmake/AmberBuildSystem2ndInit.cmake index 230c6a67c..8223c17c6 100644 --- a/cmake/AmberBuildSystem2ndInit.cmake +++ b/cmake/AmberBuildSystem2ndInit.cmake @@ -1,41 +1,41 @@ -# This script handles the parts of the Amber CMake init that must happen AFTER the enable_language() command, -# because files included by this use compile tests - -# standard library and should-be-in-the-standard-library includes -# -------------------------------------------------------------------- - -include(TargetArch) -include(ExternalProject) -include(CheckFunctionExists) -include(CheckFortranFunctionExists) -include(CheckIncludeFile) -include(CheckIncludeFileCXX) -include(CheckCSourceRuns) -include(CheckCCompilerFlag) -include(CheckCXXCompilerFlag) -include(CheckLinkerFlag) -include(CheckFortranSourceRuns) -include(CheckSymbolExists) -include(CheckConstantExists) -include(CheckLibraryExists) -include(CheckPythonPackage) -include(CheckTypeSize) -include(CMakePushCheckState) -include(TryLinkLibrary) - -# Amber include files -# -------------------------------------------------------------------- - -include(CheckBoostWorks) -include(VerifyCompilerConfig) -include(InstallWrapped) -include(LibraryTracking) -include(DownloadHttps) -include(Replace) -include(BuildReport) -include(ConfigModuleDirs) -include(ApplyOptimizationDeclarations) -include(CompilationOptions) -include(RPATHConfig) -include(CopyTarget) -include(LibraryUtils) +# This script handles the parts of the Amber CMake init that must happen AFTER the enable_language() command, +# because files included by this use compile tests + +# standard library and should-be-in-the-standard-library includes +# -------------------------------------------------------------------- + +include(TargetArch) +include(ExternalProject) +include(CheckFunctionExists) +include(CheckFortranFunctionExists) +include(CheckIncludeFile) +include(CheckIncludeFileCXX) +include(CheckCSourceRuns) +include(CheckCCompilerFlag) +include(CheckCXXCompilerFlag) +include(CheckLinkerFlag) +include(CheckFortranSourceRuns) +include(CheckSymbolExists) +include(CheckConstantExists) +include(CheckLibraryExists) +include(CheckPythonPackage) +include(CheckTypeSize) +include(CMakePushCheckState) +include(TryLinkLibrary) + +# Amber include files +# -------------------------------------------------------------------- + +include(CheckBoostWorks) +include(VerifyCompilerConfig) +include(InstallWrapped) +include(LibraryTracking) +include(DownloadHttps) +include(Replace) +include(BuildReport) +include(ConfigModuleDirs) +include(ApplyOptimizationDeclarations) +include(CompilationOptions) +include(RPATHConfig) +include(CopyTarget) +include(LibraryUtils) diff --git a/cmake/AmberBuildSystemInit.cmake b/cmake/AmberBuildSystemInit.cmake index c66cc4a52..568bfb8d3 100644 --- a/cmake/AmberBuildSystemInit.cmake +++ b/cmake/AmberBuildSystemInit.cmake @@ -1,73 +1,73 @@ -# This file contains code which must run to start up the build system, and includes files that are common to Amber and every submodule. -# This file must run AFTER a project() command without any languages, but BEFORE the enable_language() command - - -if(NOT DEFINED FIRST_RUN) - - # create a cache variable which is shadowed by a local variable - set(FIRST_RUN FALSE CACHE INTERNAL "Variable to track if it is currently the first time the build system is run" FORCE) - set(FIRST_RUN TRUE) - -endif() - - -# print header -# -------------------------------------------------------------------- -message(STATUS "**************************************************************************") -message(STATUS "Starting configuration of ${PROJECT_NAME} version ${${PROJECT_NAME}_VERSION}...") - -# print CMake version at the start so we can use it to diagnose issues even if the configure fails -message(STATUS "CMake Version: ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}") -message(STATUS "For how to use this build system, please read this wiki:") -message(STATUS " http://ambermd.org/pmwiki/pmwiki.php/Main/CMake") -message(STATUS "For a list of important CMake variables, check here:") -message(STATUS " http://ambermd.org/pmwiki/pmwiki.php/Main/CMake-Common-Options") -message(STATUS "**************************************************************************") - -# fix search path so that libraries from the install tree are not used -# -------------------------------------------------------------------- -list(REMOVE_ITEM CMAKE_SYSTEM_PREFIX_PATH "${CMAKE_INSTALL_PREFIX}") - -# eliminate extraneous install messages -# -------------------------------------------------------------------- -set(CMAKE_INSTALL_MESSAGE LAZY) - -# configure module path -# -------------------------------------------------------------------- - -list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR} - "${CMAKE_CURRENT_LIST_DIR}/jedbrown" - "${CMAKE_CURRENT_LIST_DIR}/hanjianwei" - "${CMAKE_CURRENT_LIST_DIR}/rpavlik" - "${CMAKE_CURRENT_LIST_DIR}/patched-cmake-modules") - -# prevent obliteration of the old build system's makefiles -# -------------------------------------------------------------------- - -if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") - message(FATAL_ERROR "You are building in the source directory. ${PROJECT_NAME} does not support this, since it would obliterate the Makefile build system.") -endif() - -# includes -# -------------------------------------------------------------------- - -#Basic utilities. These files CANNOT use any sort of compile checks or system introspection because no languages are enabled yet -include(CMakeParseArguments) -include(Policies NO_POLICY_SCOPE) -include(Utils) -include(Shorthand) -include(ColorMessage) - -# get install directories -include(InstallDirs) - -#run manual compiler setter, if it is enabled -include(AmberCompilerConfig) - -#control default build type. -#--------------------------------------------------------------------------------------------------------------------------------------------------------------------- - -set(CMAKE_CONFIGURATION_TYPES "DEBUG;RELEASE" CACHE STRING "Allowed build types for Amber. This only controls debugging flags, set the OPTIMIZE variable to control compiler optimizations." FORCE) -if("${CMAKE_BUILD_TYPE}" STREQUAL "") - set(CMAKE_BUILD_TYPE RELEASE CACHE STRING "Type of build. Controls debugging information and optimizations." FORCE) -endif() +# This file contains code which must run to start up the build system, and includes files that are common to Amber and every submodule. +# This file must run AFTER a project() command without any languages, but BEFORE the enable_language() command + + +if(NOT DEFINED FIRST_RUN) + + # create a cache variable which is shadowed by a local variable + set(FIRST_RUN FALSE CACHE INTERNAL "Variable to track if it is currently the first time the build system is run" FORCE) + set(FIRST_RUN TRUE) + +endif() + + +# print header +# -------------------------------------------------------------------- +message(STATUS "**************************************************************************") +message(STATUS "Starting configuration of ${PROJECT_NAME} version ${${PROJECT_NAME}_VERSION}...") + +# print CMake version at the start so we can use it to diagnose issues even if the configure fails +message(STATUS "CMake Version: ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}") +message(STATUS "For how to use this build system, please read this wiki:") +message(STATUS " http://ambermd.org/pmwiki/pmwiki.php/Main/CMake") +message(STATUS "For a list of important CMake variables, check here:") +message(STATUS " http://ambermd.org/pmwiki/pmwiki.php/Main/CMake-Common-Options") +message(STATUS "**************************************************************************") + +# fix search path so that libraries from the install tree are not used +# -------------------------------------------------------------------- +list(REMOVE_ITEM CMAKE_SYSTEM_PREFIX_PATH "${CMAKE_INSTALL_PREFIX}") + +# eliminate extraneous install messages +# -------------------------------------------------------------------- +set(CMAKE_INSTALL_MESSAGE LAZY) + +# configure module path +# -------------------------------------------------------------------- + +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR} + "${CMAKE_CURRENT_LIST_DIR}/jedbrown" + "${CMAKE_CURRENT_LIST_DIR}/hanjianwei" + "${CMAKE_CURRENT_LIST_DIR}/rpavlik" + "${CMAKE_CURRENT_LIST_DIR}/patched-cmake-modules") + +# prevent obliteration of the old build system's makefiles +# -------------------------------------------------------------------- + +if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") + message(FATAL_ERROR "You are building in the source directory. ${PROJECT_NAME} does not support this, since it would obliterate the Makefile build system.") +endif() + +# includes +# -------------------------------------------------------------------- + +#Basic utilities. These files CANNOT use any sort of compile checks or system introspection because no languages are enabled yet +include(CMakeParseArguments) +include(Policies NO_POLICY_SCOPE) +include(Utils) +include(Shorthand) +include(ColorMessage) + +# get install directories +include(InstallDirs) + +#run manual compiler setter, if it is enabled +include(AmberCompilerConfig) + +#control default build type. +#--------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +set(CMAKE_CONFIGURATION_TYPES "DEBUG;RELEASE" CACHE STRING "Allowed build types for Amber. This only controls debugging flags, set the OPTIMIZE variable to control compiler optimizations." FORCE) +if("${CMAKE_BUILD_TYPE}" STREQUAL "") + set(CMAKE_BUILD_TYPE RELEASE CACHE STRING "Type of build. Controls debugging information and optimizations." FORCE) +endif() diff --git a/cmake/AmberCompilerConfig.cmake b/cmake/AmberCompilerConfig.cmake index 3c73c1e3c..1ff2614b0 100644 --- a/cmake/AmberCompilerConfig.cmake +++ b/cmake/AmberCompilerConfig.cmake @@ -128,6 +128,7 @@ if(FIRST_RUN) set_compiler(Fortran gfortran) endif() + elseif(${COMPILER} STREQUAL CLANG) set_compiler(C clang) set_compiler(CXX "clang++") diff --git a/cmake/AmberUpdater.cmake b/cmake/AmberUpdater.cmake index eee1eddcb..9c6569312 100644 --- a/cmake/AmberUpdater.cmake +++ b/cmake/AmberUpdater.cmake @@ -1,58 +1,58 @@ -# CMake script that calls the Amber update script. BAsed on the user's choice, -# it either checks for updates or installs them. -# Must be included after PythonConfig.cmake - -# The updater requires python. Python builds don't have to be enabled, we just need to have the interpereter -if(NOT HAS_PYTHON) - return() -endif() - -# we can skip updates if this is a developer version -option(CHECK_UPDATES "Use the updater script to check for updates to Amber and AmberTools. This can take a few seconds." ${AMBER_RELEASE}) -option(APPLY_UPDATES "On the next run of CMake, apply all available updates for Amber and AmberTools. This option resets to false after it is used." FALSE) - -if(CHECK_UPDATES OR APPLY_UPDATES) - if(APPLY_UPDATES) - set(UPDATER_ARG --check-updates) - colormsg(HIBLUE "Checking for updates...") - else() - set(UPDATER_ARG --update) - colormsg(HIBLUE "Running updater...") - endif() - - # -------------------------------------------------------------------- - # Run script - - execute_process(COMMAND ${CMAKE_COMMAND} -E env AMBERHOME=${CMAKE_SOURCE_DIR} ${PYTHON_EXECUTABLE} update_amber ${UPDATER_ARG} - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - RESULT_VARIABLE UPDATE_COMMAND_RESULT - OUTPUT_VARIABLE UPDATE_COMMAND_OUTPUT) - - # -------------------------------------------------------------------- - # print the output of the updater with a prefix so the people know it's not coming from the build script - - string(REPLACE "\n" ";" UPDATE_COMMAND_OUTPUT "${UPDATE_COMMAND_OUTPUT}") - - foreach(LINE ${UPDATE_COMMAND_OUTPUT}) - colormsg(">>> ${LINE}") - endforeach() - - # -------------------------------------------------------------------- - # Print conclusion message - - if(APPLY_UPDATES) - if(${UPDATE_COMMAND_RESULT} EQUAL 0) - set(APPLY_UPDATES FALSE CACHE BOOL "" FORCE) - colormsg(HIBLUE "Updating succeeded! APPLY_UPDATES has been disabled.") - else() - colormsg(HIBLUE "Updating failed! If you need to supply additional arguments to the updater you can call the ${CMAKE_SOURCE_DIR}/update_amber script directly.") - endif() - else() - if(${UPDATE_COMMAND_RESULT} EQUAL 0) - colormsg(HIBLUE "Updater done. If you want to install updates, then set the APPLY_UPDATES variable to true.") - else() - colormsg(HIBLUE "Failed to check for updates! If you need to supply additional arguments to the updater you can call the ${CMAKE_SOURCE_DIR}/update_amber script directly.") - endif() - endif() -endif() +# CMake script that calls the Amber update script. BAsed on the user's choice, +# it either checks for updates or installs them. +# Must be included after PythonConfig.cmake + +# The updater requires python. Python builds don't have to be enabled, we just need to have the interpereter +if(NOT HAS_PYTHON) + return() +endif() + +# we can skip updates if this is a developer version +option(CHECK_UPDATES "Use the updater script to check for updates to Amber and AmberTools. This can take a few seconds." ${AMBER_RELEASE}) +option(APPLY_UPDATES "On the next run of CMake, apply all available updates for Amber and AmberTools. This option resets to false after it is used." FALSE) + +if(CHECK_UPDATES OR APPLY_UPDATES) + if(APPLY_UPDATES) + set(UPDATER_ARG --check-updates) + colormsg(HIBLUE "Checking for updates...") + else() + set(UPDATER_ARG --update) + colormsg(HIBLUE "Running updater...") + endif() + + # -------------------------------------------------------------------- + # Run script + + execute_process(COMMAND ${CMAKE_COMMAND} -E env AMBERHOME=${CMAKE_SOURCE_DIR} ${PYTHON_EXECUTABLE} update_amber ${UPDATER_ARG} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + RESULT_VARIABLE UPDATE_COMMAND_RESULT + OUTPUT_VARIABLE UPDATE_COMMAND_OUTPUT) + + # -------------------------------------------------------------------- + # print the output of the updater with a prefix so the people know it's not coming from the build script + + string(REPLACE "\n" ";" UPDATE_COMMAND_OUTPUT "${UPDATE_COMMAND_OUTPUT}") + + foreach(LINE ${UPDATE_COMMAND_OUTPUT}) + colormsg(">>> ${LINE}") + endforeach() + + # -------------------------------------------------------------------- + # Print conclusion message + + if(APPLY_UPDATES) + if(${UPDATE_COMMAND_RESULT} EQUAL 0) + set(APPLY_UPDATES FALSE CACHE BOOL "" FORCE) + colormsg(HIBLUE "Updating succeeded! APPLY_UPDATES has been disabled.") + else() + colormsg(HIBLUE "Updating failed! If you need to supply additional arguments to the updater you can call the ${CMAKE_SOURCE_DIR}/update_amber script directly.") + endif() + else() + if(${UPDATE_COMMAND_RESULT} EQUAL 0) + colormsg(HIBLUE "Updater done. If you want to install updates, then set the APPLY_UPDATES variable to true.") + else() + colormsg(HIBLUE "Failed to check for updates! If you need to supply additional arguments to the updater you can call the ${CMAKE_SOURCE_DIR}/update_amber script directly.") + endif() + endif() +endif() \ No newline at end of file diff --git a/cmake/BuildReport.cmake b/cmake/BuildReport.cmake index 3ab9a1996..5d08c928f 100644 --- a/cmake/BuildReport.cmake +++ b/cmake/BuildReport.cmake @@ -1,177 +1,171 @@ -# Prints the build report - -function(print_build_report) - if(COLOR_CMAKE_MESSAGES) - message("If you can't see the following build report, then you need to turn off COLOR_CMAKE_MESSAGES") - endif() - - colormsg(HIBLUE "**************************************************************************") - colormsg(" " _WHITE_ "Build Report") - colormsg(" " _HIMAG_ "Compiler Flags:") - colormsg(HIMAG "C" HIWHITE "No-Opt: " WHITE "${CMAKE_C_FLAGS}" HIBLUE "${NO_OPT_CFLAGS_SPC}") - colormsg(HIMAG "C" HIWHITE "Optimized: " WHITE "${CMAKE_C_FLAGS}" HIBLUE "${OPT_CFLAGS_SPC}") - colormsg("") - colormsg(GREEN "CXX" HIWHITE "No-Opt: " WHITE "${CMAKE_CXX_FLAGS}" HIBLUE "${NO_OPT_CXXFLAGS_SPC}") - colormsg(GREEN "CXX" HIWHITE "Optimized: " WHITE "${CMAKE_CXX_FLAGS}" HIBLUE "${OPT_CXXFLAGS_SPC}") - colormsg("") - colormsg(HIRED "Fortran" HIWHITE "No-Opt: " WHITE "${CMAKE_Fortran_FLAGS}" HIBLUE "${NO_OPT_FFLAGS_SPC}") - colormsg(HIRED "Fortran" HIWHITE "Optimized:" WHITE "${CMAKE_Fortran_FLAGS}" HIBLUE "${OPT_FFLAGS_SPC}") - - colormsg("") - colormsg(" " _HIMAG_ "3rd Party Libraries") - colormsg("---building bundled: -----------------------------------------------------") - - foreach(TOOL ${NEEDED_3RDPARTY_TOOLS}) - - if(${${TOOL}_INTERNAL}) - list(FIND 3RDPARTY_TOOLS ${TOOL} TOOL_INDEX) - list(GET 3RDPARTY_TOOL_USES ${TOOL_INDEX} TOOL_USE) - - colormsg(GREEN "${TOOL}" HIWHITE "- ${TOOL_USE}") - endif() - endforeach() - - colormsg("---using installed: ------------------------------------------------------") - - foreach(TOOL ${NEEDED_3RDPARTY_TOOLS}) - if(${${TOOL}_EXTERNAL}) - list(FIND 3RDPARTY_TOOLS ${TOOL} TOOL_INDEX) - list(GET 3RDPARTY_TOOL_USES ${TOOL_INDEX} TOOL_USE) - - colormsg(YELLOW "${TOOL}" HIWHITE "- ${TOOL_USE}") - endif() - endforeach() - - colormsg("---disabled: ------------------------------------------------") - - foreach(TOOL ${NEEDED_3RDPARTY_TOOLS}) - if(${${TOOL}_DISABLED}) - list(FIND 3RDPARTY_TOOLS ${TOOL} TOOL_INDEX) - list(GET 3RDPARTY_TOOL_USES ${TOOL_INDEX} TOOL_USE) - - colormsg(HIRED "${TOOL}" HIWHITE "- ${TOOL_USE}") - endif() - endforeach() - - message("") - colormsg(" " _HIMAG_ "Features:") - # we only want to print these if the corresponding build files have been included - if(DEFINED MPI) - color_print_bool("MPI: " "${MPI}") - endif() - - if(DEFINED OPENMP) - color_print_bool("OpenMP: " "${OPENMP}") - endif() - - if(DEFINED CUDA AND NOT DEFINED HIP) - color_print_bool("CUDA: " "${CUDA}") - endif() - - if(DEFINED HIP) - color_print_bool("HIP: " "${HIP}") - endif() - - if(DEFINED NCCL) - color_print_bool("NCCL: " "${NCCL}") - endif() - - color_print_bool("Build Shared Libraries: " "${SHARED}") - - if(DEFINED BUILD_GUI) - color_print_bool("Build GUI Interfaces: " "${BUILD_GUI}") - endif() - - if(DEFINED BUILD_PYTHON) - color_print_bool("Build Python Programs: " "${BUILD_PYTHON}") - if(DOWNLOAD_MINICONDA) - colormsg(" -Python Interpreter: " HIBLUE "Internal Miniconda" YELLOW "(version ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})") - else() - colormsg(" -Python Interpreter: " HIBLUE "${PYTHON_EXECUTABLE}" YELLOW "(version ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})") - endif() - endif() - - if(DEFINED BUILD_PERL) - color_print_bool("Build Perl Programs: " "${BUILD_PERL}") - endif() - - colormsg("Build configuration: " HIBLUE "${CMAKE_BUILD_TYPE}") - colormsg("Target Processor: " YELLOW "${TARGET_ARCH}") - if(BUILD_DOC) - colormsg("Build Documentation: " GREEN "With all, format: ${DOC_FORMAT}") - elseif(LYX) - colormsg("Build Documentation: " YELLOW "As 'make doc' target, format: ${DOC_FORMAT}") - else() - colormsg("Build Documentation: " HIRED "OFF") - endif() - if(DEFINED SANDER_VARIANTS_STRING) - colormsg("Sander Variants: " HIBLUE "${SANDER_VARIANTS_STRING}") - endif() - - if(DEFINED MIC_KL AND NOT AMBERTOOLS_ONLY) - color_print_bool("Knight's Landing Opts: " "${MIC_KL}") - endif() - - if(DEFINED USE_HOST_TOOLS AND USE_HOST_TOOLS) - colormsg("Using host tools from: " HIBLUE "${HOST_TOOLS_DIR}") - endif() - colormsg("Install location: " HIBLUE "${CMAKE_INSTALL_PREFIX}${CMAKE_INSTALL_POSTFIX}") - if(DEFINED INSTALL_TESTS) - color_print_bool("Installation of Tests: " "${INSTALL_TESTS}") - endif() - message("") - - #------------------------------------------------------------------------------------------ - colormsg(" " _HIMAG_ "Compilers:") - - # print compiler messages for only the languages that are enabled - - if(NOT "${CMAKE_C_COMPILER_ID}" STREQUAL "") - colormsg(CYAN " C:" YELLOW "${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION}" HIRED "(${CMAKE_C_COMPILER})") - endif() - - if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "") - colormsg(CYAN " CXX:" YELLOW "${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}" HIRED "(${CMAKE_CXX_COMPILER})") - endif() - - if(NOT "${CMAKE_Fortran_COMPILER_ID}" STREQUAL "") - colormsg(CYAN " Fortran:" YELLOW "${CMAKE_Fortran_COMPILER_ID} ${CMAKE_Fortran_COMPILER_VERSION}" HIRED "(${CMAKE_Fortran_COMPILER})") - endif() - - # this part is for Amber only - if(INSIDE_AMBER) - message("") - colormsg(" " _HIMAG_ "Building Tools:") - - # NOTE: we can't sort this until after the subdirs have been added because they need to get added in dependency order - string(TOLOWER "${AMBER_TOOLS}" AMBER_TOOLS) # list(SORT) sorts capital letters first, so we need to make everything lowercase - list(SORT AMBER_TOOLS) - list_to_space_separated(BUILDING_TOOLS ${AMBER_TOOLS}) - - colormsg("${BUILDING_TOOLS}") - message("") - colormsg(" " _HIMAG_ "NOT Building Tools:") - foreach(TOOL ${REMOVED_TOOLS}) - - # get the corresponding reason - list(FIND REMOVED_TOOLS ${TOOL} TOOL_INDEX) - list(GET REMOVED_TOOL_REASONS ${TOOL_INDEX} REMOVAL_REASON) - - colormsg(HIRED "${TOOL} - ${REMOVAL_REASON}") - endforeach() - endif() - colormsg(HIBLUE "**************************************************************************") - - if(DEFINED PRINT_PACKAGING_REPORT AND PRINT_PACKAGING_REPORT) - print_packaging_report() - endif() - - - if(ENABLEF AND (DEFINED CUDA OR DEFINED HIP)) - message("") - colormsg(HIRED "You have enabled F function support for GPUs. The current version of the F function ") - colormsg(HIRED "code takes very long to compile (hours) and requires a large amount of RAM. ") - colormsg(HIRED "Work is planned to optimize this in future releases. ") - message("") - endif() -endfunction(print_build_report) +# Prints the build report + +function(print_build_report) + if(COLOR_CMAKE_MESSAGES) + message("If you can't see the following build report, then you need to turn off COLOR_CMAKE_MESSAGES") + endif() + + colormsg(HIBLUE "**************************************************************************") + colormsg(" " _WHITE_ "Build Report") + colormsg(" " _HIMAG_ "Compiler Flags:") + colormsg(HIMAG "C" HIWHITE "No-Opt: " WHITE "${CMAKE_C_FLAGS}" HIBLUE "${NO_OPT_CFLAGS_SPC}") + colormsg(HIMAG "C" HIWHITE "Optimized: " WHITE "${CMAKE_C_FLAGS}" HIBLUE "${OPT_CFLAGS_SPC}") + colormsg("") + colormsg(GREEN "CXX" HIWHITE "No-Opt: " WHITE "${CMAKE_CXX_FLAGS}" HIBLUE "${NO_OPT_CXXFLAGS_SPC}") + colormsg(GREEN "CXX" HIWHITE "Optimized: " WHITE "${CMAKE_CXX_FLAGS}" HIBLUE "${OPT_CXXFLAGS_SPC}") + colormsg("") + colormsg(HIRED "Fortran" HIWHITE "No-Opt: " WHITE "${CMAKE_Fortran_FLAGS}" HIBLUE "${NO_OPT_FFLAGS_SPC}") + colormsg(HIRED "Fortran" HIWHITE "Optimized:" WHITE "${CMAKE_Fortran_FLAGS}" HIBLUE "${OPT_FFLAGS_SPC}") + + colormsg("") + colormsg(" " _HIMAG_ "3rd Party Libraries") + colormsg("---building bundled: -----------------------------------------------------") + + foreach(TOOL ${NEEDED_3RDPARTY_TOOLS}) + + if(${${TOOL}_INTERNAL}) + list(FIND 3RDPARTY_TOOLS ${TOOL} TOOL_INDEX) + list(GET 3RDPARTY_TOOL_USES ${TOOL_INDEX} TOOL_USE) + + colormsg(GREEN "${TOOL}" HIWHITE "- ${TOOL_USE}") + endif() + endforeach() + + colormsg("---using installed: ------------------------------------------------------") + + foreach(TOOL ${NEEDED_3RDPARTY_TOOLS}) + if(${${TOOL}_EXTERNAL}) + list(FIND 3RDPARTY_TOOLS ${TOOL} TOOL_INDEX) + list(GET 3RDPARTY_TOOL_USES ${TOOL_INDEX} TOOL_USE) + + colormsg(YELLOW "${TOOL}" HIWHITE "- ${TOOL_USE}") + endif() + endforeach() + + colormsg("---disabled: ------------------------------------------------") + + foreach(TOOL ${NEEDED_3RDPARTY_TOOLS}) + if(${${TOOL}_DISABLED}) + list(FIND 3RDPARTY_TOOLS ${TOOL} TOOL_INDEX) + list(GET 3RDPARTY_TOOL_USES ${TOOL_INDEX} TOOL_USE) + + colormsg(HIRED "${TOOL}" HIWHITE "- ${TOOL_USE}") + endif() + endforeach() + + message("") + colormsg(" " _HIMAG_ "Features:") + # we only want to print these if the corresponding build files have been included + if(DEFINED MPI) + color_print_bool("MPI: " "${MPI}") + endif() + + if(DEFINED OPENMP) + color_print_bool("OpenMP: " "${OPENMP}") + endif() + + if(DEFINED CUDA) + color_print_bool("CUDA: " "${CUDA}") + endif() + + if(DEFINED NCCL) + color_print_bool("NCCL: " "${NCCL}") + endif() + + color_print_bool("Build Shared Libraries: " "${SHARED}") + + if(DEFINED BUILD_GUI) + color_print_bool("Build GUI Interfaces: " "${BUILD_GUI}") + endif() + + if(DEFINED BUILD_PYTHON) + color_print_bool("Build Python Programs: " "${BUILD_PYTHON}") + if(DOWNLOAD_MINICONDA) + colormsg(" -Python Interpreter: " HIBLUE "Internal Miniconda" YELLOW "(version ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})") + else() + colormsg(" -Python Interpreter: " HIBLUE "${PYTHON_EXECUTABLE}" YELLOW "(version ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})") + endif() + endif() + + if(DEFINED BUILD_PERL) + color_print_bool("Build Perl Programs: " "${BUILD_PERL}") + endif() + + colormsg("Build configuration: " HIBLUE "${CMAKE_BUILD_TYPE}") + colormsg("Target Processor: " YELLOW "${TARGET_ARCH}") + if(BUILD_DOC) + colormsg("Build Documentation: " GREEN "With all, format: ${DOC_FORMAT}") + elseif(LYX) + colormsg("Build Documentation: " YELLOW "As 'make doc' target, format: ${DOC_FORMAT}") + else() + colormsg("Build Documentation: " HIRED "OFF") + endif() + if(DEFINED SANDER_VARIANTS_STRING) + colormsg("Sander Variants: " HIBLUE "${SANDER_VARIANTS_STRING}") + endif() + + if(DEFINED MIC_KL AND NOT AMBERTOOLS_ONLY) + color_print_bool("Knight's Landing Opts: " "${MIC_KL}") + endif() + + if(DEFINED USE_HOST_TOOLS AND USE_HOST_TOOLS) + colormsg("Using host tools from: " HIBLUE "${HOST_TOOLS_DIR}") + endif() + colormsg("Install location: " HIBLUE "${CMAKE_INSTALL_PREFIX}${CMAKE_INSTALL_POSTFIX}") + color_print_bool("Installation of Tests: " "${INSTALL_TESTS}") + message("") + + #------------------------------------------------------------------------------------------ + colormsg(" " _HIMAG_ "Compilers:") + + # print compiler messages for only the languages that are enabled + + if(NOT "${CMAKE_C_COMPILER_ID}" STREQUAL "") + colormsg(CYAN " C:" YELLOW "${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION}" HIRED "(${CMAKE_C_COMPILER})") + endif() + + if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "") + colormsg(CYAN " CXX:" YELLOW "${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}" HIRED "(${CMAKE_CXX_COMPILER})") + endif() + + if(NOT "${CMAKE_Fortran_COMPILER_ID}" STREQUAL "") + colormsg(CYAN " Fortran:" YELLOW "${CMAKE_Fortran_COMPILER_ID} ${CMAKE_Fortran_COMPILER_VERSION}" HIRED "(${CMAKE_Fortran_COMPILER})") + endif() + + # this part is for Amber only + if(INSIDE_AMBER) + message("") + colormsg(" " _HIMAG_ "Building Tools:") + + # NOTE: we can't sort this until after the subdirs have been added because they need to get added in dependency order + string(TOLOWER "${AMBER_TOOLS}" AMBER_TOOLS) # list(SORT) sorts capital letters first, so we need to make everything lowercase + list(SORT AMBER_TOOLS) + list_to_space_separated(BUILDING_TOOLS ${AMBER_TOOLS}) + + colormsg("${BUILDING_TOOLS}") + message("") + colormsg(" " _HIMAG_ "NOT Building Tools:") + foreach(TOOL ${REMOVED_TOOLS}) + + # get the corresponding reason + list(FIND REMOVED_TOOLS ${TOOL} TOOL_INDEX) + list(GET REMOVED_TOOL_REASONS ${TOOL_INDEX} REMOVAL_REASON) + + colormsg(HIRED "${TOOL} - ${REMOVAL_REASON}") + endforeach() + endif() + colormsg(HIBLUE "**************************************************************************") + + if(DEFINED PRINT_PACKAGING_REPORT AND PRINT_PACKAGING_REPORT) + print_packaging_report() + endif() + + + if(ENABLEF AND (DEFINED CUDA OR DEFINED HIP)) + message("") + colormsg(HIRED "You have enabled F function support for GPUs. The current version of the F function ") + colormsg(HIRED "code takes very long to compile (hours) and requires a large amount of RAM. ") + colormsg(HIRED "Work is planned to optimize this in future releases. ") + message("") + endif() +endfunction(print_build_report) diff --git a/cmake/ColorMessage.cmake b/cmake/ColorMessage.cmake index 93654d2a6..fac0a7253 100644 --- a/cmake/ColorMessage.cmake +++ b/cmake/ColorMessage.cmake @@ -1,85 +1,85 @@ -# -# AMBER: Taken from the Boost source (where it had the below comment) -# A big shout out to the cmake gurus @ compiz -# -# colormsg("Colors:" -# WHITE "white" GRAY "gray" GREEN "green" -# RED "red" YELLOW "yellow" BLUE "blue" MAG "mag" CYAN "cyan" -# _WHITE_ "white" _GRAY_ "gray" _GREEN_ "green" -# _RED_ "red" _YELLOW_ "yellow" _BLUE_ "blue" _MAG_ "mag" _CYAN_ "cyan" -# _HIWHITE_ "white" _HIGRAY_ "gray" _HIGREEN_ "green" -# _HIRED_ "red" _HIYELLOW_ "yellow" _HIBLUE_ "blue" _HIMAG_ "mag" _HICYAN_ "cyan" -# HIWHITE "white" HIGRAY "gray" HIGREEN "green" -# HIRED "red" HIYELLOW "yellow" HIBLUE "blue" HIMAG "mag" HICYAN "cyan" -# "right?") - -# figure out if color messaging is supported -test(COLOR_MSG_SUPPORTED (NOT WIN32)) - -option(COLOR_CMAKE_MESSAGES "Colorize output from the configuration script. This comes out all wrong if you use the GUI, so make sure to set this to false if you do." ${COLOR_MSG_SUPPORTED}) - -# AMBER: we put this stuff out here. Yes, it pollutes the global namespace, but it also saves having to recalculate this each invocation -# (which is what the original function did) -string (ASCII 27 _escape) -set(WHITE "29") -set(GRAY "30") -set(RED "31") -set(GREEN "32") -set(YELLOW "33") -set(BLUE "34") -set(MAG "35") -set(CYAN "36") - -foreach (color WHITE GRAY RED GREEN YELLOW BLUE MAG CYAN) - set(HI${color} "1\;${${color}}") - set(LO${color} "2\;${${color}}") - set(_${color}_ "4\;${${color}}") - set(_HI${color}_ "1\;4\;${${color}}") - set(_LO${color}_ "2\;4\;${${color}}") -endforeach() - -function (colormsg) - - if(COLOR_CMAKE_MESSAGES) - set(str "") - set(coloron FALSE) - foreach(arg ${ARGV}) - if (DEFINED ${arg}) - if (CMAKE_COLOR_MAKEFILE) - set(str "${str}${_escape}[${${arg}}m") - set(coloron TRUE) - endif() - else() - set(str "${str}${arg}") - if (coloron) - set(str "${str}${_escape}[0m") - set(coloron FALSE) - endif() - set(str "${str} ") - endif() - endforeach() - message(STATUS ${str}) - else() - # just get the color words out of the arguments, then print the string - set(str "") - - foreach(arg ${ARGV}) - if (DEFINED ${arg}) - # do nothing - else() - set(str "${str}${arg} ") - endif() - endforeach() - message(STATUS ${str}) - endif() -endfunction() - -# Print a boolean variable with a colored "ON" or "OFF" indicator -# Mainly used by the build report -function(color_print_bool MESSAGE VALUE) - if("${VALUE}") - colormsg(${MESSAGE} GREEN ON) - else() - colormsg(${MESSAGE} HIRED OFF) - endif() -endfunction(color_print_bool) +# +# AMBER: Taken from the Boost source (where it had the below comment) +# A big shout out to the cmake gurus @ compiz +# +# colormsg("Colors:" +# WHITE "white" GRAY "gray" GREEN "green" +# RED "red" YELLOW "yellow" BLUE "blue" MAG "mag" CYAN "cyan" +# _WHITE_ "white" _GRAY_ "gray" _GREEN_ "green" +# _RED_ "red" _YELLOW_ "yellow" _BLUE_ "blue" _MAG_ "mag" _CYAN_ "cyan" +# _HIWHITE_ "white" _HIGRAY_ "gray" _HIGREEN_ "green" +# _HIRED_ "red" _HIYELLOW_ "yellow" _HIBLUE_ "blue" _HIMAG_ "mag" _HICYAN_ "cyan" +# HIWHITE "white" HIGRAY "gray" HIGREEN "green" +# HIRED "red" HIYELLOW "yellow" HIBLUE "blue" HIMAG "mag" HICYAN "cyan" +# "right?") + +# figure out if color messaging is supported +test(COLOR_MSG_SUPPORTED (NOT WIN32)) + +option(COLOR_CMAKE_MESSAGES "Colorize output from the configuration script. This comes out all wrong if you use the GUI, so make sure to set this to false if you do." ${COLOR_MSG_SUPPORTED}) + +# AMBER: we put this stuff out here. Yes, it pollutes the global namespace, but it also saves having to recalculate this each invocation +# (which is what the original function did) +string (ASCII 27 _escape) +set(WHITE "29") +set(GRAY "30") +set(RED "31") +set(GREEN "32") +set(YELLOW "33") +set(BLUE "34") +set(MAG "35") +set(CYAN "36") + +foreach (color WHITE GRAY RED GREEN YELLOW BLUE MAG CYAN) + set(HI${color} "1\;${${color}}") + set(LO${color} "2\;${${color}}") + set(_${color}_ "4\;${${color}}") + set(_HI${color}_ "1\;4\;${${color}}") + set(_LO${color}_ "2\;4\;${${color}}") +endforeach() + +function (colormsg) + + if(COLOR_CMAKE_MESSAGES) + set(str "") + set(coloron FALSE) + foreach(arg ${ARGV}) + if (DEFINED ${arg}) + if (CMAKE_COLOR_MAKEFILE) + set(str "${str}${_escape}[${${arg}}m") + set(coloron TRUE) + endif() + else() + set(str "${str}${arg}") + if (coloron) + set(str "${str}${_escape}[0m") + set(coloron FALSE) + endif() + set(str "${str} ") + endif() + endforeach() + message(STATUS ${str}) + else() + # just get the color words out of the arguments, then print the string + set(str "") + + foreach(arg ${ARGV}) + if (DEFINED ${arg}) + # do nothing + else() + set(str "${str}${arg} ") + endif() + endforeach() + message(STATUS ${str}) + endif() +endfunction() + +# Print a boolean variable with a colored "ON" or "OFF" indicator +# Mainly used by the build report +function(color_print_bool MESSAGE VALUE) + if("${VALUE}") + colormsg(${MESSAGE} GREEN ON) + else() + colormsg(${MESSAGE} HIRED OFF) + endif() +endfunction(color_print_bool) diff --git a/cmake/CompilationOptions.cmake b/cmake/CompilationOptions.cmake index 20ef5f01d..bb60c315b 100644 --- a/cmake/CompilationOptions.cmake +++ b/cmake/CompilationOptions.cmake @@ -1,136 +1,136 @@ -# This file can be included after at least one language is enabled, but before all of them are. -# It sets up all of the CMake options that affect compiler flags. - -# Set up options which affect compiler flags. -#------------------------------------------------------------------------------------------ - -#Dragonegg option -set(DRAGONEGG "" CACHE PATH "Path to the the Dragonegg gcc to LLVM bridge. Set to empty string to disable. If specified, it will be applied to any GCC compilers in use (gcc, g++, and gfortran).") - - # Check dragonegg -if(DRAGONEGG) - if(NOT EXISTS ${DRAGONEGG}) - message(FATAL_ERROR "Dragonegg enabled, but the Dragonegg path ${DRAGONEGG} does not point to a file.") - endif() -endif() - -#shared vs static option -option(STATIC "If true, build static libraries and freestanding (except for data files) executables. Otherwise, compile common code into shared libraries and link them to programs. \ -The runtime path is set properly now, so unless you move the installation AND don't source amber.sh you won't have to mess with LD_LIBRARY PATH" FALSE) - -if(STATIC) - set(SHARED FALSE) -else() - set(SHARED TRUE) -endif() - - -option(LARGE_FILE_SUPPORT "Build C code with large file support. Always on when building for a 64 bit target." TRUE) - -# FFT support -option(USE_FFT "Whether to use the Fastest Fourier Transform in the West library and build RISM and the PBSA FFT solver." TRUE) - -#set default library type appropriately -set(BUILD_SHARED_LIBS ${SHARED}) - -# NOTE: The correct way to handle optimization is to use generator expressions based on the current configuration. -# However, sometimes I need to use set_property(SOURCE PROPERTY COMPILE_FLAGS) to set compile flags for individual source files. -# This property didn't support generator expressions until CMake 3.8. Grrrrr. -# So, we use CMAKE__FLAGS_DEBUG for per-config debugging flags, but use a separate optimization switch. -option(OPTIMIZE "Whether to build code with compiler flags for optimization." TRUE) - -option(UNUSED_WARNINGS "Enable warnings about unused variables. Really clutters up the build output." FALSE) -option(UNINITIALIZED_WARNINGS "Enable warnings about uninitialized variables. Kind of clutters up the build output, but these need to be fixed." TRUE) - -option(DOUBLE_PRECISION "Build Amber's Fortran programs with double precision math." TRUE) - - -#let's try to enforce a reasonable standard here -set(CMAKE_C_STANDARD 99) -set(CMAKE_CXX_STANDARD 11) - -# I can't think of any better place to put this... - -#------------------------------------------------------------------------------ -# Now that we have our compiler, detect target architecture. -# This is kind of a hack, but it works. -# See TargetArch.cmake (from https://github.com/axr/solar-cmake) for details. -#------------------------------------------------------------------------------ -target_architecture(TARGET_ARCH) - -if("${TARGET_ARCH}" STREQUAL unknown OR "${TARGET_ARCH}" STREQUAL "") - message(FATAL_ERROR "Could not detect target architecture from compiler. Does the compiler work?") -endif() - - -#initialize SSE based on TARGET_ARCH -list_contains(SSE_SUPPORTED ${TARGET_ARCH} x86_64 ia64 i386) -set(SSE ${SSE_SUPPORTED} CACHE BOOL "Optimize for the SSE family of vectorizations.") -set(SSE_TYPES "" CACHE STRING "CPU types for which auto-dispatch code will be produced (Intel compilers version 11 and higher). Known valid - options are SSE2, SSE3, SSSE3, SSE4.1 and SSE4.2. Multiple options (comma separated) are permitted.") - -# Figure out no-undefined flag -if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) - set(NO_UNDEFINED_FLAG "-Wl,-undefined,error") -elseif((${CMAKE_SYSTEM_NAME} STREQUAL Linux) OR MINGW) - set(NO_UNDEFINED_FLAG "-Wl,--no-undefined") -else() - set(NO_UNDEFINED_FLAG "") -endif() - - -#------------------------------------------------------------------------------- -# Set up a couple of convenience variables to make checking the target OS less verbose -#------------------------------------------------------------------------------- -test(TARGET_OSX "${CMAKE_SYSTEM_NAME}" STREQUAL Darwin) -test(TARGET_WINDOWS "${CMAKE_SYSTEM_NAME}" STREQUAL Windows) -test(TARGET_LINUX "${CMAKE_SYSTEM_NAME}" STREQUAL Linux OR "${CMAKE_SYSTEM_NAME}" STREQUAL Android) # Android is close enough to Linux for our purposes - -test(HOST_OSX "${CMAKE_HOST_SYSTEM_NAME}" STREQUAL Darwin) -test(HOST_WINDOWS "${CMAKE_HOST_SYSTEM_NAME}" STREQUAL Windows) -test(HOST_LINUX "${CMAKE_HOST_SYSTEM_NAME}" STREQUAL Linux OR "${CMAKE_HOST_SYSTEM_NAME}" STREQUAL Android) - -# -------------------------------------------------------------------- -# Determine if we are mixing different vendors' compilers -# -------------------------------------------------------------------- -set(MIXING_COMPILERS TRUE) -if(("${CMAKE_C_COMPILER_ID}" STREQUAL "" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "") OR "${CMAKE_C_COMPILER_ID}" STREQUAL "${CMAKE_CXX_COMPILER_ID}") - if(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "" OR "${CMAKE_Fortran_COMPILER_ID}" STREQUAL "") OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "${CMAKE_Fortran_COMPILER_ID}") - set(MIXING_COMPILERS FALSE) - endif() -endif() - -# -------------------------------------------------------------------- -# Find all enabled languages -# -------------------------------------------------------------------- -get_property(ALL_ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) - -set(ENABLED_LANGUAGES "") -# filter out ancillary languages (RC, NONE, etc.) -foreach(LANG ${ALL_ENABLED_LANGUAGES}) - if("${LANG}" STREQUAL "C" OR "${LANG}" STREQUAL "CXX" OR "${LANG}" STREQUAL "Fortran") - list(APPEND ENABLED_LANGUAGES ${LANG}) - endif() -endforeach() - -# -------------------------------------------------------------------- -# Minor bug fixes -# -------------------------------------------------------------------- - -# on MinGW there's a weird compatibility issue where FindBoost expects CMake to set a variable that it doesn't actually set -# so we have to help it out a bit - -if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(CMAKE_CXX_COMPILER_ARCHITECTURE_ID x64) -else() - set(CMAKE_CXX_COMPILER_ARCHITECTURE_ID X86) -endif() - -# For some reason, CMake isn't able to detect the implicit link dirs from PGI and doesn't see libraries in architecture dirs on Linux. -# This is ultimately a best-effort guess but should work for the common case. -if("${CMAKE_C_COMPILER_ID}" STREQUAL "PGI" AND HOST_LINUX AND "${TARGET_ARCH}" STREQUAL "x86_64") - - list(APPEND CMAKE_INCLUDE_PATH /usr/include/x86_64-linux-gnu) - list(APPEND CMAKE_LIBRARY_PATH /usr/lib/x86_64-linux-gnu) - +# This file can be included after at least one language is enabled, but before all of them are. +# It sets up all of the CMake options that affect compiler flags. + +# Set up options which affect compiler flags. +#------------------------------------------------------------------------------------------ + +#Dragonegg option +set(DRAGONEGG "" CACHE PATH "Path to the the Dragonegg gcc to LLVM bridge. Set to empty string to disable. If specified, it will be applied to any GCC compilers in use (gcc, g++, and gfortran).") + + # Check dragonegg +if(DRAGONEGG) + if(NOT EXISTS ${DRAGONEGG}) + message(FATAL_ERROR "Dragonegg enabled, but the Dragonegg path ${DRAGONEGG} does not point to a file.") + endif() +endif() + +#shared vs static option +option(STATIC "If true, build static libraries and freestanding (except for data files) executables. Otherwise, compile common code into shared libraries and link them to programs. \ +The runtime path is set properly now, so unless you move the installation AND don't source amber.sh you won't have to mess with LD_LIBRARY PATH" FALSE) + +if(STATIC) + set(SHARED FALSE) +else() + set(SHARED TRUE) +endif() + + +option(LARGE_FILE_SUPPORT "Build C code with large file support. Always on when building for a 64 bit target." TRUE) + +# FFT support +option(USE_FFT "Whether to use the Fastest Fourier Transform in the West library and build RISM and the PBSA FFT solver." TRUE) + +#set default library type appropriately +set(BUILD_SHARED_LIBS ${SHARED}) + +# NOTE: The correct way to handle optimization is to use generator expressions based on the current configuration. +# However, sometimes I need to use set_property(SOURCE PROPERTY COMPILE_FLAGS) to set compile flags for individual source files. +# This property didn't support generator expressions until CMake 3.8. Grrrrr. +# So, we use CMAKE__FLAGS_DEBUG for per-config debugging flags, but use a separate optimization switch. +option(OPTIMIZE "Whether to build code with compiler flags for optimization." TRUE) + +option(UNUSED_WARNINGS "Enable warnings about unused variables. Really clutters up the build output." FALSE) +option(UNINITIALIZED_WARNINGS "Enable warnings about uninitialized variables. Kind of clutters up the build output, but these need to be fixed." TRUE) + +option(DOUBLE_PRECISION "Build Amber's Fortran programs with double precision math." TRUE) + + +#let's try to enforce a reasonable standard here +set(CMAKE_C_STANDARD 99) +set(CMAKE_CXX_STANDARD 11) + +# I can't think of any better place to put this... + +#------------------------------------------------------------------------------ +# Now that we have our compiler, detect target architecture. +# This is kind of a hack, but it works. +# See TargetArch.cmake (from https://github.com/axr/solar-cmake) for details. +#------------------------------------------------------------------------------ +target_architecture(TARGET_ARCH) + +if("${TARGET_ARCH}" STREQUAL unknown OR "${TARGET_ARCH}" STREQUAL "") + message(FATAL_ERROR "Could not detect target architecture from compiler. Does the compiler work?") +endif() + + +#initialize SSE based on TARGET_ARCH +list_contains(SSE_SUPPORTED ${TARGET_ARCH} x86_64 ia64 i386) +set(SSE ${SSE_SUPPORTED} CACHE BOOL "Optimize for the SSE family of vectorizations.") +set(SSE_TYPES "" CACHE STRING "CPU types for which auto-dispatch code will be produced (Intel compilers version 11 and higher). Known valid + options are SSE2, SSE3, SSSE3, SSE4.1 and SSE4.2. Multiple options (comma separated) are permitted.") + +# Figure out no-undefined flag +if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) + set(NO_UNDEFINED_FLAG "-Wl,-undefined,error") +elseif((${CMAKE_SYSTEM_NAME} STREQUAL Linux) OR MINGW) + set(NO_UNDEFINED_FLAG "-Wl,--no-undefined") +else() + set(NO_UNDEFINED_FLAG "") +endif() + + +#------------------------------------------------------------------------------- +# Set up a couple of convenience variables to make checking the target OS less verbose +#------------------------------------------------------------------------------- +test(TARGET_OSX "${CMAKE_SYSTEM_NAME}" STREQUAL Darwin) +test(TARGET_WINDOWS "${CMAKE_SYSTEM_NAME}" STREQUAL Windows) +test(TARGET_LINUX "${CMAKE_SYSTEM_NAME}" STREQUAL Linux OR "${CMAKE_SYSTEM_NAME}" STREQUAL Android) # Android is close enough to Linux for our purposes + +test(HOST_OSX "${CMAKE_HOST_SYSTEM_NAME}" STREQUAL Darwin) +test(HOST_WINDOWS "${CMAKE_HOST_SYSTEM_NAME}" STREQUAL Windows) +test(HOST_LINUX "${CMAKE_HOST_SYSTEM_NAME}" STREQUAL Linux OR "${CMAKE_HOST_SYSTEM_NAME}" STREQUAL Android) + +# -------------------------------------------------------------------- +# Determine if we are mixing different vendors' compilers +# -------------------------------------------------------------------- +set(MIXING_COMPILERS TRUE) +if(("${CMAKE_C_COMPILER_ID}" STREQUAL "" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "") OR "${CMAKE_C_COMPILER_ID}" STREQUAL "${CMAKE_CXX_COMPILER_ID}") + if(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "" OR "${CMAKE_Fortran_COMPILER_ID}" STREQUAL "") OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "${CMAKE_Fortran_COMPILER_ID}") + set(MIXING_COMPILERS FALSE) + endif() +endif() + +# -------------------------------------------------------------------- +# Find all enabled languages +# -------------------------------------------------------------------- +get_property(ALL_ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) + +set(ENABLED_LANGUAGES "") +# filter out ancillary languages (RC, NONE, etc.) +foreach(LANG ${ALL_ENABLED_LANGUAGES}) + if("${LANG}" STREQUAL "C" OR "${LANG}" STREQUAL "CXX" OR "${LANG}" STREQUAL "Fortran") + list(APPEND ENABLED_LANGUAGES ${LANG}) + endif() +endforeach() + +# -------------------------------------------------------------------- +# Minor bug fixes +# -------------------------------------------------------------------- + +# on MinGW there's a weird compatibility issue where FindBoost expects CMake to set a variable that it doesn't actually set +# so we have to help it out a bit + +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(CMAKE_CXX_COMPILER_ARCHITECTURE_ID x64) +else() + set(CMAKE_CXX_COMPILER_ARCHITECTURE_ID X86) +endif() + +# For some reason, CMake isn't able to detect the implicit link dirs from PGI and doesn't see libraries in architecture dirs on Linux. +# This is ultimately a best-effort guess but should work for the common case. +if("${CMAKE_C_COMPILER_ID}" STREQUAL "PGI" AND HOST_LINUX AND "${TARGET_ARCH}" STREQUAL "x86_64") + + list(APPEND CMAKE_INCLUDE_PATH /usr/include/x86_64-linux-gnu) + list(APPEND CMAKE_LIBRARY_PATH /usr/lib/x86_64-linux-gnu) + endif() \ No newline at end of file diff --git a/cmake/CompilerFlags.cmake b/cmake/CompilerFlags.cmake index 0d2c9f0de..43a83c453 100644 --- a/cmake/CompilerFlags.cmake +++ b/cmake/CompilerFlags.cmake @@ -80,6 +80,10 @@ if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") endif() endif() + if("${CMAKE_C_COMPILER_VERSION}" VERSION_GREATER_EQUAL 10.0) + add_flags(C -fcommon) + endif() + if(DRAGONEGG) #check dragonegg check_c_compiler_flag(-fplugin=${DRAGONEGG} DRAGONEGG_C_WORKS) @@ -176,6 +180,13 @@ if("${CMAKE_Fortran_COMPILER_ID}" STREQUAL "GNU") add_flags(Fortran -fplugin=${DRAGONEGG}) endif() + + # gfortran 10.0 and higher need special flag to allow argument rank mismatch + if("${CMAKE_Fortran_COMPILER_VERSION}" VERSION_GREATER 10.0) + add_flags(Fortran -fallow-argument-mismatch) + add_flags(Fortran -fno-inline-arg-packing) + endif() + endif() #clang @@ -338,7 +349,7 @@ endif() if("${CMAKE_C_COMPILER_ID}" STREQUAL "IntelLLVM") set(CMAKE_C_FLAGS_DEBUG "-g -debug all") - set(OPT_CFLAGS -ip -O3) + set(OPT_CFLAGS -ipo -O3) # How flags get set for optimization depend on whether we have a MIC processor, # the version of Intel compiler we have, and whether we are cross-compiling @@ -374,7 +385,7 @@ if("${CMAKE_Fortran_COMPILER_ID}" STREQUAL "IntelLLVM") set(CMAKE_Fortran_FLAGS_DEBUG "/Zi") else() set(CMAKE_Fortran_FLAGS_DEBUG "-g -debug all") - set(OPT_FFLAGS -ip -O3) + set(OPT_FFLAGS -ipo -O3) if(SSE) if("${CMAKE_Fortran_COMPILER_VERSION}" VERSION_GREATER 11 OR ${CMAKE_Fortran_COMPILER_VERSION} VERSION_EQUAL 11) diff --git a/cmake/CopyTarget.cmake b/cmake/CopyTarget.cmake index 799aa2445..89c2a604c 100644 --- a/cmake/CopyTarget.cmake +++ b/cmake/CopyTarget.cmake @@ -146,19 +146,4 @@ function(remove_link_libraries TARGET) # ARGN: LIBRARIES... set_property(TARGET ${TARGET} PROPERTY LINK_LIBRARIES ${TARGET_LINK_LIBRARIES}) set_property(TARGET ${TARGET} PROPERTY INTERFACE_LINK_LIBRARIES ${TARGET_INTERFACE_LINK_LIBRARIES}) -endfunction(remove_link_libraries) - -function(remove_compile_definitions TARGET) # ARGN: LIBRARIES... - get_property(TARGET_COMPILE_DEFINITIONS TARGET ${TARGET} PROPERTY COMPILE_DEFINITIONS) - get_property(TARGET_INTERFACE_COMPILE_DEFINITIONS TARGET ${TARGET} PROPERTY INTERFACE_COMPILE_DEFINITIONS) - - if(NOT "${TARGET_COMPILE_DEFINITIONS}" STREQUAL "") - list(REMOVE_ITEM TARGET_COMPILE_DEFINITIONS ${ARGN}) - endif() - if(NOT "${TARGET_INTERFACE_COMPILE_DEFINITIONS}" STREQUAL "") - list(REMOVE_ITEM TARGET_INTERFACE_COMPILE_DEFINITIONS ${ARGN}) - endif() - - set_property(TARGET ${TARGET} PROPERTY COMPILE_DEFINITIONS ${TARGET_COMPILE_DEFINITIONS}) - set_property(TARGET ${TARGET} PROPERTY INTERFACE_COMPILE_DEFINITIONS ${TARGET_INTERFACE_COMPILE_DEFINITIONS}) -endfunction(remove_compile_definitions) \ No newline at end of file +endfunction(remove_link_libraries) \ No newline at end of file diff --git a/cmake/CudaConfig.cmake b/cmake/CudaConfig.cmake index 20658bb16..1b956e3a3 100644 --- a/cmake/CudaConfig.cmake +++ b/cmake/CudaConfig.cmake @@ -7,81 +7,142 @@ if(CROSSCOMPILE) set(CUDA FALSE) else() - # first, find CUDA. - find_package(CUDA) option(CUDA "Build ${PROJECT_NAME} with CUDA GPU acceleration support." FALSE) - - if(CUDA AND NOT CUDA_FOUND) - message(FATAL_ERROR "You turned on CUDA, but it was not found. Please set the CUDA_TOOLKIT_ROOT_DIR option to your CUDA install directory.") - endif() - if(CUDA) - + find_package(CUDA REQUIRED) + set(CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER}) - #Note at present we do not include SM3.5 or SM3.7 since they sometimes show performance - #regressions over just using SM3.0. - #SM8.0 = A100 - set(SM80FLAGS -gencode arch=compute_80,code=sm_80) - #SM7.5 = RTX20xx, RTX Titan, T4 and Quadro RTX - set(SM75FLAGS -gencode arch=compute_60,code=sm_75) + #SM9.0 = GH200 + set(SM90FLAGS -gencode arch=compute_90,code=sm_90) + #SM8.6 -- not currently used, but should be tested on Cuda 11.1 + set(SM86FLAGS -gencode arch=compute_86,code=sm_86) + #SM8.0 = A100 + set(SM80FLAGS -gencode arch=compute_80,code=sm_80) + #SM7.5 = RTX20xx, RTX Titan, T4 and Quadro RTX + set(SM75FLAGS -gencode arch=compute_75,code=sm_75) #SM7.0 = V100 and Volta Geforce / GTX Ampere? - set(SM70FLAGS -gencode arch=compute_60,code=sm_70) - #SM6.2 = ??? - set(SM62FLAGS -gencode arch=compute_62,code=sm_62) + set(SM70FLAGS -gencode arch=compute_70,code=sm_70) + #SM6.2 = ??? -- not currently used anyway + #set(SM62FLAGS -gencode arch=compute_62,code=sm_62) #SM6.1 = GP106 = GTX-1070, GP104 = GTX-1080, GP102 = Titan-X[P] set(SM61FLAGS -gencode arch=compute_61,code=sm_61) #SM6.0 = GP100 / P100 = DGX-1 set(SM60FLAGS -gencode arch=compute_60,code=sm_60) #SM5.3 = GM200 [Grid] = M60, M40? - set(SM53FLAGS -gencode arch=compute_53,code=sm_53 -DUSE_LEGACY_ATOMICS) + set(SM53FLAGS -gencode arch=compute_53,code=sm_53) #SM5.2 = GM200 = GTX-Titan-X, M6000 etc. - set(SM52FLAGS -gencode arch=compute_52,code=sm_52 -DUSE_LEGACY_ATOMICS) + set(SM52FLAGS -gencode arch=compute_52,code=sm_52) #SM5.0 = GM204 = GTX980, 970 etc - set(SM50FLAGS -gencode arch=compute_50,code=sm_50 -DUSE_LEGACY_ATOMICS) - #SM3.7 = GK210 = K80 - set(SM37FLAGS -gencode arch=compute_37,code=sm_37 -DUSE_LEGACY_ATOMICS) + set(SM50FLAGS -gencode arch=compute_50,code=sm_50) + #SM3.7 = GK210 = K80 -- not currently used, since SM3.0 may be better + #set(SM37FLAGS -gencode arch=compute_37,code=sm_37) #SM3.5 = GK110 + 110B = K20, K20X, K40, GTX780, GTX-Titan, GTX-Titan-Black, GTX-Titan-Z - set(SM35FLAGS -gencode arch=compute_35,code=sm_35 -DUSE_LEGACY_ATOMICS) + set(SM35FLAGS -gencode arch=compute_35,code=sm_35) #SM3.0 = GK104 = K10, GTX680, 690 etc. - set(SM30FLAGS -gencode arch=compute_30,code=sm_30 -DUSE_LEGACY_ATOMICS) - + set(SM30FLAGS -gencode arch=compute_30,code=sm_30) + message(STATUS "CUDA version ${CUDA_VERSION} detected") - + if(${CUDA_VERSION} VERSION_EQUAL 7.5) message(STATUS "Configuring CUDA for SM3.0, SM5.0, SM5.2 and SM5.3") message(STATUS "BE AWARE: CUDA 7.5 does not support GTX-1080, Titan-XP, DGX-1, V100 or other Pascal/Volta based GPUs.") list(APPEND CUDA_NVCC_FLAGS ${SM30FLAGS} ${SM50FLAGS} ${SM52FLAGS} ${SM53FLAGS}) - + elseif(${CUDA_VERSION} VERSION_EQUAL 8.0) message(STATUS "Configuring CUDA for SM3.0, SM5.0, SM5.2, SM5.3, SM6.0, SM6.1 and SM6.2") message(STATUS "BE AWARE: CUDA 8.0 does not support V100, GV100, Titan-V or later GPUs") list(APPEND CUDA_NVCC_FLAGS ${SM30FLAGS} ${SM50FLAGS} ${SM52FLAGS} ${SM53FLAGS} ${SM60FLAGS} ${SM61FLAGS} -Wno-deprecated-gpu-targets) - - elseif((${CUDA_VERSION} VERSION_GREATER_EQUAL 9.0) AND (${CUDA_VERSION} VERSION_LESS 10.0)) + + elseif((${CUDA_VERSION} VERSION_GREATER_EQUAL 9.0) AND (${CUDA_VERSION} VERSION_LESS 10.0)) message(STATUS "Configuring for SM3.0, SM3.5, SM3.7, SM5.0, SM5.2, SM5.3, SM6.0, SM6.1 and SM7.0") list(APPEND CUDA_NVCC_FLAGS ${SM30FLAGS} ${SM50FLAGS} ${SM52FLAGS} ${SM53FLAGS} ${SM60FLAGS} ${SM61FLAGS} ${SM70FLAGS} -Wno-deprecated-gpu-targets -Wno-deprecated-declarations) + elseif((${CUDA_VERSION} VERSION_GREATER_EQUAL 10.0) AND (${CUDA_VERSION} VERSION_LESS 11.0)) message(STATUS "Configuring for SM3.0, SM3.5, SM3.7, SM5.0, SM5.2, SM5.3, SM6.0, SM6.1, SM7.0 and SM7.5") - list(APPEND CUDA_NVCC_FLAGS ${SM30FLAGS} ${SM50FLAGS} ${SM52FLAGS} ${SM53FLAGS} ${SM60FLAGS} ${SM61FLAGS} ${SM70FLAGS} ${SM75FLAGS} -Wno-deprecated-gpu-targets -Wno-deprecated-declarations) - elseif(${CUDA_VERSION} VERSION_EQUAL 11.0) - # Implement the standard compilation rather than a warp-synchronous one, which is deprecated as of CUDA 11 - set(SM70FLAGS -gencode arch=compute_70,code=sm_70) - set(SM75FLAGS -gencode arch=compute_75,code=sm_75) - message(STATUS "Configuring for SM3.5, SM5.0, SM5.2, SM5.3, SM6.0, SM6.1, SM7.0, SM7.5 and SM8.0") - list(APPEND CUDA_NVCC_FLAGS ${SM35FLAGS} ${SM50FLAGS} ${SM52FLAGS} ${SM53FLAGS} ${SM60FLAGS} ${SM61FLAGS} ${SM70FLAGS} ${SM75FLAGS} ${SM80FLAGS} -Wno-deprecated-gpu-targets -Wno-deprecated-declarations) + list(APPEND CUDA_NVCC_FLAGS ${SM30FLAGS} ${SM50FLAGS} ${SM52FLAGS} ${SM53FLAGS} ${SM60FLAGS} ${SM61FLAGS} ${SM70FLAGS} ${SM75FLAGS} -Wno-deprecated-gpu-targets -Wno-deprecated-declarations) + + elseif((${CUDA_VERSION} VERSION_GREATER_EQUAL 11.0) AND (${CUDA_VERSION} VERSION_LESS 12.0)) + # Implement the standard compilation rather than a warp-synchronous one, which is deprecated as of CUDA 11 + + message(STATUS "Configuring for SM3.5, SM5.0, SM5.2, SM5.3, SM6.0, SM6.1, SM7.0, SM7.5 and SM8.0") + list(APPEND CUDA_NVCC_FLAGS ${SM35FLAGS} ${SM50FLAGS} ${SM52FLAGS} ${SM53FLAGS} ${SM60FLAGS} ${SM61FLAGS} ${SM70FLAGS} ${SM75FLAGS} ${SM80FLAGS} -Wno-deprecated-gpu-targets -Wno-deprecated-declarations) + elseif((${CUDA_VERSION} VERSION_GREATER_EQUAL 12.0) AND (${CUDA_VERSION} VERSION_LESS 12.5)) + message(STATUS "Configuring for SM5.0, SM5.2, SM5.3, SM6.0, SM6.1, SM7.0, SM7.5, SM8.0, SM8.6, and SM9.0") + list(APPEND CUDA_NVCC_FLAGS ${SM50FLAGS} ${SM52FLAGS} ${SM53FLAGS} ${SM60FLAGS} ${SM61FLAGS} ${SM70FLAGS} ${SM75FLAGS} ${SM80FLAGS} ${SM86FLAGS} ${SM90FLAGS} -Wno-deprecated-gpu-targets -Wno-deprecated-declarations) + + else() + message(FATAL_ERROR "Error: Untested CUDA version. AMBER currently requires CUDA version >= 7.5 and < 12.5.") + endif() + + # check maximum GNU compiler versions wrt cuda: + # PROGRAMMER WARNING: This code is NOT trivial. Before you + # modify it, read and understand it and the stackoverflow link ! + # https://stackoverflow.com/questions/6622454/cuda-incompatible-with-my-gcc-version + # VERSION_EQUAL 10 means 10.0, so use ranges to compare major versions. + if ( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" AND ( + ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.3 + AND CUDA_VERSION VERSION_GREATER_EQUAL 12.4 + AND CUDA_VERSION VERSION_LESS_EQUAL 12.4 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.3 + AND CUDA_VERSION VERSION_GREATER_EQUAL 12.1 + AND CUDA_VERSION VERSION_LESS_EQUAL 12.3 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.2 + AND CUDA_VERSION VERSION_GREATER_EQUAL 12 + AND CUDA_VERSION VERSION_LESS_EQUAL 12 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12 + AND CUDA_VERSION VERSION_GREATER_EQUAL 11.4.1 + AND CUDA_VERSION VERSION_LESS_EQUAL 11.8 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 11 + AND CUDA_VERSION VERSION_GREATER_EQUAL 11.1 + AND CUDA_VERSION VERSION_LESS_EQUAL 11.4.0 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10 + AND CUDA_VERSION VERSION_GREATER_EQUAL 11 + AND CUDA_VERSION VERSION_LESS_EQUAL 11 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9 + AND CUDA_VERSION VERSION_GREATER_EQUAL 10.1 + AND CUDA_VERSION VERSION_LESS_EQUAL 10.2 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8 + AND CUDA_VERSION VERSION_GREATER_EQUAL 9.2 + AND CUDA_VERSION VERSION_LESS_EQUAL 10.0 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7 + AND CUDA_VERSION VERSION_GREATER_EQUAL 9.0 + AND CUDA_VERSION VERSION_LESS_EQUAL 9.1 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6 + AND CUDA_VERSION VERSION_GREATER_EQUAL 8 + AND CUDA_VERSION VERSION_LESS_EQUAL 8 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5 + AND CUDA_VERSION VERSION_GREATER_EQUAL 7 + AND CUDA_VERSION VERSION_LESS_EQUAL 7 ) + ) ) + message(STATUS "Checking CUDA and GNU versions -- compatible") + elseif ( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" AND ( + CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13.2 + OR CUDA_VERSION VERSION_GREATER 12.4 + ) ) + message(STATUS "Checking CUDA and GNU versions -- compatibility unknown") + message(STATUS " See https://stackoverflow.com/questions/6622454/cuda-incompatible-with-my-gcc-version") + elseif ( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" ) + message(STATUS "") + message("************************************************************") + message("Error: Incompatible CUDA and GNU versions") + message(" ${CMAKE_CXX_COMPILER_VERSION}") + message(" ${CMAKE_CXX_COMPILER_VERSION_MAJOR}") + message("See https://stackoverflow.com/questions/6622454/cuda-incompatible-with-my-gcc-version") + message("************************************************************") + message(STATUS "") + message(FATAL_ERROR) else() - message(FATAL_ERROR "Error: Unsupported CUDA version. AMBER requires CUDA version >= 7.5 and <= 11.0. - Please upgrade your CUDA installation or disable building with CUDA.") + message(STATUS "Checking CUDA and compiler versions -- compatibility unknown") endif() - + set(CUDA_PROPAGATE_HOST_FLAGS FALSE) - + #the same CUDA file is used for multiple targets in PMEMD, so turn this off set(CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE FALSE) - + # -------------------------------------------------------------------- - # import a couple of CUDA libraries used by amber tools + # import a couple of CUDA libraries used by PMEMD and PBSA import_library(cublas "${CUDA_cublas_LIBRARY}") import_library(cufft "${CUDA_cufft_LIBRARY}") @@ -100,14 +161,55 @@ else() ENV CUDA_PATH ENV CUDA_LIB_PATH PATH_SUFFIXES lib64/stubs lib/stubs - DOC "Path to the CUDA Nvidia Management Library") + DOC "Path to the CUDA Nvidia Management Library" + NO_DEFAULT_PATH) if(NOT EXISTS "${CUDA_nvidia-ml_LIBRARY}") - message(WARNING "Cannot find the NVidia Management Library (libnvidia-ml) in your CUDA toolkit. mdgx.cuda will not be built.") + message(WARNING "Cannot find the NVidia Management Library (libnvidia-ml) in your CUDA toolkit. mdgx.cuda will not be built.") else() import_library(nvidia-ml "${CUDA_nvidia-ml_LIBRARY}") endif() + endif() + + option(HIP "Build ${PROJECT_NAME} with HIP GPU acceleration support." FALSE) + option(HIP_RDC "Build relocatable device code, also known as separate compilation mode." FALSE) + option(HIP_WARP64 "Build for CDNA AMD GPUs (warp size 64) or RDNA (warp size 32)" TRUE) + if(HIP) + find_package(HipCUDA REQUIRED) + set(CUDA ON) + + set(CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER}) + list(APPEND CUDA_NVCC_FLAGS + -DAMBER_PLATFORM_AMD + -fPIC + -std=c++14 + ) + + add_compile_definitions(AMBER_PLATFORM_AMD) + if(HIP_WARP64) + add_compile_definitions(AMBER_PLATFORM_AMD_WARP64) + endif() + set(CUDA_PROPAGATE_HOST_FLAGS FALSE) + + #the same CUDA file is used for multiple targets in PMEMD, so turn this off + set(CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE FALSE) + + if(HIP_RDC) + # Only hipcc can link a library compiled using RDC mode + # -Wl,--unresolved-symbols=ignore-in-object-files is added after + # because CMAKE_SHARED_LINKER_FLAGS contains -Wl,--no-undefined, but we link + # the whole program with all external shared libs later. + set(CMAKE_HIP_CREATE_SHARED_LIBRARY "${CUDA_NVCC_EXECUTABLE} -fgpu-rdc --hip-link -Wl,--unresolved-symbols=ignore-in-object-files -Wl,-soname, -o ") + # set(CMAKE_CXX_CREATE_SHARED_LIBRARY "${CUDA_NVCC_EXECUTABLE} -fgpu-rdc --hip-link -Wl,--unresolved-symbols=ignore-in-object-files -o ") + endif() + + import_library(cublas "${CUDA_cublas_LIBRARY}") + import_library(cufft "${CUDA_cufft_LIBRARY}") + + import_library(curand "${CUDA_curand_LIBRARY}") + import_library(cusparse "${CUDA_cusparse_LIBRARY}") + #import_library(cudadevrt "${CUDA_cudadevrt_LIBRARY}") endif() endif() diff --git a/cmake/ExternalPrograms.cmake b/cmake/ExternalPrograms.cmake index e37a82270..52038903f 100644 --- a/cmake/ExternalPrograms.cmake +++ b/cmake/ExternalPrograms.cmake @@ -1,42 +1,42 @@ -#File to search for miscellaneous programs that Amber uses -#NOTE: must be included after MPIConfig, OpenMPConfig, and CompilerFLags - - -#------------------------------------------------------------------------------ -# check for dl -#------------------------------------------------------------------------------ -check_library_exists(dl dlopen "" HAVE_LIBDL) - -#----------------------------------- -# M4 for XLeap -#----------------------------------- -find_program(M4 m4) - -#------------------------------------------------------------------------------ -# Flex -#------------------------------------------------------------------------------ -find_package(FLEX REQUIRED) - -#------------------------------------------------------------------------------ -# Bison -#------------------------------------------------------------------------------ -find_package(BISON REQUIRED) - -#------------------------------------------------------------------------------ -# bash, for running shell scripts -#------------------------------------------------------------------------------ -find_program(BASH bash) - -if(BASH AND NOT HOST_WINDOWS) - set(AUTOMAKE_DEFAULT TRUE) -else() - set(AUTOMAKE_DEFAULT FALSE) -endif() - -option(CAN_BUILD_AUTOMAKE "Whether it is possible to build dependencies which use Automake build systems on this platform." ${AUTOMAKE_DEFAULT}) - -#------------------------------------------------------------------------------ -# make, for configure scripts -#------------------------------------------------------------------------------ -set(MAKE_COMMAND make CACHE STRING "Command to run to make 3rd party projects with autotools / make-based build systems.") - +#File to search for miscellaneous programs that Amber uses +#NOTE: must be included after MPIConfig, OpenMPConfig, and CompilerFLags + + +#------------------------------------------------------------------------------ +# check for dl +#------------------------------------------------------------------------------ +check_library_exists(dl dlopen "" HAVE_LIBDL) + +#----------------------------------- +# M4 for XLeap +#----------------------------------- +find_program(M4 m4) + +#------------------------------------------------------------------------------ +# Flex +#------------------------------------------------------------------------------ +find_package(FLEX REQUIRED) + +#------------------------------------------------------------------------------ +# Bison +#------------------------------------------------------------------------------ +find_package(BISON REQUIRED) + +#------------------------------------------------------------------------------ +# bash, for running shell scripts +#------------------------------------------------------------------------------ +find_program(BASH bash) + +if(BASH AND NOT HOST_WINDOWS) + set(AUTOMAKE_DEFAULT TRUE) +else() + set(AUTOMAKE_DEFAULT FALSE) +endif() + +option(CAN_BUILD_AUTOMAKE "Whether it is possible to build dependencies which use Automake build systems on this platform." ${AUTOMAKE_DEFAULT}) + +#------------------------------------------------------------------------------ +# make, for configure scripts +#------------------------------------------------------------------------------ +set(MAKE_COMMAND make CACHE STRING "Command to run to make 3rd party projects with autotools / make-based build systems.") + diff --git a/cmake/FindAPBS.cmake b/cmake/FindAPBS.cmake index 7136f50f9..8b85aea4e 100644 --- a/cmake/FindAPBS.cmake +++ b/cmake/FindAPBS.cmake @@ -14,9 +14,12 @@ find_library(APBS_GENERIC_LIB apbs_generic) find_library(APBS_ROUTINES_LIB apbs_routines) find_library(APBS_PMGC_LIB apbs_pmgc) find_library(APBS_MG_LIB apbs_mg) +find_library(APBS_MC_LIB mc) +find_library(APBS_FEM_LIB apbs_fem) find_library(APBS_MALOC_LIB maloc) +find_library(UMFPACK_LIB umfpack) -set(APBS_LIBRARIES ${APBS_API_LIB} ${APBS_ROUTINES_LIB} ${APBS_MG_LIB} ${APBS_PMGC_LIB} ${APBS_GENERIC_LIB} ${APBS_MALOC_LIB} ) +set(APBS_LIBRARIES ${APBS_API_LIB} ${APBS_ROUTINES_LIB} ${APBS_MG_LIB} ${APBS_MC_LIB} ${APBS_PMGC_LIB} ${APBS_FEM_LIB} ${APBS_GENERIC_LIB} ${APBS_MALOC_LIB} ${UMFPACK_LIB} ) # on Windows, maloc needs to link to ws2_32.dll if("${CMAKE_SYSTEM_NAME}" STREQUAL Windows) @@ -24,15 +27,12 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL Windows) list(APPEND APBS_LIBRARIES ws2_32) endif() -find_path(APBS_INCLUDES apbs/apbs.h) +find_path(APBS_INCLUDES apbs.h) -#some of apbs's headers #include , so we have to supply the outer include directory as well -set(APBS_INNER_INCLUDES ${APBS_INCLUDES}/apbs ${APBS_INCLUDES}) - -if(NOT(APBS_GENERIC_LIB AND APBS_ROUTINES_LIB AND APBS_PMGC_LIB AND APBS_MG_LIB AND APBS_MALOC_LIB)) +if(NOT(APBS_GENERIC_LIB AND APBS_ROUTINES_LIB AND APBS_PMGC_LIB AND APBS_MG_LIB AND APBS_MC_LIB AND APBS_FEM_LIB AND UMFPACK_LIB AND APBS_MALOC_LIB)) set(FIND_APBS_FAILURE_MESSAGE "Could not find some or all of the five main APBS libraries. Please set APBS_GENERIC_LIB, APBS_ROUTINES_LIB, -APBS_PMGC_LIB, APBS_MG_LIB, and APBS_MALOC_LIB to point to the correct libraries") +APBS_PMGC_LIB, APBS_MG_LIB, APBS_MC_LIB, APBS_FEM_LIB, UMFPACK_LIB, and APBS_MALOC_LIB to point to the correct libraries") elseif(NOT APBS_API_LIB) @@ -54,4 +54,4 @@ else() endif() -find_package_handle_standard_args(APBS ${FIND_APBS_FAILURE_MESSAGE} APBS_API_LIB APBS_ROUTINES_LIB APBS_MG_LIB APBS_PMGC_LIB APBS_GENERIC_LIB APBS_MALOC_LIB APBS_WORKS APBS_INCLUDES) \ No newline at end of file +find_package_handle_standard_args(APBS ${FIND_APBS_FAILURE_MESSAGE} APBS_API_LIB APBS_ROUTINES_LIB APBS_MG_LIB APBS_PMGC_LIB APBS_GENERIC_LIB APBS_FEM_LIB APBS_MC_LIB UMFPACK_LIB APBS_MALOC_LIB APBS_WORKS APBS_INCLUDES) diff --git a/cmake/FindCUDA/make2cmake.cmake b/cmake/FindCUDA/make2cmake.cmake new file mode 100644 index 000000000..7b5389ec5 --- /dev/null +++ b/cmake/FindCUDA/make2cmake.cmake @@ -0,0 +1,106 @@ +# James Bigler, NVIDIA Corp (nvidia.com - jbigler) +# Abe Stephens, SCI Institute -- http://www.sci.utah.edu/~abe/FindCuda.html +# +# Copyright (c) 2008 - 2009 NVIDIA Corporation. All rights reserved. +# +# Copyright (c) 2007-2009 +# Scientific Computing and Imaging Institute, University of Utah +# +# This code is licensed under the MIT License. See the FindCUDA.cmake script +# for the text of the license. + +# The MIT License +# +# License for the specific language governing rights and limitations under +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# + +####################################################################### +# This converts a file written in makefile syntax into one that can be included +# by CMake. + +# Input variables +# +# verbose:BOOL=<> OFF: Be as quiet as possible (default) +# ON : Extra output +# +# input_file:FILEPATH=<> Path to dependecy file in makefile format +# +# output_file:FILEPATH=<> Path to file with dependencies in CMake readable variable +# + +file(READ ${input_file} depend_text) + +if (NOT "${depend_text}" STREQUAL "") + + # message("FOUND DEPENDS") + + string(REPLACE "\\ " " " depend_text ${depend_text}) + + # This works for the nvcc -M generated dependency files. + string(REGEX REPLACE "^.* : " "" depend_text ${depend_text}) + string(REGEX REPLACE "[ \\\\]*\n" ";" depend_text ${depend_text}) + + set(dependency_list "") + + foreach(file ${depend_text}) + + string(REGEX REPLACE "^ +" "" file ${file}) + + # OK, now if we had a UNC path, nvcc has a tendency to only output the first '/' + # instead of '//'. Here we will test to see if the file exists, if it doesn't then + # try to prepend another '/' to the path and test again. If it still fails remove the + # path. + + if(NOT EXISTS "${file}") + if (EXISTS "/${file}") + set(file "/${file}") + else() + if(verbose) + message(WARNING " Removing non-existent dependency file: ${file}") + endif() + set(file "") + endif() + endif() + + # Make sure we check to see if we have a file, before asking if it is not a directory. + # if(NOT IS_DIRECTORY "") will return TRUE. + if(file AND NOT IS_DIRECTORY "${file}") + # If softlinks start to matter, we should change this to REALPATH. For now we need + # to flatten paths, because nvcc can generate stuff like /bin/../include instead of + # just /include. + get_filename_component(file_absolute "${file}" ABSOLUTE) + list(APPEND dependency_list "${file_absolute}") + endif() + + endforeach() + +else() + # message("FOUND NO DEPENDS") +endif() + +# Remove the duplicate entries and sort them. +list(REMOVE_DUPLICATES dependency_list) +list(SORT dependency_list) + +foreach(file ${dependency_list}) + string(APPEND cuda_nvcc_depend " \"${file}\"\n") +endforeach() + +file(WRITE ${output_file} "# Generated by: make2cmake.cmake\nSET(CUDA_NVCC_DEPEND\n ${cuda_nvcc_depend})\n\n") diff --git a/cmake/FindCUDA/parse_cubin.cmake b/cmake/FindCUDA/parse_cubin.cmake new file mode 100644 index 000000000..626c8a2e4 --- /dev/null +++ b/cmake/FindCUDA/parse_cubin.cmake @@ -0,0 +1,111 @@ +# James Bigler, NVIDIA Corp (nvidia.com - jbigler) +# Abe Stephens, SCI Institute -- http://www.sci.utah.edu/~abe/FindCuda.html +# +# Copyright (c) 2008 - 2009 NVIDIA Corporation. All rights reserved. +# +# Copyright (c) 2007-2009 +# Scientific Computing and Imaging Institute, University of Utah +# +# This code is licensed under the MIT License. See the FindCUDA.cmake script +# for the text of the license. + +# The MIT License +# +# License for the specific language governing rights and limitations under +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# + +####################################################################### +# Parses a .cubin file produced by nvcc and reports statistics about the file. + + +file(READ ${input_file} file_text) + +if (NOT "${file_text}" STREQUAL "") + + string(REPLACE ";" "\\;" file_text ${file_text}) + string(REPLACE "\ncode" ";code" file_text ${file_text}) + + list(LENGTH file_text len) + + foreach(line ${file_text}) + + # Only look at "code { }" blocks. + if(line MATCHES "^code") + + # Break into individual lines. + string(REGEX REPLACE "\n" ";" line ${line}) + + foreach(entry ${line}) + + # Extract kernel names. + if (${entry} MATCHES "[^g]name = ([^ ]+)") + set(entry "${CMAKE_MATCH_1}") + + # Check to see if the kernel name starts with "_" + set(skip FALSE) + # if (${entry} MATCHES "^_") + # Skip the rest of this block. + # message("Skipping ${entry}") + # set(skip TRUE) + # else () + message("Kernel: ${entry}") + # endif () + + endif() + + # Skip the rest of the block if necessary + if(NOT skip) + + # Registers + if (${entry} MATCHES "reg([ ]+)=([ ]+)([^ ]+)") + set(entry "${CMAKE_MATCH_3}") + message("Registers: ${entry}") + endif() + + # Local memory + if (${entry} MATCHES "lmem([ ]+)=([ ]+)([^ ]+)") + set(entry "${CMAKE_MATCH_3}") + message("Local: ${entry}") + endif() + + # Shared memory + if (${entry} MATCHES "smem([ ]+)=([ ]+)([^ ]+)") + set(entry "${CMAKE_MATCH_3}") + message("Shared: ${entry}") + endif() + + if (${entry} MATCHES "^}") + message("") + endif() + + endif() + + + endforeach() + + endif() + + endforeach() + +else() + # message("FOUND NO DEPENDS") +endif() + + diff --git a/cmake/FindCUDA/run_nvcc.cmake b/cmake/FindCUDA/run_nvcc.cmake new file mode 100644 index 000000000..1687f07a8 --- /dev/null +++ b/cmake/FindCUDA/run_nvcc.cmake @@ -0,0 +1,307 @@ +# James Bigler, NVIDIA Corp (nvidia.com - jbigler) +# +# Copyright (c) 2008 - 2009 NVIDIA Corporation. All rights reserved. +# +# This code is licensed under the MIT License. See the FindCUDA.cmake script +# for the text of the license. + +# The MIT License +# +# License for the specific language governing rights and limitations under +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. + + +########################################################################## +# This file runs the nvcc commands to produce the desired output file along with +# the dependency file needed by CMake to compute dependencies. In addition the +# file checks the output of each command and if the command fails it deletes the +# output files. + +# Input variables +# +# verbose:BOOL=<> OFF: Be as quiet as possible (default) +# ON : Describe each step +# +# build_configuration:STRING=<> Typically one of Debug, MinSizeRel, Release, or +# RelWithDebInfo, but it should match one of the +# entries in CUDA_HOST_FLAGS. This is the build +# configuration used when compiling the code. If +# blank or unspecified Debug is assumed as this is +# what CMake does. +# +# generated_file:STRING=<> File to generate. This argument must be passed in. +# +# generated_cubin_file:STRING=<> File to generate. This argument must be passed +# in if build_cubin is true. + +if(NOT generated_file) + message(FATAL_ERROR "You must specify generated_file on the command line") +endif() + +# Set these up as variables to make reading the generated file easier +set(CMAKE_COMMAND "@CMAKE_COMMAND@") # path +set(source_file "@source_file@") # path +set(NVCC_generated_dependency_file "@NVCC_generated_dependency_file@") # path +set(cmake_dependency_file "@cmake_dependency_file@") # path +set(CUDA_make2cmake "@CUDA_make2cmake@") # path +set(CUDA_parse_cubin "@CUDA_parse_cubin@") # path +set(build_cubin @build_cubin@) # bool +set(CUDA_HOST_COMPILER "@CUDA_HOST_COMPILER@") # path +# We won't actually use these variables for now, but we need to set this, in +# order to force this file to be run again if it changes. +set(generated_file_path "@generated_file_path@") # path +set(generated_file_internal "@generated_file@") # path +set(generated_cubin_file_internal "@generated_cubin_file@") # path + +set(CUDA_NVCC_EXECUTABLE "@CUDA_NVCC_EXECUTABLE@") # path +set(CUDA_NVCC_FLAGS @CUDA_NVCC_FLAGS@ ;; @CUDA_WRAP_OPTION_NVCC_FLAGS@) # list +@CUDA_NVCC_FLAGS_CONFIG@ +set(nvcc_flags @nvcc_flags@) # list +set(CUDA_NVCC_INCLUDE_DIRS "@CUDA_NVCC_INCLUDE_DIRS@") # list (needs to be in quotes to handle spaces properly). +set(CUDA_NVCC_COMPILE_DEFINITIONS "@CUDA_NVCC_COMPILE_DEFINITIONS@") # list (needs to be in quotes to handle spaces properly). +set(format_flag "@format_flag@") # string +set(cuda_language_flag @cuda_language_flag@) # list + +# Clean up list of include directories and add -I flags +list(REMOVE_DUPLICATES CUDA_NVCC_INCLUDE_DIRS) +set(CUDA_NVCC_INCLUDE_ARGS) +foreach(dir ${CUDA_NVCC_INCLUDE_DIRS}) + # Extra quotes are added around each flag to help nvcc parse out flags with spaces. + list(APPEND CUDA_NVCC_INCLUDE_ARGS "-I${dir}") +endforeach() + +# Clean up list of compile definitions, add -D flags, and append to nvcc_flags +list(REMOVE_DUPLICATES CUDA_NVCC_COMPILE_DEFINITIONS) +foreach(def ${CUDA_NVCC_COMPILE_DEFINITIONS}) + list(APPEND nvcc_flags "-D${def}") +endforeach() + +if(build_cubin AND NOT generated_cubin_file) + message(FATAL_ERROR "You must specify generated_cubin_file on the command line") +endif() + +# This is the list of host compilation flags. It C or CXX should already have +# been chosen by FindCUDA.cmake. +@CUDA_HOST_FLAGS@ + +# Take the compiler flags and package them up to be sent to the compiler via -Xcompiler +set(nvcc_host_compiler_flags "") +# If we weren't given a build_configuration, use Debug. +if(NOT build_configuration) + set(build_configuration Debug) +endif() +string(TOUPPER "${build_configuration}" build_configuration) +#message("CUDA_NVCC_HOST_COMPILER_FLAGS = ${CUDA_NVCC_HOST_COMPILER_FLAGS}") +foreach(flag ${CMAKE_HOST_FLAGS} ${CMAKE_HOST_FLAGS_${build_configuration}}) + # Extra quotes are added around each flag to help nvcc parse out flags with spaces. + #string(APPEND nvcc_host_compiler_flags ",\"${flag}\"") + string(APPEND nvcc_host_compiler_flags "${flag}") +endforeach() +if (nvcc_host_compiler_flags) + #set(nvcc_host_compiler_flags "-Xcompiler" ${nvcc_host_compiler_flags}) +endif() +#message("nvcc_host_compiler_flags = \"${nvcc_host_compiler_flags}\"") +# Add the build specific configuration flags +list(APPEND CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS_${build_configuration}}) + +# Any -ccbin existing in CUDA_NVCC_FLAGS gets highest priority +list( FIND CUDA_NVCC_FLAGS "-ccbin" ccbin_found0 ) +list( FIND CUDA_NVCC_FLAGS "--compiler-bindir" ccbin_found1 ) +if( ccbin_found0 LESS 0 AND ccbin_found1 LESS 0 AND CUDA_HOST_COMPILER ) + if (CUDA_HOST_COMPILER STREQUAL "$(VCInstallDir)bin" AND DEFINED CCBIN) + set(CCBIN -ccbin "${CCBIN}") + else() + set(CCBIN -ccbin "${CUDA_HOST_COMPILER}") + endif() +endif() + +# cuda_execute_process - Executes a command with optional command echo and status message. +# +# status - Status message to print if verbose is true +# command - COMMAND argument from the usual execute_process argument structure +# ARGN - Remaining arguments are the command with arguments +# +# CUDA_result - return value from running the command +# +# Make this a macro instead of a function, so that things like RESULT_VARIABLE +# and other return variables are present after executing the process. +macro(cuda_execute_process status command) + set(_command ${command}) + if(NOT "x${_command}" STREQUAL "xCOMMAND") + message(FATAL_ERROR "Malformed call to cuda_execute_process. Missing COMMAND as second argument. (command = ${command})") + endif() + if(verbose) + execute_process(COMMAND "${CMAKE_COMMAND}" -E echo -- ${status}) + # Now we need to build up our command string. We are accounting for quotes + # and spaces, anything else is left up to the user to fix if they want to + # copy and paste a runnable command line. + set(cuda_execute_process_string) + foreach(arg ${ARGN}) + # If there are quotes, excape them, so they come through. + string(REPLACE "\"" "\\\"" arg ${arg}) + # Args with spaces need quotes around them to get them to be parsed as a single argument. + if(arg MATCHES " ") + list(APPEND cuda_execute_process_string "\"${arg}\"") + else() + list(APPEND cuda_execute_process_string ${arg}) + endif() + endforeach() + # Echo the command + execute_process(COMMAND ${CMAKE_COMMAND} -E echo ${cuda_execute_process_string}) + endif() + # Run the command + execute_process(COMMAND ${ARGN} RESULT_VARIABLE CUDA_result ) +endmacro() + +# Delete the target file +cuda_execute_process( + "Removing ${generated_file}" + COMMAND "${CMAKE_COMMAND}" -E remove "${generated_file}" + ) + +# For CUDA 2.3 and below, -G -M doesn't work, so remove the -G flag +# for dependency generation and hope for the best. +set(depends_CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}") +set(CUDA_VERSION @CUDA_VERSION@) +if(CUDA_VERSION VERSION_LESS "3.0") + cmake_policy(PUSH) + # CMake policy 0007 NEW states that empty list elements are not + # ignored. I'm just setting it to avoid the warning that's printed. + cmake_policy(SET CMP0007 NEW) + # Note that this will remove all occurances of -G. + list(REMOVE_ITEM depends_CUDA_NVCC_FLAGS "-G") + cmake_policy(POP) +endif() + +# nvcc doesn't define __CUDACC__ for some reason when generating dependency files. This +# can cause incorrect dependencies when #including files based on this macro which is +# defined in the generating passes of nvcc invokation. We will go ahead and manually +# define this for now until a future version fixes this bug. +set(CUDACC_DEFINE -D__CUDACC__) + +# Generate the dependency file +cuda_execute_process( + "Generating dependency file: ${NVCC_generated_dependency_file}" + COMMAND "${CUDA_NVCC_EXECUTABLE}" + -M + #${CUDACC_DEFINE} + "${source_file}" + -o "${NVCC_generated_dependency_file}" + #${CCBIN} + ${nvcc_flags} + ${nvcc_host_compiler_flags} + ${depends_CUDA_NVCC_FLAGS} + #-DNVCC + ${CUDA_NVCC_INCLUDE_ARGS} + ) + +if(CUDA_result) + message(FATAL_ERROR "Error generating ${generated_file}") +endif() + +# Generate the cmake readable dependency file to a temp file. Don't put the +# quotes just around the filenames for the input_file and output_file variables. +# CMake will pass the quotes through and not be able to find the file. +cuda_execute_process( + "Generating temporary cmake readable file: ${cmake_dependency_file}.tmp" + COMMAND "${CMAKE_COMMAND}" + -D "input_file:FILEPATH=${NVCC_generated_dependency_file}" + -D "output_file:FILEPATH=${cmake_dependency_file}.tmp" + -D "verbose=${verbose}" + -P "${CUDA_make2cmake}" + ) + +if(CUDA_result) + message(FATAL_ERROR "Error generating ${generated_file}") +endif() + +# Copy the file if it is different +cuda_execute_process( + "Copy if different ${cmake_dependency_file}.tmp to ${cmake_dependency_file}" + COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${cmake_dependency_file}.tmp" "${cmake_dependency_file}" + ) + +if(CUDA_result) + message(FATAL_ERROR "Error generating ${generated_file}") +endif() + +# Delete the temporary file +cuda_execute_process( + "Removing ${cmake_dependency_file}.tmp and ${NVCC_generated_dependency_file}" + COMMAND "${CMAKE_COMMAND}" -E remove "${cmake_dependency_file}.tmp" "${NVCC_generated_dependency_file}" + ) + +if(CUDA_result) + message(FATAL_ERROR "Error generating ${generated_file}") +endif() + +# Generate the code +cuda_execute_process( + "Generating ${generated_file}" + COMMAND "${CUDA_NVCC_EXECUTABLE}" + "${source_file}" + ${cuda_language_flag} + ${format_flag} -o "${generated_file}" + #${CCBIN} + ${nvcc_flags} + ${nvcc_host_compiler_flags} + ${CUDA_NVCC_FLAGS} + -DNVCC + ${CUDA_NVCC_INCLUDE_ARGS} + ) + +if(CUDA_result) + # Since nvcc can sometimes leave half done files make sure that we delete the output file. + cuda_execute_process( + "Removing ${generated_file}" + COMMAND "${CMAKE_COMMAND}" -E remove "${generated_file}" + ) + message(FATAL_ERROR "Error generating file ${generated_file}") +else() + if(verbose) + message("Generated ${generated_file} successfully.") + endif() +endif() + +# Cubin resource report commands. +if( build_cubin ) + # Run with -cubin to produce resource usage report. + cuda_execute_process( + "Generating ${generated_cubin_file}" + COMMAND "${CUDA_NVCC_EXECUTABLE}" + "${source_file}" + ${CUDA_NVCC_FLAGS} + ${nvcc_flags} + #${CCBIN} + ${nvcc_host_compiler_flags} + -DNVCC + -cubin + -o "${generated_cubin_file}" + ${CUDA_NVCC_INCLUDE_ARGS} + ) + + # Execute the parser script. + cuda_execute_process( + "Executing the parser script" + COMMAND "${CMAKE_COMMAND}" + -D "input_file:STRING=${generated_cubin_file}" + -P "${CUDA_parse_cubin}" + ) + +endif() diff --git a/cmake/FindCUDA/select_compute_arch.cmake b/cmake/FindCUDA/select_compute_arch.cmake new file mode 100644 index 000000000..8fb44d80a --- /dev/null +++ b/cmake/FindCUDA/select_compute_arch.cmake @@ -0,0 +1,198 @@ +# Synopsis: +# CUDA_SELECT_NVCC_ARCH_FLAGS(out_variable [target_CUDA_architectures]) +# -- Selects GPU arch flags for nvcc based on target_CUDA_architectures +# target_CUDA_architectures : Auto | Common | All | LIST(ARCH_AND_PTX ...) +# - "Auto" detects local machine GPU compute arch at runtime. +# - "Common" and "All" cover common and entire subsets of architectures +# ARCH_AND_PTX : NAME | NUM.NUM | NUM.NUM(NUM.NUM) | NUM.NUM+PTX +# NAME: Fermi Kepler Maxwell Kepler+Tegra Kepler+Tesla Maxwell+Tegra Pascal +# NUM: Any number. Only those pairs are currently accepted by NVCC though: +# 2.0 2.1 3.0 3.2 3.5 3.7 5.0 5.2 5.3 6.0 6.2 +# Returns LIST of flags to be added to CUDA_NVCC_FLAGS in ${out_variable} +# Additionally, sets ${out_variable}_readable to the resulting numeric list +# Example: +# CUDA_SELECT_NVCC_ARCH_FLAGS(ARCH_FLAGS 3.0 3.5+PTX 5.2(5.0) Maxwell) +# LIST(APPEND CUDA_NVCC_FLAGS ${ARCH_FLAGS}) +# +# More info on CUDA architectures: https://en.wikipedia.org/wiki/CUDA +# + +# This list will be used for CUDA_ARCH_NAME = All option +set(CUDA_KNOWN_GPU_ARCHITECTURES "Fermi" "Kepler" "Maxwell") + +# This list will be used for CUDA_ARCH_NAME = Common option (enabled by default) +set(CUDA_COMMON_GPU_ARCHITECTURES "3.0" "3.5" "5.0") + +if (CUDA_VERSION VERSION_GREATER "6.5") + list(APPEND CUDA_KNOWN_GPU_ARCHITECTURES "Kepler+Tegra" "Kepler+Tesla" "Maxwell+Tegra") + list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "5.2") +endif () + +if (CUDA_VERSION VERSION_GREATER "7.5") + list(APPEND CUDA_KNOWN_GPU_ARCHITECTURES "Pascal") + list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "6.0" "6.1" "6.1+PTX") +else() + list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "5.2+PTX") +endif () + + + +################################################################################################ +# A function for automatic detection of GPUs installed (if autodetection is enabled) +# Usage: +# CUDA_DETECT_INSTALLED_GPUS(OUT_VARIABLE) +# +function(CUDA_DETECT_INSTALLED_GPUS OUT_VARIABLE) + if(NOT CUDA_GPU_DETECT_OUTPUT) + set(file ${PROJECT_BINARY_DIR}/detect_cuda_compute_capabilities.cpp) + + file(WRITE ${file} "" + "#include \n" + "#include \n" + "int main()\n" + "{\n" + " int count = 0;\n" + " if (cudaSuccess != cudaGetDeviceCount(&count)) return -1;\n" + " if (count == 0) return -1;\n" + " for (int device = 0; device < count; ++device)\n" + " {\n" + " cudaDeviceProp prop;\n" + " if (cudaSuccess == cudaGetDeviceProperties(&prop, device))\n" + " std::printf(\"%d.%d \", prop.major, prop.minor);\n" + " }\n" + " return 0;\n" + "}\n") + + try_run(run_result compile_result ${PROJECT_BINARY_DIR} ${file} + CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${CUDA_INCLUDE_DIRS}" + LINK_LIBRARIES ${CUDA_LIBRARIES} + RUN_OUTPUT_VARIABLE compute_capabilities) + + if(run_result EQUAL 0) + string(REPLACE "2.1" "2.1(2.0)" compute_capabilities "${compute_capabilities}") + set(CUDA_GPU_DETECT_OUTPUT ${compute_capabilities} + CACHE INTERNAL "Returned GPU architectures from detect_gpus tool" FORCE) + endif() + endif() + + if(NOT CUDA_GPU_DETECT_OUTPUT) + message(STATUS "Automatic GPU detection failed. Building for common architectures.") + set(${OUT_VARIABLE} ${CUDA_COMMON_GPU_ARCHITECTURES} PARENT_SCOPE) + else() + set(${OUT_VARIABLE} ${CUDA_GPU_DETECT_OUTPUT} PARENT_SCOPE) + endif() +endfunction() + + +################################################################################################ +# Function for selecting GPU arch flags for nvcc based on CUDA architectures from parameter list +# Usage: +# SELECT_NVCC_ARCH_FLAGS(out_variable [list of CUDA compute archs]) +function(CUDA_SELECT_NVCC_ARCH_FLAGS out_variable) + set(CUDA_ARCH_LIST "${ARGN}") + + if("X${CUDA_ARCH_LIST}" STREQUAL "X" ) + set(CUDA_ARCH_LIST "Auto") + endif() + + set(cuda_arch_bin) + set(cuda_arch_ptx) + + if("${CUDA_ARCH_LIST}" STREQUAL "All") + set(CUDA_ARCH_LIST ${CUDA_KNOWN_GPU_ARCHITECTURES}) + elseif("${CUDA_ARCH_LIST}" STREQUAL "Common") + set(CUDA_ARCH_LIST ${CUDA_COMMON_GPU_ARCHITECTURES}) + elseif("${CUDA_ARCH_LIST}" STREQUAL "Auto") + CUDA_DETECT_INSTALLED_GPUS(CUDA_ARCH_LIST) + message(STATUS "Autodetected CUDA architecture(s): ${CUDA_ARCH_LIST}") + endif() + + # Now process the list and look for names + string(REGEX REPLACE "[ \t]+" ";" CUDA_ARCH_LIST "${CUDA_ARCH_LIST}") + list(REMOVE_DUPLICATES CUDA_ARCH_LIST) + foreach(arch_name ${CUDA_ARCH_LIST}) + set(arch_bin) + set(arch_ptx) + set(add_ptx FALSE) + # Check to see if we are compiling PTX + if(arch_name MATCHES "(.*)\\+PTX$") + set(add_ptx TRUE) + set(arch_name ${CMAKE_MATCH_1}) + endif() + if(arch_name MATCHES "^([0-9]\\.[0-9](\\([0-9]\\.[0-9]\\))?)$") + set(arch_bin ${CMAKE_MATCH_1}) + set(arch_ptx ${arch_bin}) + else() + # Look for it in our list of known architectures + if(${arch_name} STREQUAL "Fermi") + set(arch_bin 2.0 "2.1(2.0)") + elseif(${arch_name} STREQUAL "Kepler+Tegra") + set(arch_bin 3.2) + elseif(${arch_name} STREQUAL "Kepler+Tesla") + set(arch_bin 3.7) + elseif(${arch_name} STREQUAL "Kepler") + set(arch_bin 3.0 3.5) + set(arch_ptx 3.5) + elseif(${arch_name} STREQUAL "Maxwell+Tegra") + set(arch_bin 5.3) + elseif(${arch_name} STREQUAL "Maxwell") + set(arch_bin 5.0 5.2) + set(arch_ptx 5.2) + elseif(${arch_name} STREQUAL "Pascal") + set(arch_bin 6.0 6.1) + set(arch_ptx 6.1) + else() + message(SEND_ERROR "Unknown CUDA Architecture Name ${arch_name} in CUDA_SELECT_NVCC_ARCH_FLAGS") + endif() + endif() + if(NOT arch_bin) + message(SEND_ERROR "arch_bin wasn't set for some reason") + endif() + list(APPEND cuda_arch_bin ${arch_bin}) + if(add_ptx) + if (NOT arch_ptx) + set(arch_ptx ${arch_bin}) + endif() + list(APPEND cuda_arch_ptx ${arch_ptx}) + endif() + endforeach() + + # remove dots and convert to lists + string(REGEX REPLACE "\\." "" cuda_arch_bin "${cuda_arch_bin}") + string(REGEX REPLACE "\\." "" cuda_arch_ptx "${cuda_arch_ptx}") + string(REGEX MATCHALL "[0-9()]+" cuda_arch_bin "${cuda_arch_bin}") + string(REGEX MATCHALL "[0-9]+" cuda_arch_ptx "${cuda_arch_ptx}") + + if(cuda_arch_bin) + list(REMOVE_DUPLICATES cuda_arch_bin) + endif() + if(cuda_arch_ptx) + list(REMOVE_DUPLICATES cuda_arch_ptx) + endif() + + set(nvcc_flags "") + set(nvcc_archs_readable "") + + # Tell NVCC to add binaries for the specified GPUs + foreach(arch ${cuda_arch_bin}) + if(arch MATCHES "([0-9]+)\\(([0-9]+)\\)") + # User explicitly specified ARCH for the concrete CODE + list(APPEND nvcc_flags -gencode arch=compute_${CMAKE_MATCH_2},code=sm_${CMAKE_MATCH_1}) + list(APPEND nvcc_archs_readable sm_${CMAKE_MATCH_1}) + else() + # User didn't explicitly specify ARCH for the concrete CODE, we assume ARCH=CODE + list(APPEND nvcc_flags -gencode arch=compute_${arch},code=sm_${arch}) + list(APPEND nvcc_archs_readable sm_${arch}) + endif() + endforeach() + + # Tell NVCC to add PTX intermediate code for the specified architectures + foreach(arch ${cuda_arch_ptx}) + list(APPEND nvcc_flags -gencode arch=compute_${arch},code=compute_${arch}) + list(APPEND nvcc_archs_readable compute_${arch}) + endforeach() + + string(REPLACE ";" " " nvcc_archs_readable "${nvcc_archs_readable}") + set(${out_variable} ${nvcc_flags} PARENT_SCOPE) + set(${out_variable}_readable ${nvcc_archs_readable} PARENT_SCOPE) +endfunction() diff --git a/cmake/FindDeePMD.cmake b/cmake/FindDeePMD.cmake new file mode 100644 index 000000000..3066968a8 --- /dev/null +++ b/cmake/FindDeePMD.cmake @@ -0,0 +1,30 @@ +# - Find DeePMD-kit +# +# This module finds the DeePMD-kit C library on your system. +# +# Variables: +# DeePMD_FOUND - Whether DeePMD-kit was found +# +# If DeePMD-kit was found, this module also creates the following imported target: +# DEEPMD::deepmd_c - Target for DeePMD-kit's C libraries + + +# find library +find_library(DeePMD_LIBRARY + NAMES deepmd_c + DOC "Path to DeePMD-kit C library") + +# search for headers +find_path(DeePMD_INCLUDE_DIR + NAMES deepmd/deepmd.hpp deepmd/c_api.h + DOC "Path to DeePMD-kit's includes. Should contain deepmd/deepmd.hpp and deepmd/c_api.h") + +find_package_handle_standard_args(DeePMD + REQUIRED_VARS DeePMD_LIBRARY DeePMD_INCLUDE_DIR) + +# create imported target +if(DeePMD_FOUND) + add_library(DeePMD::deepmd_c UNKNOWN IMPORTED) + set_property(TARGET DeePMD::deepmd_c PROPERTY IMPORTED_LOCATION ${DeePMD_LIBRARY}) + set_property(TARGET DeePMD::deepmd_c PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${DeePMD_INCLUDE_DIR}) +endif() diff --git a/cmake/FindHipCUDA.cmake b/cmake/FindHipCUDA.cmake new file mode 100644 index 000000000..6a4b3faf1 --- /dev/null +++ b/cmake/FindHipCUDA.cmake @@ -0,0 +1,1939 @@ +#.rst: +# FindHipCUDA +# -------- +# +# Tools for building CUDA C files using hipcc: libraries and build dependencies. +# +# This script locates the NVIDIA CUDA C tools. It should work on linux, +# windows, and mac and should be reasonably up to date with CUDA C +# releases. +# +# This script makes use of the standard find_package arguments of +# , REQUIRED and QUIET. CUDA_FOUND will report if an +# acceptable version of CUDA was found. +# +# The script will prompt the user to specify CUDA_TOOLKIT_ROOT_DIR if +# the prefix cannot be determined by the location of nvcc in the system +# path and REQUIRED is specified to find_package(). To use a different +# installed version of the toolkit set the environment variable +# CUDA_BIN_PATH before running cmake (e.g. +# CUDA_BIN_PATH=/usr/local/cuda1.0 instead of the default +# /usr/local/cuda) or set CUDA_TOOLKIT_ROOT_DIR after configuring. If +# you change the value of CUDA_TOOLKIT_ROOT_DIR, various components that +# depend on the path will be relocated. +# +# It might be necessary to set CUDA_TOOLKIT_ROOT_DIR manually on certain +# platforms, or to use a cuda runtime not installed in the default +# location. In newer versions of the toolkit the cuda library is +# included with the graphics driver- be sure that the driver version +# matches what is needed by the cuda runtime version. +# +# The following variables affect the behavior of the macros in the +# script (in alphebetical order). Note that any of these flags can be +# changed multiple times in the same directory before calling +# CUDA_ADD_EXECUTABLE, CUDA_ADD_LIBRARY, CUDA_COMPILE, CUDA_COMPILE_PTX, +# CUDA_COMPILE_FATBIN, CUDA_COMPILE_CUBIN or CUDA_WRAP_SRCS:: +# +# CUDA_64_BIT_DEVICE_CODE (Default matches host bit size) +# -- Set to ON to compile for 64 bit device code, OFF for 32 bit device code. +# Note that making this different from the host code when generating object +# or C files from CUDA code just won't work, because size_t gets defined by +# nvcc in the generated source. If you compile to PTX and then load the +# file yourself, you can mix bit sizes between device and host. +# +# CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE (Default ON) +# -- Set to ON if you want the custom build rule to be attached to the source +# file in Visual Studio. Turn OFF if you add the same cuda file to multiple +# targets. +# +# This allows the user to build the target from the CUDA file; however, bad +# things can happen if the CUDA source file is added to multiple targets. +# When performing parallel builds it is possible for the custom build +# command to be run more than once and in parallel causing cryptic build +# errors. VS runs the rules for every source file in the target, and a +# source can have only one rule no matter how many projects it is added to. +# When the rule is run from multiple targets race conditions can occur on +# the generated file. Eventually everything will get built, but if the user +# is unaware of this behavior, there may be confusion. It would be nice if +# this script could detect the reuse of source files across multiple targets +# and turn the option off for the user, but no good solution could be found. +# +# CUDA_BUILD_CUBIN (Default OFF) +# -- Set to ON to enable and extra compilation pass with the -cubin option in +# Device mode. The output is parsed and register, shared memory usage is +# printed during build. +# +# CUDA_BUILD_EMULATION (Default OFF for device mode) +# -- Set to ON for Emulation mode. -D_DEVICEEMU is defined for CUDA C files +# when CUDA_BUILD_EMULATION is TRUE. +# +# CUDA_GENERATED_OUTPUT_DIR (Default CMAKE_CURRENT_BINARY_DIR) +# -- Set to the path you wish to have the generated files placed. If it is +# blank output files will be placed in CMAKE_CURRENT_BINARY_DIR. +# Intermediate files will always be placed in +# CMAKE_CURRENT_BINARY_DIR/CMakeFiles. +# +# CUDA_HOST_COMPILATION_CPP (Default ON) +# -- Set to OFF for C compilation of host code. +# +# CUDA_HOST_COMPILER (Default CMAKE_C_COMPILER, $(VCInstallDir)/bin for VS) +# -- Set the host compiler to be used by nvcc. Ignored if -ccbin or +# --compiler-bindir is already present in the CUDA_NVCC_FLAGS or +# CUDA_NVCC_FLAGS_ variables. For Visual Studio targets +# $(VCInstallDir)/bin is a special value that expands out to the path when +# the command is run from within VS. +# +# CUDA_NVCC_FLAGS +# CUDA_NVCC_FLAGS_ +# -- Additional NVCC command line arguments. NOTE: multiple arguments must be +# semi-colon delimited (e.g. --compiler-options;-Wall) +# +# CUDA_PROPAGATE_HOST_FLAGS (Default ON) +# -- Set to ON to propagate CMAKE_{C,CXX}_FLAGS and their configuration +# dependent counterparts (e.g. CMAKE_C_FLAGS_DEBUG) automatically to the +# host compiler through nvcc's -Xcompiler flag. This helps make the +# generated host code match the rest of the system better. Sometimes +# certain flags give nvcc problems, and this will help you turn the flag +# propagation off. This does not affect the flags supplied directly to nvcc +# via CUDA_NVCC_FLAGS or through the OPTION flags specified through +# CUDA_ADD_LIBRARY, CUDA_ADD_EXECUTABLE, or CUDA_WRAP_SRCS. Flags used for +# shared library compilation are not affected by this flag. +# +# CUDA_SEPARABLE_COMPILATION (Default OFF) +# -- If set this will enable separable compilation for all CUDA runtime object +# files. If used outside of CUDA_ADD_EXECUTABLE and CUDA_ADD_LIBRARY +# (e.g. calling CUDA_WRAP_SRCS directly), +# CUDA_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME and +# CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS should be called. +# +# CUDA_SOURCE_PROPERTY_FORMAT +# -- If this source file property is set, it can override the format specified +# to CUDA_WRAP_SRCS (OBJ, PTX, CUBIN, or FATBIN). If an input source file +# is not a .cu file, setting this file will cause it to be treated as a .cu +# file. See documentation for set_source_files_properties on how to set +# this property. +# +# CUDA_USE_STATIC_CUDA_RUNTIME (Default ON) +# -- When enabled the static version of the CUDA runtime library will be used +# in CUDA_LIBRARIES. If the version of CUDA configured doesn't support +# this option, then it will be silently disabled. +# +# CUDA_VERBOSE_BUILD (Default OFF) +# -- Set to ON to see all the commands used when building the CUDA file. When +# using a Makefile generator the value defaults to VERBOSE (run make +# VERBOSE=1 to see output), although setting CUDA_VERBOSE_BUILD to ON will +# always print the output. +# +# The script creates the following macros (in alphebetical order):: +# +# CUDA_ADD_CUFFT_TO_TARGET( cuda_target ) +# -- Adds the cufft library to the target (can be any target). Handles whether +# you are in emulation mode or not. +# +# CUDA_ADD_CUBLAS_TO_TARGET( cuda_target ) +# -- Adds the cublas library to the target (can be any target). Handles +# whether you are in emulation mode or not. +# +# CUDA_ADD_EXECUTABLE( cuda_target file0 file1 ... +# [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] [OPTIONS ...] ) +# -- Creates an executable "cuda_target" which is made up of the files +# specified. All of the non CUDA C files are compiled using the standard +# build rules specified by CMAKE and the cuda files are compiled to object +# files using nvcc and the host compiler. In addition CUDA_INCLUDE_DIRS is +# added automatically to include_directories(). Some standard CMake target +# calls can be used on the target after calling this macro +# (e.g. set_target_properties and target_link_libraries), but setting +# properties that adjust compilation flags will not affect code compiled by +# nvcc. Such flags should be modified before calling CUDA_ADD_EXECUTABLE, +# CUDA_ADD_LIBRARY or CUDA_WRAP_SRCS. +# +# CUDA_ADD_LIBRARY( cuda_target file0 file1 ... +# [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] [OPTIONS ...] ) +# -- Same as CUDA_ADD_EXECUTABLE except that a library is created. +# +# CUDA_BUILD_CLEAN_TARGET() +# -- Creates a convience target that deletes all the dependency files +# generated. You should make clean after running this target to ensure the +# dependency files get regenerated. +# +# CUDA_COMPILE( generated_files file0 file1 ... [STATIC | SHARED | MODULE] +# [OPTIONS ...] ) +# -- Returns a list of generated files from the input source files to be used +# with ADD_LIBRARY or ADD_EXECUTABLE. +# +# CUDA_COMPILE_PTX( generated_files file0 file1 ... [OPTIONS ...] ) +# -- Returns a list of PTX files generated from the input source files. +# +# CUDA_COMPILE_FATBIN( generated_files file0 file1 ... [OPTIONS ...] ) +# -- Returns a list of FATBIN files generated from the input source files. +# +# CUDA_COMPILE_CUBIN( generated_files file0 file1 ... [OPTIONS ...] ) +# -- Returns a list of CUBIN files generated from the input source files. +# +# CUDA_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME( output_file_var +# cuda_target +# object_files ) +# -- Compute the name of the intermediate link file used for separable +# compilation. This file name is typically passed into +# CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS. output_file_var is produced +# based on cuda_target the list of objects files that need separable +# compilation as specified by object_files. If the object_files list is +# empty, then output_file_var will be empty. This function is called +# automatically for CUDA_ADD_LIBRARY and CUDA_ADD_EXECUTABLE. Note that +# this is a function and not a macro. +# +# CUDA_INCLUDE_DIRECTORIES( path0 path1 ... ) +# -- Sets the directories that should be passed to nvcc +# (e.g. nvcc -Ipath0 -Ipath1 ... ). These paths usually contain other .cu +# files. +# +# +# CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS( output_file_var cuda_target +# nvcc_flags object_files) +# -- Generates the link object required by separable compilation from the given +# object files. This is called automatically for CUDA_ADD_EXECUTABLE and +# CUDA_ADD_LIBRARY, but can be called manually when using CUDA_WRAP_SRCS +# directly. When called from CUDA_ADD_LIBRARY or CUDA_ADD_EXECUTABLE the +# nvcc_flags passed in are the same as the flags passed in via the OPTIONS +# argument. The only nvcc flag added automatically is the bitness flag as +# specified by CUDA_64_BIT_DEVICE_CODE. Note that this is a function +# instead of a macro. +# +# CUDA_SELECT_NVCC_ARCH_FLAGS(out_variable [target_CUDA_architectures]) +# -- Selects GPU arch flags for nvcc based on target_CUDA_architectures +# target_CUDA_architectures : Auto | Common | All | LIST(ARCH_AND_PTX ...) +# - "Auto" detects local machine GPU compute arch at runtime. +# - "Common" and "All" cover common and entire subsets of architectures +# ARCH_AND_PTX : NAME | NUM.NUM | NUM.NUM(NUM.NUM) | NUM.NUM+PTX +# NAME: Fermi Kepler Maxwell Kepler+Tegra Kepler+Tesla Maxwell+Tegra Pascal +# NUM: Any number. Only those pairs are currently accepted by NVCC though: +# 2.0 2.1 3.0 3.2 3.5 3.7 5.0 5.2 5.3 6.0 6.2 +# Returns LIST of flags to be added to CUDA_NVCC_FLAGS in ${out_variable} +# Additionally, sets ${out_variable}_readable to the resulting numeric list +# Example: +# CUDA_SELECT_NVCC_ARCH_FLAGS(ARCH_FLAGS 3.0 3.5+PTX 5.2(5.0) Maxwell) +# LIST(APPEND CUDA_NVCC_FLAGS ${ARCH_FLAGS}) +# +# More info on CUDA architectures: https://en.wikipedia.org/wiki/CUDA +# Note that this is a function instead of a macro. +# +# CUDA_WRAP_SRCS ( cuda_target format generated_files file0 file1 ... +# [STATIC | SHARED | MODULE] [OPTIONS ...] ) +# -- This is where all the magic happens. CUDA_ADD_EXECUTABLE, +# CUDA_ADD_LIBRARY, CUDA_COMPILE, and CUDA_COMPILE_PTX all call this +# function under the hood. +# +# Given the list of files (file0 file1 ... fileN) this macro generates +# custom commands that generate either PTX or linkable objects (use "PTX" or +# "OBJ" for the format argument to switch). Files that don't end with .cu +# or have the HEADER_FILE_ONLY property are ignored. +# +# The arguments passed in after OPTIONS are extra command line options to +# give to nvcc. You can also specify per configuration options by +# specifying the name of the configuration followed by the options. General +# options must precede configuration specific options. Not all +# configurations need to be specified, only the ones provided will be used. +# +# OPTIONS -DFLAG=2 "-DFLAG_OTHER=space in flag" +# DEBUG -g +# RELEASE --use_fast_math +# RELWITHDEBINFO --use_fast_math;-g +# MINSIZEREL --use_fast_math +# +# For certain configurations (namely VS generating object files with +# CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE set to ON), no generated file will +# be produced for the given cuda file. This is because when you add the +# cuda file to Visual Studio it knows that this file produces an object file +# and will link in the resulting object file automatically. +# +# This script will also generate a separate cmake script that is used at +# build time to invoke nvcc. This is for several reasons. +# +# 1. nvcc can return negative numbers as return values which confuses +# Visual Studio into thinking that the command succeeded. The script now +# checks the error codes and produces errors when there was a problem. +# +# 2. nvcc has been known to not delete incomplete results when it +# encounters problems. This confuses build systems into thinking the +# target was generated when in fact an unusable file exists. The script +# now deletes the output files if there was an error. +# +# 3. By putting all the options that affect the build into a file and then +# make the build rule dependent on the file, the output files will be +# regenerated when the options change. +# +# This script also looks at optional arguments STATIC, SHARED, or MODULE to +# determine when to target the object compilation for a shared library. +# BUILD_SHARED_LIBS is ignored in CUDA_WRAP_SRCS, but it is respected in +# CUDA_ADD_LIBRARY. On some systems special flags are added for building +# objects intended for shared libraries. A preprocessor macro, +# _EXPORTS is defined when a shared library compilation is +# detected. +# +# Flags passed into add_definitions with -D or /D are passed along to nvcc. +# +# +# +# The script defines the following variables:: +# +# CUDA_VERSION_MAJOR -- The major version of cuda as reported by nvcc. +# CUDA_VERSION_MINOR -- The minor version. +# CUDA_VERSION +# CUDA_VERSION_STRING -- CUDA_VERSION_MAJOR.CUDA_VERSION_MINOR +# CUDA_HAS_FP16 -- Whether a short float (float16,fp16) is supported. +# +# CUDA_TOOLKIT_ROOT_DIR -- Path to the CUDA Toolkit (defined if not set). +# CUDA_SDK_ROOT_DIR -- Path to the CUDA SDK. Use this to find files in the +# SDK. This script will not directly support finding +# specific libraries or headers, as that isn't +# supported by NVIDIA. If you want to change +# libraries when the path changes see the +# FindCUDA.cmake script for an example of how to clear +# these variables. There are also examples of how to +# use the CUDA_SDK_ROOT_DIR to locate headers or +# libraries, if you so choose (at your own risk). +# CUDA_INCLUDE_DIRS -- Include directory for cuda headers. Added automatically +# for CUDA_ADD_EXECUTABLE and CUDA_ADD_LIBRARY. +# CUDA_LIBRARIES -- Cuda RT library. +# CUDA_CUFFT_LIBRARIES -- Device or emulation library for the Cuda FFT +# implementation (alternative to: +# CUDA_ADD_CUFFT_TO_TARGET macro) +# CUDA_CUBLAS_LIBRARIES -- Device or emulation library for the Cuda BLAS +# implementation (alternative to: +# CUDA_ADD_CUBLAS_TO_TARGET macro). +# CUDA_cudart_static_LIBRARY -- Statically linkable cuda runtime library. +# Only available for CUDA version 5.5+ +# CUDA_cudadevrt_LIBRARY -- Device runtime library. +# Required for separable compilation. +# CUDA_cupti_LIBRARY -- CUDA Profiling Tools Interface library. +# Only available for CUDA version 4.0+. +# CUDA_curand_LIBRARY -- CUDA Random Number Generation library. +# Only available for CUDA version 3.2+. +# CUDA_cusolver_LIBRARY -- CUDA Direct Solver library. +# Only available for CUDA version 7.0+. +# CUDA_cusparse_LIBRARY -- CUDA Sparse Matrix library. +# Only available for CUDA version 3.2+. +# CUDA_npp_LIBRARY -- NVIDIA Performance Primitives lib. +# Only available for CUDA version 4.0+. +# CUDA_nppc_LIBRARY -- NVIDIA Performance Primitives lib (core). +# Only available for CUDA version 5.5+. +# CUDA_nppi_LIBRARY -- NVIDIA Performance Primitives lib (image processing). +# Only available for CUDA version 5.5+. +# CUDA_npps_LIBRARY -- NVIDIA Performance Primitives lib (signal processing). +# Only available for CUDA version 5.5+. +# CUDA_nvcuvenc_LIBRARY -- CUDA Video Encoder library. +# Only available for CUDA version 3.2+. +# Windows only. +# CUDA_nvcuvid_LIBRARY -- CUDA Video Decoder library. +# Only available for CUDA version 3.2+. +# Windows only. +# + +# James Bigler, NVIDIA Corp (nvidia.com - jbigler) +# Abe Stephens, SCI Institute -- http://www.sci.utah.edu/~abe/FindCuda.html +# +# Copyright (c) 2008 - 2009 NVIDIA Corporation. All rights reserved. +# +# Copyright (c) 2007-2009 +# Scientific Computing and Imaging Institute, University of Utah +# +# This code is licensed under the MIT License. See the FindCUDA.cmake script +# for the text of the license. + +# The MIT License +# +# License for the specific language governing rights and limitations under +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +############################################################################### + +# FindCUDA.cmake + +#if HIP was enabled, use HIP path +if(HIP) + set(CUDA_TOOLKIT_ROOT_DIR ${HIP_TOOLKIT_ROOT_DIR}) +endif() +# This macro helps us find the location of helper files we will need the full path to +macro(CUDA_FIND_HELPER_FILE _name _extension) + set(_full_name "${_name}.${_extension}") + # CMAKE_CURRENT_LIST_FILE contains the full path to the file currently being + # processed. Using this variable, we can pull out the current path, and + # provide a way to get access to the other files we need local to here. + get_filename_component(CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) + set(CUDA_${_name} "${CMAKE_CURRENT_LIST_DIR}/FindCUDA/${_full_name}") + if(NOT EXISTS "${CUDA_${_name}}") + set(error_message "${_full_name} not found in ${CMAKE_CURRENT_LIST_DIR}/FindCUDA") + if(CUDA_FIND_REQUIRED) + message(FATAL_ERROR "${error_message}") + else() + if(NOT CUDA_FIND_QUIETLY) + message(STATUS "${error_message}") + endif() + endif() + endif() + # Set this variable as internal, so the user isn't bugged with it. + set(CUDA_${_name} ${CUDA_${_name}} CACHE INTERNAL "Location of ${_full_name}" FORCE) +endmacro() + +##################################################################### +## CUDA_INCLUDE_NVCC_DEPENDENCIES +## + +# So we want to try and include the dependency file if it exists. If +# it doesn't exist then we need to create an empty one, so we can +# include it. + +# If it does exist, then we need to check to see if all the files it +# depends on exist. If they don't then we should clear the dependency +# file and regenerate it later. This covers the case where a header +# file has disappeared or moved. + +macro(CUDA_INCLUDE_NVCC_DEPENDENCIES dependency_file) + set(CUDA_NVCC_DEPEND) + set(CUDA_NVCC_DEPEND_REGENERATE FALSE) + + + # Include the dependency file. Create it first if it doesn't exist . The + # INCLUDE puts a dependency that will force CMake to rerun and bring in the + # new info when it changes. DO NOT REMOVE THIS (as I did and spent a few + # hours figuring out why it didn't work. + if(NOT EXISTS ${dependency_file}) + file(WRITE ${dependency_file} "#FindHipCUDA.cmake generated file. Do not edit.\n") + endif() + # Always include this file to force CMake to run again next + # invocation and rebuild the dependencies. + #message("including dependency_file = ${dependency_file}") + include(${dependency_file}) + + # Now we need to verify the existence of all the included files + # here. If they aren't there we need to just blank this variable and + # make the file regenerate again. +# if(DEFINED CUDA_NVCC_DEPEND) +# message("CUDA_NVCC_DEPEND set") +# else() +# message("CUDA_NVCC_DEPEND NOT set") +# endif() + if(CUDA_NVCC_DEPEND) + #message("CUDA_NVCC_DEPEND found") + foreach(f ${CUDA_NVCC_DEPEND}) + # message("searching for ${f}") + if(NOT EXISTS ${f}) + #message("file ${f} not found") + set(CUDA_NVCC_DEPEND_REGENERATE TRUE) + endif() + endforeach() + else() + #message("CUDA_NVCC_DEPEND false") + # No dependencies, so regenerate the file. + set(CUDA_NVCC_DEPEND_REGENERATE TRUE) + endif() + + #message("CUDA_NVCC_DEPEND_REGENERATE = ${CUDA_NVCC_DEPEND_REGENERATE}") + # No incoming dependencies, so we need to generate them. Make the + # output depend on the dependency file itself, which should cause the + # rule to re-run. + if(CUDA_NVCC_DEPEND_REGENERATE) + set(CUDA_NVCC_DEPEND ${dependency_file}) + #message("Generating an empty dependency_file: ${dependency_file}") + file(WRITE ${dependency_file} "#FindHipCUDA.cmake generated file. Do not edit.\n") + endif() + +endmacro() + +############################################################################### +############################################################################### +# Setup variables' defaults +############################################################################### +############################################################################### + +# Allow the user to specify if the device code is supposed to be 32 or 64 bit. +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(CUDA_64_BIT_DEVICE_CODE_DEFAULT ON) +else() + set(CUDA_64_BIT_DEVICE_CODE_DEFAULT OFF) +endif() +option(CUDA_64_BIT_DEVICE_CODE "Compile device code in 64 bit mode" ${CUDA_64_BIT_DEVICE_CODE_DEFAULT}) + +# Attach the build rule to the source file in VS. This option +option(CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE "Attach the build rule to the CUDA source file. Enable only when the CUDA source file is added to at most one target." ON) + +# Prints out extra information about the cuda file during compilation +option(CUDA_BUILD_CUBIN "Generate and parse .cubin files in Device mode." OFF) + +# Set whether we are using emulation or device mode. +option(CUDA_BUILD_EMULATION "Build in Emulation mode" OFF) + +# Where to put the generated output. +set(CUDA_GENERATED_OUTPUT_DIR "" CACHE PATH "Directory to put all the output files. If blank it will default to the CMAKE_CURRENT_BINARY_DIR") + +# Parse HOST_COMPILATION mode. +option(CUDA_HOST_COMPILATION_CPP "Generated file extension" ON) + +# Extra user settable flags +set(CUDA_NVCC_FLAGS "" CACHE STRING "Semi-colon delimit multiple arguments.") + +if(CMAKE_GENERATOR MATCHES "Visual Studio") + set(CUDA_HOST_COMPILER "$(VCInstallDir)bin" CACHE FILEPATH "Host side compiler used by NVCC") +else() + if(APPLE + AND "${CMAKE_C_COMPILER_ID}" MATCHES "Clang" + AND "${CMAKE_C_COMPILER}" MATCHES "/cc$") + # Using cc which is symlink to clang may let NVCC think it is GCC and issue + # unhandled -dumpspecs option to clang. Also in case neither + # CMAKE_C_COMPILER is defined (project does not use C language) nor + # CUDA_HOST_COMPILER is specified manually we should skip -ccbin and let + # nvcc use its own default C compiler. + # Only care about this on APPLE with clang to avoid + # following symlinks to things like ccache + if(DEFINED CMAKE_C_COMPILER AND NOT DEFINED CUDA_HOST_COMPILER) + get_filename_component(c_compiler_realpath "${CMAKE_C_COMPILER}" REALPATH) + # if the real path does not end up being clang then + # go back to using CMAKE_C_COMPILER + if(NOT "${c_compiler_realpath}" MATCHES "/clang$") + set(c_compiler_realpath "${CMAKE_C_COMPILER}") + endif() + else() + set(c_compiler_realpath "") + endif() + set(CUDA_HOST_COMPILER "${c_compiler_realpath}" CACHE FILEPATH "Host side compiler used by NVCC") + else() + set(CUDA_HOST_COMPILER "${CMAKE_C_COMPILER}" + CACHE FILEPATH "Host side compiler used by NVCC") + endif() +endif() + +# Propagate the host flags to the host compiler via -Xcompiler +option(CUDA_PROPAGATE_HOST_FLAGS "Propage C/CXX_FLAGS and friends to the host compiler via -Xcompile" ON) + +# Enable CUDA_SEPARABLE_COMPILATION +option(CUDA_SEPARABLE_COMPILATION "Compile CUDA objects with separable compilation enabled. Requires CUDA 5.0+" OFF) + +# Specifies whether the commands used when compiling the .cu file will be printed out. +option(CUDA_VERBOSE_BUILD "Print out the commands run while compiling the CUDA source file. With the Makefile generator this defaults to VERBOSE variable specified on the command line, but can be forced on with this option." OFF) + +mark_as_advanced( + CUDA_64_BIT_DEVICE_CODE + CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE + CUDA_GENERATED_OUTPUT_DIR + CUDA_HOST_COMPILATION_CPP + CUDA_NVCC_FLAGS + CUDA_PROPAGATE_HOST_FLAGS + CUDA_BUILD_CUBIN + CUDA_BUILD_EMULATION + CUDA_VERBOSE_BUILD + CUDA_SEPARABLE_COMPILATION + ) + +# Makefile and similar generators don't define CMAKE_CONFIGURATION_TYPES, so we +# need to add another entry for the CMAKE_BUILD_TYPE. We also need to add the +# standerd set of 4 build types (Debug, MinSizeRel, Release, and RelWithDebInfo) +# for completeness. We need run this loop in order to accomodate the addition +# of extra configuration types. Duplicate entries will be removed by +# REMOVE_DUPLICATES. +set(CUDA_configuration_types ${CMAKE_CONFIGURATION_TYPES} ${CMAKE_BUILD_TYPE} Debug MinSizeRel Release RelWithDebInfo) +list(REMOVE_DUPLICATES CUDA_configuration_types) +foreach(config ${CUDA_configuration_types}) + string(TOUPPER ${config} config_upper) + set(CUDA_NVCC_FLAGS_${config_upper} "" CACHE STRING "Semi-colon delimit multiple arguments.") + mark_as_advanced(CUDA_NVCC_FLAGS_${config_upper}) +endforeach() + +############################################################################### +############################################################################### +# Locate CUDA, Set Build Type, etc. +############################################################################### +############################################################################### + +macro(cuda_unset_include_and_libraries) + unset(CUDA_TOOLKIT_INCLUDE CACHE) + unset(CUDA_CUDART_LIBRARY CACHE) + unset(CUDA_CUDA_LIBRARY CACHE) + # Make sure you run this before you unset CUDA_VERSION. + if(CUDA_VERSION VERSION_EQUAL "3.0") + # This only existed in the 3.0 version of the CUDA toolkit + unset(CUDA_CUDARTEMU_LIBRARY CACHE) + endif() + unset(CUDA_cudart_static_LIBRARY CACHE) + unset(CUDA_cudadevrt_LIBRARY CACHE) + unset(CUDA_cublas_LIBRARY CACHE) + unset(CUDA_cublas_device_LIBRARY CACHE) + unset(CUDA_cublasemu_LIBRARY CACHE) + unset(CUDA_cufft_LIBRARY CACHE) + unset(CUDA_cufftemu_LIBRARY CACHE) + unset(CUDA_cupti_LIBRARY CACHE) + unset(CUDA_curand_LIBRARY CACHE) + unset(CUDA_cusolver_LIBRARY CACHE) + unset(CUDA_cusparse_LIBRARY CACHE) + unset(CUDA_npp_LIBRARY CACHE) + unset(CUDA_nppc_LIBRARY CACHE) + unset(CUDA_nppi_LIBRARY CACHE) + unset(CUDA_npps_LIBRARY CACHE) + unset(CUDA_nvcuvenc_LIBRARY CACHE) + unset(CUDA_nvcuvid_LIBRARY CACHE) + unset(CUDA_USE_STATIC_CUDA_RUNTIME CACHE) + unset(CUDA_GPU_DETECT_OUTPUT CACHE) +endmacro() + +# Check to see if the CUDA_TOOLKIT_ROOT_DIR and CUDA_SDK_ROOT_DIR have changed, +# if they have then clear the cache variables, so that will be detected again. +if(NOT "${CUDA_TOOLKIT_ROOT_DIR}" STREQUAL "${CUDA_TOOLKIT_ROOT_DIR_INTERNAL}") + unset(CUDA_TOOLKIT_TARGET_DIR CACHE) + unset(CUDA_NVCC_EXECUTABLE CACHE) + cuda_unset_include_and_libraries() + unset(CUDA_VERSION CACHE) +endif() + +if(NOT "${CUDA_TOOLKIT_TARGET_DIR}" STREQUAL "${CUDA_TOOLKIT_TARGET_DIR_INTERNAL}") + cuda_unset_include_and_libraries() +endif() + +# +# End of unset() +# + +# +# Start looking for things +# + +# Search for the cuda distribution. +if(NOT CUDA_TOOLKIT_ROOT_DIR AND NOT CMAKE_CROSSCOMPILING) + # Search in the CUDA_BIN_PATH first. + find_path(CUDA_TOOLKIT_ROOT_DIR + NAMES hipcc hipcc.exe + PATHS + ENV CUDA_TOOLKIT_ROOT + ENV CUDA_PATH + ENV CUDA_BIN_PATH + ENV HIP_HOME + PATH_SUFFIXES bin bin64 + DOC "Toolkit location." + NO_DEFAULT_PATH + ) + + # Now search default paths + find_path(CUDA_TOOLKIT_ROOT_DIR + NAMES nvcc nvcc.exe + PATHS /opt/cuda/bin + /usr/local/bin + /usr/local/cuda/bin + DOC "Toolkit location." + ) + + if (CUDA_TOOLKIT_ROOT_DIR) + string(REGEX REPLACE "[/\\\\]?bin[64]*[/\\\\]?$" "" CUDA_TOOLKIT_ROOT_DIR ${CUDA_TOOLKIT_ROOT_DIR}) + # We need to force this back into the cache. + set(CUDA_TOOLKIT_ROOT_DIR ${CUDA_TOOLKIT_ROOT_DIR} CACHE PATH "Toolkit location." FORCE) + set(CUDA_TOOLKIT_TARGET_DIR ${CUDA_TOOLKIT_ROOT_DIR}) + endif() + + if (NOT EXISTS ${CUDA_TOOLKIT_ROOT_DIR}) + if(CUDA_FIND_REQUIRED) + message(FATAL_ERROR "Specify CUDA_TOOLKIT_ROOT_DIR") + elseif(NOT CUDA_FIND_QUIETLY) + message("CUDA_TOOLKIT_ROOT_DIR not found or specified") + endif() + endif () +endif () + +if(CMAKE_CROSSCOMPILING) + SET (CUDA_TOOLKIT_ROOT $ENV{CUDA_TOOLKIT_ROOT}) + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7-a") + # Support for NVPACK + set (CUDA_TOOLKIT_TARGET_NAME "armv7-linux-androideabi") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm") + # Support for arm cross compilation + set(CUDA_TOOLKIT_TARGET_NAME "armv7-linux-gnueabihf") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") + # Support for aarch64 cross compilation + if (ANDROID_ARCH_NAME STREQUAL "arm64") + set(CUDA_TOOLKIT_TARGET_NAME "aarch64-linux-androideabi") + else() + set(CUDA_TOOLKIT_TARGET_NAME "aarch64-linux") + endif (ANDROID_ARCH_NAME STREQUAL "arm64") + endif() + + if (EXISTS "${CUDA_TOOLKIT_ROOT}/targets/${CUDA_TOOLKIT_TARGET_NAME}") + set(CUDA_TOOLKIT_TARGET_DIR "${CUDA_TOOLKIT_ROOT}/targets/${CUDA_TOOLKIT_TARGET_NAME}" CACHE PATH "CUDA Toolkit target location.") + SET (CUDA_TOOLKIT_ROOT_DIR ${CUDA_TOOLKIT_ROOT}) + mark_as_advanced(CUDA_TOOLKIT_TARGET_DIR) + endif() + + # add known CUDA targetr root path to the set of directories we search for programs, libraries and headers + set( CMAKE_FIND_ROOT_PATH "${CUDA_TOOLKIT_TARGET_DIR};${CMAKE_FIND_ROOT_PATH}") + macro( cuda_find_host_program ) + find_host_program( ${ARGN} ) + endmacro() +else() + # for non-cross-compile, find_host_program == find_program and CUDA_TOOLKIT_TARGET_DIR == CUDA_TOOLKIT_ROOT_DIR + macro( cuda_find_host_program ) + find_program( ${ARGN} ) + endmacro() + SET (CUDA_TOOLKIT_TARGET_DIR ${CUDA_TOOLKIT_ROOT_DIR}) +endif() + + +# CUDA_NVCC_EXECUTABLE +cuda_find_host_program(CUDA_NVCC_EXECUTABLE + NAMES hipcc + PATHS "${CUDA_TOOLKIT_ROOT_DIR}" + ENV CUDA_PATH + ENV CUDA_BIN_PATH + PATH_SUFFIXES bin bin64 + NO_DEFAULT_PATH + ) +# Search default search paths, after we search our own set of paths. +cuda_find_host_program(CUDA_NVCC_EXECUTABLE hipcc) +mark_as_advanced(CUDA_NVCC_EXECUTABLE) + +if(CUDA_NVCC_EXECUTABLE AND NOT CUDA_VERSION) + # Compute the version. + string(REGEX REPLACE "([0-9]+)\\.([0-9]+).*" "\\1" CUDA_VERSION_MAJOR ${HIPCUDA_EMULATE_VERSION}) + string(REGEX REPLACE "([0-9]+)\\.([0-9]+).*" "\\2" CUDA_VERSION_MINOR ${HIPCUDA_EMULATE_VERSION}) + set(CUDA_VERSION "${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR}" CACHE STRING "Version of CUDA emulation as requested by the user.") + mark_as_advanced(CUDA_VERSION) +else() + # Need to set these based off of the cached value + string(REGEX REPLACE "([0-9]+)\\.([0-9]+).*" "\\1" CUDA_VERSION_MAJOR "${CUDA_VERSION}") + string(REGEX REPLACE "([0-9]+)\\.([0-9]+).*" "\\2" CUDA_VERSION_MINOR "${CUDA_VERSION}") +endif() + + +# Always set this convenience variable +set(CUDA_VERSION_STRING "${CUDA_VERSION}") + +# CUDA_TOOLKIT_INCLUDE +find_path(CUDA_TOOLKIT_INCLUDE + hip_version.h # Header included in toolkit + PATHS ${CUDA_TOOLKIT_ROOT_DIR} + ENV CUDA_PATH + ENV CUDA_INC_PATH + PATH_SUFFIXES include/hip + NO_DEFAULT_PATH + ) +# Search default search paths, after we search our own set of paths. +find_path(CUDA_TOOLKIT_INCLUDE hip_version.h) +mark_as_advanced(CUDA_TOOLKIT_INCLUDE) + +if (EXISTS "${CUDA_TOOLKIT_INCLUDE}/hip_fp16.h") + set(CUDA_HAS_FP16 TRUE) +else() + set(CUDA_HAS_FP16 FALSE) +endif() + +# Set the user list of include dir to nothing to initialize it. +set (CUDA_NVCC_INCLUDE_DIRS_USER "") +set (CUDA_INCLUDE_DIRS ${CUDA_TOOLKIT_INCLUDE}) + +macro(cuda_find_library_local_first_with_path_ext _var _names _doc _path_ext ) + find_library(${_var} + NAMES ${_names} + PATHS "${CUDA_TOOLKIT_TARGET_DIR}" + ENV CUDA_PATH + ENV CUDA_LIB_PATH + PATH_SUFFIXES ${_cuda_64bit_lib_dir} "${_path_ext}lib/Win32" "${_path_ext}lib" "${_path_ext}libWin32" + DOC ${_doc} + NO_DEFAULT_PATH + ) + if (NOT CMAKE_CROSSCOMPILING) + # Search default search paths, after we search our own set of paths. + find_library(${_var} + NAMES ${_names} + PATHS "/opt/rocm/lib" + DOC ${_doc} + ) + endif() +endmacro() + +macro(cuda_find_library_local_first _var _names _doc) + cuda_find_library_local_first_with_path_ext( "${_var}" "${_names}" "${_doc}" "" ) +endmacro() + +macro(find_library_local_first _var _names _doc ) + cuda_find_library_local_first( "${_var}" "${_names}" "${_doc}" "" ) +endmacro() + + +# CUDA_LIBRARIES +cuda_find_library_local_first(CUDA_CUDART_LIBRARY amdhip64 "\"cudart\" library") + + +if(CUDA_cudart_static_LIBRARY) + # If static cudart available, use it by default, but provide a user-visible option to disable it. + option(CUDA_USE_STATIC_CUDA_RUNTIME "Use the static version of the CUDA runtime library if available" ON) + set(CUDA_CUDART_LIBRARY_VAR CUDA_cudart_static_LIBRARY) +else() + # If not available, silently disable the option. + set(CUDA_USE_STATIC_CUDA_RUNTIME OFF CACHE INTERNAL "") + set(CUDA_CUDART_LIBRARY_VAR CUDA_CUDART_LIBRARY) +endif() + +if(CUDA_USE_STATIC_CUDA_RUNTIME) + if(UNIX) + # Check for the dependent libraries. Here we look for pthreads. + if (DEFINED CMAKE_THREAD_PREFER_PTHREAD) + set(_cuda_cmake_thread_prefer_pthread ${CMAKE_THREAD_PREFER_PTHREAD}) + endif() + set(CMAKE_THREAD_PREFER_PTHREAD 1) + + # Many of the FindXYZ CMake comes with makes use of try_compile with int main(){return 0;} + # as the source file. Unfortunately this causes a warning with -Wstrict-prototypes and + # -Werror causes the try_compile to fail. We will just temporarily disable other flags + # when doing the find_package command here. + set(_cuda_cmake_c_flags ${CMAKE_C_FLAGS}) + set(CMAKE_C_FLAGS "-fPIC") + find_package(Threads REQUIRED) + set(CMAKE_C_FLAGS ${_cuda_cmake_c_flags}) + + if (DEFINED _cuda_cmake_thread_prefer_pthread) + set(CMAKE_THREAD_PREFER_PTHREAD ${_cuda_cmake_thread_prefer_pthread}) + unset(_cuda_cmake_thread_prefer_pthread) + else() + unset(CMAKE_THREAD_PREFER_PTHREAD) + endif() + + if(NOT APPLE) + #On Linux, you must link against librt when using the static cuda runtime. + find_library(CUDA_rt_LIBRARY rt) + if (NOT CUDA_rt_LIBRARY) + message(WARNING "Expecting to find librt for libcudart_static, but didn't find it.") + endif() + endif() + endif() +endif() + +# CUPTI library showed up in cuda toolkit 4.0 +if(NOT CUDA_VERSION VERSION_LESS "4.0") + cuda_find_library_local_first_with_path_ext(CUDA_cupti_LIBRARY cupti "\"cupti\" library" "extras/CUPTI/") + mark_as_advanced(CUDA_cupti_LIBRARY) +endif() + +# Set the CUDA_LIBRARIES variable. This is the set of stuff to link against if you are +# using the CUDA runtime. For the dynamic version of the runtime, most of the +# dependencies are brough in, but for the static version there are additional libraries +# and linker commands needed. +# Initialize to empty +set(CUDA_LIBRARIES) + +# If we are using emulation mode and we found the cudartemu library then use +# that one instead of cudart. +if(CUDA_BUILD_EMULATION AND CUDA_CUDARTEMU_LIBRARY) + list(APPEND CUDA_LIBRARIES ${CUDA_CUDARTEMU_LIBRARY}) +elseif(CUDA_USE_STATIC_CUDA_RUNTIME AND CUDA_cudart_static_LIBRARY) + list(APPEND CUDA_LIBRARIES ${CUDA_cudart_static_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS}) + if (CUDA_rt_LIBRARY) + list(APPEND CUDA_LIBRARIES ${CUDA_rt_LIBRARY}) + endif() + if(APPLE) + # We need to add the default path to the driver (libcuda.dylib) as an rpath, so that + # the static cuda runtime can find it at runtime. + list(APPEND CUDA_LIBRARIES -Wl,-rpath,/usr/local/cuda/lib) + endif() +else() + list(APPEND CUDA_LIBRARIES ${CUDA_CUDART_LIBRARY}) +endif() + +# 1.1 toolkit on linux doesn't appear to have a separate library on +# some platforms. +cuda_find_library_local_first(CUDA_CUDA_LIBRARY cuda "\"cuda\" library (older versions only).") + +mark_as_advanced( + CUDA_CUDA_LIBRARY + CUDA_CUDART_LIBRARY + ) + +####################### +# Look for some of the toolkit helper libraries +#macro(FIND_CUDA_HELPER_LIBS _name) +# if(_name MATCHES "(fft|rand)") +# string(REGEX REPLACE "^(cu)" "roc" _hipname ${_name}) +# string(REGEX REPLACE "_" "-" _hipname ${_hipname}) +# else() +# string(REGEX REPLACE "^(cu)" "hip" _hipname ${_name}) +# endif() +# cuda_find_library_local_first(CUDA_${_name}_LIBRARY ${_hipname} "\"${_name}\" library") +# mark_as_advanced(CUDA_${_name}_LIBRARY) +#endmacro() + +####################### +# Disable emulation for v3.1 onward +if(CUDA_VERSION VERSION_GREATER "3.0") + if(CUDA_BUILD_EMULATION) + message(FATAL_ERROR "CUDA_BUILD_EMULATION is not supported in version 3.1 and onwards. You must disable it to proceed. You have version ${CUDA_VERSION}.") + endif() +endif() + +list(APPEND CMAKE_PREFIX_PATH ${CUDA_TOOLKIT_ROOT_DIR}) + +# Set a default build type if none was specified +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to 'Release' as none was specified.") + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "" "Debug" "Release" "MinSizeRel" "RelWithDebInfo") +endif() + +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE CACHE BOOL "Add paths to linker search and installed rpath") + +# Use target ID syntax if supported for AMDGPU_TARGETS +if(TARGET_ID_SUPPORT) + set(AMDGPU_TARGETS gfx803;gfx900:xnack-;gfx906:xnack-;gfx908:xnack- CACHE STRING "List of specific machine types for library to target") +else() + set(AMDGPU_TARGETS gfx803;gfx900;gfx906;gfx908 CACHE STRING "List of specific machine types for library to target") +endif() +set(AMDGPU_TEST_TARGETS "" CACHE STRING "List of specific device types to test for") # Leave empty for default system device + +list(APPEND CMAKE_PREFIX_PATH /opt/rocm /opt/rocm/hip) +find_package(hip REQUIRED CONFIG PATHS /opt/rocm) + +foreach(_name IN ITEMS cufft cublas curand cusparse cusolver) + # Find the roc::rocLIB base library of all dependencies + string(REGEX REPLACE "^(cu)" "roc" _rocname ${_name}) + list(APPEND CMAKE_PREFIX_PATH ${CUDA_TOOLKIT_ROOT_DIR}/${_rocname}) + find_package(${_rocname}) + set(CUDA_${_name}_LIBRARY roc::${_rocname}) + if(TARGET roc::${_rocname}) + message(STATUS "Found ${_name} as roc::${_rocname}") + endif() + + # If HIP wrappers exist, append those + if(NOT _name MATCHES "(solver)") + string(REGEX REPLACE "^(cu)" "hip" _hipname ${_name}) + if(_name MATCHES "(fft|rand)") + set(_hipnamespace "hip") + else() + set(_hipnamespace "roc") + endif() + list(APPEND CMAKE_PREFIX_PATH ${CUDA_TOOLKIT_ROOT_DIR}/${_hipname}) + find_package(${_hipname}) + if(TARGET ${_hipnamespace}::${_hipname}) + message(STATUS "Adding ${_hipnamespace}::${_hipname} to ${_name}") + list(APPEND CUDA_${_name}_LIBRARY ${_hipnamespace}::${_hipname}) + # HIP-TODO: Includes the new hipFFT header so /opt/rocm/include/hipfft.h will not be + # included first and show `#warning The hipFFT version included in rocFFT is deprecated` + if(_name MATCHES "(fft)") + list(PREPEND CUDA_INCLUDE_DIRS ${HIPFFT_INCLUDE_DIR}) + endif() + list(PREPEND CUDA_INCLUDE_DIRS ${ROCM_PATH}/include/hipfft/) + list(PREPEND CUDA_INCLUDE_DIRS ${ROCM_PATH}/include/hipblas/) + list(PREPEND CUDA_INCLUDE_DIRS ${ROCM_PATH}/include/hipsparse/) + endif() + endif() + + # Add legacy uppercase variables + if(_name MATCHES "(fft|blas)") + string(TOUPPER ${_name} _uppername) + set(CUDA_${_uppername}_LIBRARIES ${CUDA_${_name}_LIBRARY}) + endif() +endforeach() + +# Add newer CUDA header-only libraries that didn't coexist with these scripts but may be picked up implicitly +find_package(hipcub) +if(TARGET hip::hipcub) + message(STATUS "Found hip::hipcub: adding to CUDA_INCLUDE_DIRS") + get_target_property(HIPCUB_INCLUDE_DIR hip::hipcub INTERFACE_INCLUDE_DIRECTORIES) + list(APPEND CUDA_INCLUDE_DIRS ${HIPCUB_INCLUDE_DIR}) +endif() + +find_package(rocthrust) +if(TARGET roc::rocthrust) + message(STATUS "Found roc::rocthrust: adding to CUDA_INCLUDE_DIRS") + get_target_property(ROCTHRUST_INCLUDE_DIR roc::rocthrust INTERFACE_INCLUDE_DIRECTORIES) + list(APPEND CUDA_INCLUDE_DIRS ${ROCTHRUST_INCLUDE_DIR}) +endif() + +######################## +# Look for the SDK stuff. As of CUDA 3.0 NVSDKCUDA_ROOT has been replaced with +# NVSDKCOMPUTE_ROOT with the old CUDA C contents moved into the C subdirectory +find_path(CUDA_SDK_ROOT_DIR common/inc/cutil.h + HINTS + "$ENV{NVSDKCOMPUTE_ROOT}/C" + ENV NVSDKCUDA_ROOT + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\NVIDIA Corporation\\Installed Products\\NVIDIA SDK 10\\Compute;InstallDir]" + PATHS + "/Developer/GPU\ Computing/C" + ) + +# Keep the CUDA_SDK_ROOT_DIR first in order to be able to override the +# environment variables. +set(CUDA_SDK_SEARCH_PATH + "${CUDA_SDK_ROOT_DIR}" + "${CUDA_TOOLKIT_ROOT_DIR}/local/NVSDK0.2" + "${CUDA_TOOLKIT_ROOT_DIR}/NVSDK0.2" + "${CUDA_TOOLKIT_ROOT_DIR}/NV_CUDA_SDK" + "$ENV{HOME}/NVIDIA_CUDA_SDK" + "$ENV{HOME}/NVIDIA_CUDA_SDK_MACOSX" + "/Developer/CUDA" + ) + +# Example of how to find an include file from the CUDA_SDK_ROOT_DIR + +# find_path(CUDA_CUT_INCLUDE_DIR +# cutil.h +# PATHS ${CUDA_SDK_SEARCH_PATH} +# PATH_SUFFIXES "common/inc" +# DOC "Location of cutil.h" +# NO_DEFAULT_PATH +# ) +# # Now search system paths +# find_path(CUDA_CUT_INCLUDE_DIR cutil.h DOC "Location of cutil.h") + +# mark_as_advanced(CUDA_CUT_INCLUDE_DIR) + + +# Example of how to find a library in the CUDA_SDK_ROOT_DIR + +# # cutil library is called cutil64 for 64 bit builds on windows. We don't want +# # to get these confused, so we are setting the name based on the word size of +# # the build. + +# if(CMAKE_SIZEOF_VOID_P EQUAL 8) +# set(cuda_cutil_name cutil64) +# else() +# set(cuda_cutil_name cutil32) +# endif() + +# find_library(CUDA_CUT_LIBRARY +# NAMES cutil ${cuda_cutil_name} +# PATHS ${CUDA_SDK_SEARCH_PATH} +# # The new version of the sdk shows up in common/lib, but the old one is in lib +# PATH_SUFFIXES "common/lib" "lib" +# DOC "Location of cutil library" +# NO_DEFAULT_PATH +# ) +# # Now search system paths +# find_library(CUDA_CUT_LIBRARY NAMES cutil ${cuda_cutil_name} DOC "Location of cutil library") +# mark_as_advanced(CUDA_CUT_LIBRARY) +# set(CUDA_CUT_LIBRARIES ${CUDA_CUT_LIBRARY}) + + + +############################# +# Check for required components +set(CUDA_FOUND TRUE) + +set(CUDA_TOOLKIT_ROOT_DIR_INTERNAL "${CUDA_TOOLKIT_ROOT_DIR}" CACHE INTERNAL + "This is the value of the last time CUDA_TOOLKIT_ROOT_DIR was set successfully." FORCE) +set(CUDA_TOOLKIT_TARGET_DIR_INTERNAL "${CUDA_TOOLKIT_TARGET_DIR}" CACHE INTERNAL + "This is the value of the last time CUDA_TOOLKIT_TARGET_DIR was set successfully." FORCE) +set(CUDA_SDK_ROOT_DIR_INTERNAL "${CUDA_SDK_ROOT_DIR}" CACHE INTERNAL + "This is the value of the last time CUDA_SDK_ROOT_DIR was set successfully." FORCE) + +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(CUDA + REQUIRED_VARS + CUDA_TOOLKIT_ROOT_DIR + CUDA_NVCC_EXECUTABLE + CUDA_INCLUDE_DIRS + ${CUDA_CUDART_LIBRARY_VAR} + VERSION_VAR + CUDA_VERSION + ) + + + +############################################################################### +############################################################################### +# Macros +############################################################################### +############################################################################### + +############################################################################### +# Add include directories to pass to the nvcc command. +macro(CUDA_INCLUDE_DIRECTORIES) + foreach(dir ${ARGN}) + list(APPEND CUDA_NVCC_INCLUDE_DIRS_USER ${dir}) + endforeach() +endmacro() + + +############################################################################## +cuda_find_helper_file(parse_cubin cmake) +cuda_find_helper_file(make2cmake cmake) +cuda_find_helper_file(run_nvcc cmake) +include("${CMAKE_CURRENT_LIST_DIR}/FindCUDA/select_compute_arch.cmake") + +############################################################################## +# Separate the OPTIONS out from the sources +# +macro(CUDA_GET_SOURCES_AND_OPTIONS _sources _cmake_options _options) + set( ${_sources} ) + set( ${_cmake_options} ) + set( ${_options} ) + set( _found_options FALSE ) + foreach(arg ${ARGN}) + if("x${arg}" STREQUAL "xOPTIONS") + set( _found_options TRUE ) + elseif( + "x${arg}" STREQUAL "xWIN32" OR + "x${arg}" STREQUAL "xMACOSX_BUNDLE" OR + "x${arg}" STREQUAL "xEXCLUDE_FROM_ALL" OR + "x${arg}" STREQUAL "xSTATIC" OR + "x${arg}" STREQUAL "xSHARED" OR + "x${arg}" STREQUAL "xMODULE" + ) + list(APPEND ${_cmake_options} ${arg}) + else() + if ( _found_options ) + list(APPEND ${_options} ${arg}) + else() + # Assume this is a file + list(APPEND ${_sources} ${arg}) + endif() + endif() + endforeach() +endmacro() + +############################################################################## +# Parse the OPTIONS from ARGN and set the variables prefixed by _option_prefix +# +macro(CUDA_PARSE_NVCC_OPTIONS _option_prefix) + set( _found_config ) + foreach(arg ${ARGN}) + # Determine if we are dealing with a perconfiguration flag + foreach(config ${CUDA_configuration_types}) + string(TOUPPER ${config} config_upper) + if (arg STREQUAL "${config_upper}") + set( _found_config _${arg}) + # Set arg to nothing to keep it from being processed further + set( arg ) + endif() + endforeach() + + if ( arg ) + list(APPEND ${_option_prefix}${_found_config} "${arg}") + endif() + endforeach() +endmacro() + +############################################################################## +# Helper to add the include directory for CUDA only once +function(CUDA_ADD_CUDA_INCLUDE_ONCE) + get_directory_property(_include_directories INCLUDE_DIRECTORIES) + set(_add TRUE) + if(_include_directories) + foreach(dir ${_include_directories}) + if("${dir}" STREQUAL "${CUDA_INCLUDE_DIRS}") + set(_add FALSE) + endif() + endforeach() + endif() + if(_add) + include_directories(${CUDA_INCLUDE_DIRS}) + endif() +endfunction() + +function(CUDA_BUILD_SHARED_LIBRARY shared_flag) + set(cmake_args ${ARGN}) + # If SHARED, MODULE, or STATIC aren't already in the list of arguments, then + # add SHARED or STATIC based on the value of BUILD_SHARED_LIBS. + list(FIND cmake_args SHARED _cuda_found_SHARED) + list(FIND cmake_args MODULE _cuda_found_MODULE) + list(FIND cmake_args STATIC _cuda_found_STATIC) + if( _cuda_found_SHARED GREATER -1 OR + _cuda_found_MODULE GREATER -1 OR + _cuda_found_STATIC GREATER -1) + set(_cuda_build_shared_libs) + else() + if (BUILD_SHARED_LIBS) + set(_cuda_build_shared_libs SHARED) + else() + set(_cuda_build_shared_libs STATIC) + endif() + endif() + set(${shared_flag} ${_cuda_build_shared_libs} PARENT_SCOPE) +endfunction() + +############################################################################## +# Helper to avoid clashes of files with the same basename but different paths. +# This doesn't attempt to do exactly what CMake internals do, which is to only +# add this path when there is a conflict, since by the time a second collision +# in names is detected it's already too late to fix the first one. For +# consistency sake the relative path will be added to all files. +function(CUDA_COMPUTE_BUILD_PATH path build_path) + #message("CUDA_COMPUTE_BUILD_PATH([${path}] ${build_path})") + # Only deal with CMake style paths from here on out + file(TO_CMAKE_PATH "${path}" bpath) + if (IS_ABSOLUTE "${bpath}") + # Absolute paths are generally unnessary, especially if something like + # file(GLOB_RECURSE) is used to pick up the files. + + string(FIND "${bpath}" "${CMAKE_CURRENT_BINARY_DIR}" _binary_dir_pos) + if (_binary_dir_pos EQUAL 0) + file(RELATIVE_PATH bpath "${CMAKE_CURRENT_BINARY_DIR}" "${bpath}") + else() + file(RELATIVE_PATH bpath "${CMAKE_CURRENT_SOURCE_DIR}" "${bpath}") + endif() + endif() + + # This recipe is from cmLocalGenerator::CreateSafeUniqueObjectFileName in the + # CMake source. + + # Remove leading / + string(REGEX REPLACE "^[/]+" "" bpath "${bpath}") + # Avoid absolute paths by removing ':' + string(REPLACE ":" "_" bpath "${bpath}") + # Avoid relative paths that go up the tree + string(REPLACE "../" "__/" bpath "${bpath}") + # Avoid spaces + string(REPLACE " " "_" bpath "${bpath}") + + # Strip off the filename. I wait until here to do it, since removin the + # basename can make a path that looked like path/../basename turn into + # path/.. (notice the trailing slash). + get_filename_component(bpath "${bpath}" PATH) + + set(${build_path} "${bpath}" PARENT_SCOPE) + #message("${build_path} = ${bpath}") +endfunction() + +############################################################################## +# This helper macro populates the following variables and setups up custom +# commands and targets to invoke the nvcc compiler to generate C or PTX source +# dependent upon the format parameter. The compiler is invoked once with -M +# to generate a dependency file and a second time with -cuda or -ptx to generate +# a .cpp or .ptx file. +# INPUT: +# cuda_target - Target name +# format - PTX, CUBIN, FATBIN or OBJ +# FILE1 .. FILEN - The remaining arguments are the sources to be wrapped. +# OPTIONS - Extra options to NVCC +# OUTPUT: +# generated_files - List of generated files +############################################################################## +############################################################################## + +macro(CUDA_WRAP_SRCS cuda_target format generated_files) + + # Put optional arguments in list. + set(_argn_list "${ARGN}") + # If one of the given optional arguments is "PHONY", make a note of it, then + # remove it from the list. + list(FIND _argn_list "PHONY" _phony_idx) + if("${_phony_idx}" GREATER "-1") + set(_target_is_phony true) + list(REMOVE_AT _argn_list ${_phony_idx}) + else() + set(_target_is_phony false) + endif() + + # If CMake doesn't support separable compilation, complain + if(CUDA_SEPARABLE_COMPILATION AND CMAKE_VERSION VERSION_LESS "2.8.10.1") + message(SEND_ERROR "CUDA_SEPARABLE_COMPILATION isn't supported for CMake versions less than 2.8.10.1") + endif() + + # Set up all the command line flags here, so that they can be overridden on a per target basis. + + set(nvcc_flags "") + + # Emulation if the card isn't present. + if (CUDA_BUILD_EMULATION) + # Emulation. + set(nvcc_flags ${nvcc_flags} --device-emulation -D_DEVICEEMU -g) + message(WARNING "CUDA_BUILD_EMULATION requested from FindHipCUDA") + else() + # Device mode. No flags necessary. + endif() + + if(CUDA_HOST_COMPILATION_CPP) + set(CUDA_C_OR_CXX CXX) + else() + if(CUDA_VERSION VERSION_LESS "3.0") + set(nvcc_flags ${nvcc_flags} --host-compilation C) + else() + message(WARNING "--host-compilation flag is deprecated in CUDA version >= 3.0. Removing --host-compilation C flag" ) + endif() + set(CUDA_C_OR_CXX C) + endif() + + set(generated_extension ${CMAKE_${CUDA_C_OR_CXX}_OUTPUT_EXTENSION}) + + if(CUDA_64_BIT_DEVICE_CODE) + set(nvcc_flags ${nvcc_flags} -m64) + else() + set(nvcc_flags ${nvcc_flags} -m32) + endif() + + if(CUDA_TARGET_CPU_ARCH) + set(nvcc_flags ${nvcc_flags} "--target-cpu-architecture=${CUDA_TARGET_CPU_ARCH}") + endif() + + # This needs to be passed in at this stage, because VS needs to fill out the + # value of VCInstallDir from within VS. Note that CCBIN is only used if + # -ccbin or --compiler-bindir isn't used and CUDA_HOST_COMPILER matches + # $(VCInstallDir)/bin. + if(CMAKE_GENERATOR MATCHES "Visual Studio") + set(ccbin_flags -D "\"CCBIN:PATH=$(VCInstallDir)bin\"" ) + else() + set(ccbin_flags) + endif() + + # Figure out which configure we will use and pass that in as an argument to + # the script. We need to defer the decision until compilation time, because + # for VS projects we won't know if we are making a debug or release build + # until build time. + if(CMAKE_GENERATOR MATCHES "Visual Studio") + set( CUDA_build_configuration "$(ConfigurationName)" ) + else() + set( CUDA_build_configuration "${CMAKE_BUILD_TYPE}") + endif() + + # Initialize our list of includes with the user ones followed by the CUDA system ones. + set(CUDA_NVCC_INCLUDE_DIRS ${CUDA_NVCC_INCLUDE_DIRS_USER} "${CUDA_INCLUDE_DIRS}") + if(_target_is_phony) + # If the passed in target name isn't a real target (i.e., this is from a call to one of the + # cuda_compile_* functions), need to query directory properties to get include directories + # and compile definitions. + get_directory_property(_dir_include_dirs INCLUDE_DIRECTORIES) + get_directory_property(_dir_compile_defs COMPILE_DEFINITIONS) + + list(APPEND CUDA_NVCC_INCLUDE_DIRS "${_dir_include_dirs}") + set(CUDA_NVCC_COMPILE_DEFINITIONS "${_dir_compile_defs}") + else() + # Append the include directories for this target via generator expression, which is + # expanded by the FILE(GENERATE) call below. This generator expression captures all + # include dirs set by the user, whether via directory properties or target properties + list(APPEND CUDA_NVCC_INCLUDE_DIRS "$") + + # Do the same thing with compile definitions + set(CUDA_NVCC_COMPILE_DEFINITIONS "$") + endif() + + + # Reset these variables + set(CUDA_WRAP_OPTION_NVCC_FLAGS) + foreach(config ${CUDA_configuration_types}) + string(TOUPPER ${config} config_upper) + set(CUDA_WRAP_OPTION_NVCC_FLAGS_${config_upper}) + endforeach() + + CUDA_GET_SOURCES_AND_OPTIONS(_cuda_wrap_sources _cuda_wrap_cmake_options _cuda_wrap_options ${_argn_list}) + CUDA_PARSE_NVCC_OPTIONS(CUDA_WRAP_OPTION_NVCC_FLAGS ${_cuda_wrap_options}) + + # Figure out if we are building a shared library. BUILD_SHARED_LIBS is + # respected in CUDA_ADD_LIBRARY. + set(_cuda_build_shared_libs FALSE) + # SHARED, MODULE + list(FIND _cuda_wrap_cmake_options SHARED _cuda_found_SHARED) + list(FIND _cuda_wrap_cmake_options MODULE _cuda_found_MODULE) + if(_cuda_found_SHARED GREATER -1 OR _cuda_found_MODULE GREATER -1) + set(_cuda_build_shared_libs TRUE) + endif() + # STATIC + list(FIND _cuda_wrap_cmake_options STATIC _cuda_found_STATIC) + if(_cuda_found_STATIC GREATER -1) + set(_cuda_build_shared_libs FALSE) + endif() + + # CUDA_HOST_FLAGS + if(_cuda_build_shared_libs) + # If we are setting up code for a shared library, then we need to add extra flags for + # compiling objects for shared libraries. + set(CUDA_HOST_SHARED_FLAGS ${CMAKE_SHARED_LIBRARY_${CUDA_C_OR_CXX}_FLAGS}) + else() + set(CUDA_HOST_SHARED_FLAGS) + endif() + # Only add the CMAKE_{C,CXX}_FLAGS if we are propagating host flags. We + # always need to set the SHARED_FLAGS, though. + if(CUDA_PROPAGATE_HOST_FLAGS) + set(_cuda_host_flags "set(CMAKE_HOST_FLAGS ${CMAKE_${CUDA_C_OR_CXX}_FLAGS} ${CUDA_HOST_SHARED_FLAGS})") + else() + set(_cuda_host_flags "set(CMAKE_HOST_FLAGS ${CUDA_HOST_SHARED_FLAGS})") + endif() + + set(_cuda_nvcc_flags_config "# Build specific configuration flags") + # Loop over all the configuration types to generate appropriate flags for run_nvcc.cmake + foreach(config ${CUDA_configuration_types}) + string(TOUPPER ${config} config_upper) + # CMAKE_FLAGS are strings and not lists. By not putting quotes around CMAKE_FLAGS + # we convert the strings to lists (like we want). + + if(CUDA_PROPAGATE_HOST_FLAGS) + # nvcc chokes on -g3 in versions previous to 3.0, so replace it with -g + set(_cuda_fix_g3 FALSE) + + if(CMAKE_COMPILER_IS_GNUCC) + if (CUDA_VERSION VERSION_LESS "3.0" OR + CUDA_VERSION VERSION_EQUAL "4.1" OR + CUDA_VERSION VERSION_EQUAL "4.2" + ) + set(_cuda_fix_g3 TRUE) + endif() + endif() + if(_cuda_fix_g3) + string(REPLACE "-g3" "-g" _cuda_C_FLAGS "${CMAKE_${CUDA_C_OR_CXX}_FLAGS_${config_upper}}") + else() + set(_cuda_C_FLAGS "${CMAKE_${CUDA_C_OR_CXX}_FLAGS_${config_upper}}") + endif() + + string(APPEND _cuda_host_flags "\nset(CMAKE_HOST_FLAGS_${config_upper} ${_cuda_C_FLAGS})") + endif() + + # Note that if we ever want CUDA_NVCC_FLAGS_ to be string (instead of a list + # like it is currently), we can remove the quotes around the + # ${CUDA_NVCC_FLAGS_${config_upper}} variable like the CMAKE_HOST_FLAGS_ variable. + string(APPEND _cuda_nvcc_flags_config "\nset(CUDA_NVCC_FLAGS_${config_upper} ${CUDA_NVCC_FLAGS_${config_upper}} ;; ${CUDA_WRAP_OPTION_NVCC_FLAGS_${config_upper}})") + endforeach() + + # Process the C++11 flag. If the host sets the flag, we need to add it to nvcc and + # remove it from the host. This is because -Xcompile -std=c++ will choke nvcc (it uses + # the C preprocessor). In order to get this to work correctly, we need to use nvcc's + # specific c++11 flag. + #if( "${_cuda_host_flags}" MATCHES "-std=c\\+\\+11") + # # Add the c++11 flag to nvcc if it isn't already present. Note that we only look at + # # the main flag instead of the configuration specific flags. + # if( NOT "${CUDA_NVCC_FLAGS}" MATCHES "-std;c\\+\\+11" ) + # list(APPEND nvcc_flags --std c++11) + # endif() + # string(REGEX REPLACE "[-]+std=c\\+\\+11" "" _cuda_host_flags "${_cuda_host_flags}") + #endif() + + #if(_cuda_build_shared_libs) + # list(APPEND nvcc_flags "-D${cuda_target}_EXPORTS") + #endif() + + # Reset the output variable + set(_cuda_wrap_generated_files "") + + # Iterate over the macro arguments and create custom + # commands for all the .cu files. + foreach(file ${_argn_list}) + # Ignore any file marked as a HEADER_FILE_ONLY + get_source_file_property(_is_header ${file} HEADER_FILE_ONLY) + # Allow per source file overrides of the format. Also allows compiling non-.cu files. + get_source_file_property(_cuda_source_format ${file} CUDA_SOURCE_PROPERTY_FORMAT) + if((${file} MATCHES "\\.cu$" OR _cuda_source_format) AND NOT _is_header) + + if(NOT _cuda_source_format) + set(_cuda_source_format ${format}) + endif() + # If file isn't a .cu file, we need to tell nvcc to treat it as such. + if(NOT ${file} MATCHES "\\.cu$") + set(cuda_language_flag "-x hip") + else() + set(cuda_language_flag) + endif() + + if( ${_cuda_source_format} MATCHES "OBJ") + set( cuda_compile_to_external_module OFF ) + else() + set( cuda_compile_to_external_module ON ) + if( ${_cuda_source_format} MATCHES "PTX" ) + set( cuda_compile_to_external_module_type "ptx" ) + elseif( ${_cuda_source_format} MATCHES "CUBIN") + set( cuda_compile_to_external_module_type "cubin" ) + elseif( ${_cuda_source_format} MATCHES "FATBIN") + set( cuda_compile_to_external_module_type "fatbin" ) + else() + message( FATAL_ERROR "Invalid format flag passed to CUDA_WRAP_SRCS or set with CUDA_SOURCE_PROPERTY_FORMAT file property for file '${file}': '${_cuda_source_format}'. Use OBJ, PTX, CUBIN or FATBIN.") + endif() + endif() + + if(cuda_compile_to_external_module) + # Don't use any of the host compilation flags for PTX targets. + set(CUDA_HOST_FLAGS) + set(CUDA_NVCC_FLAGS_CONFIG) + else() + set(CUDA_HOST_FLAGS ${_cuda_host_flags}) + set(CUDA_NVCC_FLAGS_CONFIG ${_cuda_nvcc_flags_config}) + endif() + + # Determine output directory + cuda_compute_build_path("${file}" cuda_build_path) + set(cuda_compile_intermediate_directory "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${cuda_target}.dir/${cuda_build_path}") + if(CUDA_GENERATED_OUTPUT_DIR) + set(cuda_compile_output_dir "${CUDA_GENERATED_OUTPUT_DIR}") + else() + if ( cuda_compile_to_external_module ) + set(cuda_compile_output_dir "${CMAKE_CURRENT_BINARY_DIR}") + else() + set(cuda_compile_output_dir "${cuda_compile_intermediate_directory}") + endif() + endif() + + # Add a custom target to generate a c or ptx file. ###################### + + get_filename_component( basename ${file} NAME ) + if( cuda_compile_to_external_module ) + set(generated_file_path "${cuda_compile_output_dir}") + set(generated_file_basename "${cuda_target}_generated_${basename}.${cuda_compile_to_external_module_type}") + set(format_flag "-${cuda_compile_to_external_module_type}") + file(MAKE_DIRECTORY "${cuda_compile_output_dir}") + else() + set(generated_file_path "${cuda_compile_output_dir}/${CMAKE_CFG_INTDIR}") + set(generated_file_basename "${cuda_target}_generated_${basename}${generated_extension}") + if(CUDA_SEPARABLE_COMPILATION) + set(format_flag "-dc") + message(WARNING "FindHipCUDA was requested to do separable compilation.") + else() + set(format_flag "-c") + endif() + endif() + + # Set all of our file names. Make sure that whatever filenames that have + # generated_file_path in them get passed in through as a command line + # argument, so that the ${CMAKE_CFG_INTDIR} gets expanded at run time + # instead of configure time. + set(generated_file "${generated_file_path}/${generated_file_basename}") + set(cmake_dependency_file "${cuda_compile_intermediate_directory}/${generated_file_basename}.depend") + set(NVCC_generated_dependency_file "${cuda_compile_intermediate_directory}/${generated_file_basename}.NVCC-depend") + set(generated_cubin_file "${generated_file_path}/${generated_file_basename}.cubin.txt") + set(custom_target_script_pregen "${cuda_compile_intermediate_directory}/${generated_file_basename}.cmake.pre-gen") + set(custom_target_script "${cuda_compile_intermediate_directory}/${generated_file_basename}$<$>:.$>.cmake") + + # Setup properties for obj files: + if( NOT cuda_compile_to_external_module ) + set_source_files_properties("${generated_file}" + PROPERTIES + EXTERNAL_OBJECT true # This is an object file not to be compiled, but only be linked. + ) + endif() + + # Don't add CMAKE_CURRENT_SOURCE_DIR if the path is already an absolute path. + get_filename_component(file_path "${file}" PATH) + if(IS_ABSOLUTE "${file_path}") + set(source_file "${file}") + else() + set(source_file "${CMAKE_CURRENT_SOURCE_DIR}/${file}") + endif() + + if( NOT cuda_compile_to_external_module AND CUDA_SEPARABLE_COMPILATION) + list(APPEND ${cuda_target}_SEPARABLE_COMPILATION_OBJECTS "${generated_file}") + endif() + + # Bring in the dependencies. Creates a variable CUDA_NVCC_DEPEND ####### + cuda_include_nvcc_dependencies(${cmake_dependency_file}) + + # Convience string for output ########################################### + if(CUDA_BUILD_EMULATION) + set(cuda_build_type "Emulation") + else() + set(cuda_build_type "Device") + endif() + + # Build the NVCC made dependency file ################################### + set(build_cubin OFF) + if ( NOT CUDA_BUILD_EMULATION AND CUDA_BUILD_CUBIN ) + if ( NOT cuda_compile_to_external_module ) + message(WARNING "FindHipCUDA was asked to use -cubin reporting") + set ( build_cubin ON ) + endif() + endif() + + # Configure the build script + configure_file("${CUDA_run_nvcc}" "${custom_target_script_pregen}" @ONLY) + file(GENERATE + OUTPUT "${custom_target_script}" + INPUT "${custom_target_script_pregen}" + ) + + # So if a user specifies the same cuda file as input more than once, you + # can have bad things happen with dependencies. Here we check an option + # to see if this is the behavior they want. + if(CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE) + set(main_dep MAIN_DEPENDENCY ${source_file}) + else() + set(main_dep DEPENDS ${source_file}) + endif() + + if(CUDA_VERBOSE_BUILD) + set(verbose_output ON) + elseif(CMAKE_GENERATOR MATCHES "Makefiles") + set(verbose_output "$(VERBOSE)") + else() + set(verbose_output OFF) + endif() + + # Create up the comment string + file(RELATIVE_PATH generated_file_relative_path "${CMAKE_BINARY_DIR}" "${generated_file}") + if(cuda_compile_to_external_module) + set(cuda_build_comment_string "Building HIPCC ${cuda_compile_to_external_module_type} file ${generated_file_relative_path}") + else() + set(cuda_build_comment_string "Building HIPCC (${cuda_build_type}) object ${generated_file_relative_path}") + endif() + + set(_verbatim VERBATIM) + if(ccbin_flags MATCHES "\\$\\(VCInstallDir\\)") + set(_verbatim "") + endif() + + # Build the generated file and dependency file ########################## + add_custom_command( + OUTPUT ${generated_file} + # These output files depend on the source_file and the contents of cmake_dependency_file + ${main_dep} + DEPENDS ${CUDA_NVCC_DEPEND} + DEPENDS ${custom_target_script} + # Make sure the output directory exists before trying to write to it. + COMMAND ${CMAKE_COMMAND} -E make_directory "${generated_file_path}" + COMMAND ${CMAKE_COMMAND} ARGS + -D verbose:BOOL=${verbose_output} + ${ccbin_flags} + -D build_configuration:STRING=${CUDA_build_configuration} + -D "generated_file:STRING=${generated_file}" + -D "generated_cubin_file:STRING=${generated_cubin_file}" + -P "${custom_target_script}" + WORKING_DIRECTORY "${cuda_compile_intermediate_directory}" + COMMENT "${cuda_build_comment_string}" + ${_verbatim} + ) + + # Make sure the build system knows the file is generated. + set_source_files_properties(${generated_file} PROPERTIES GENERATED TRUE) + + list(APPEND _cuda_wrap_generated_files ${generated_file}) + + # Add the other files that we want cmake to clean on a cleanup ########## + list(APPEND CUDA_ADDITIONAL_CLEAN_FILES "${cmake_dependency_file}") + list(REMOVE_DUPLICATES CUDA_ADDITIONAL_CLEAN_FILES) + set(CUDA_ADDITIONAL_CLEAN_FILES ${CUDA_ADDITIONAL_CLEAN_FILES} CACHE INTERNAL "List of intermediate files that are part of the cuda dependency scanning.") + + endif() + endforeach() + + # Set the return parameter + set(${generated_files} ${_cuda_wrap_generated_files}) +endmacro() + +function(_cuda_get_important_host_flags important_flags flag_string) + if(CMAKE_GENERATOR MATCHES "Visual Studio") + string(REGEX MATCHALL "/M[DT][d]?" flags "${flag_string}") + list(APPEND ${important_flags} ${flags}) + else() + string(REGEX MATCHALL "-fPIC" flags "${flag_string}") + list(APPEND ${important_flags} ${flags}) + endif() + set(${important_flags} ${${important_flags}} PARENT_SCOPE) +endfunction() + +############################################################################### +############################################################################### +# Separable Compilation Link +############################################################################### +############################################################################### + +# Compute the filename to be used by CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS +function(CUDA_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME output_file_var cuda_target object_files) + if (object_files) + set(generated_extension ${CMAKE_${CUDA_C_OR_CXX}_OUTPUT_EXTENSION}) + set(output_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${cuda_target}.dir/${CMAKE_CFG_INTDIR}/${cuda_target}_intermediate_link${generated_extension}") + else() + set(output_file) + endif() + + set(${output_file_var} "${output_file}" PARENT_SCOPE) +endfunction() + +# Setup the build rule for the separable compilation intermediate link file. +function(CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS output_file cuda_target options object_files) + if (object_files) + + set_source_files_properties("${output_file}" + PROPERTIES + EXTERNAL_OBJECT TRUE # This is an object file not to be compiled, but only + # be linked. + GENERATED TRUE # This file is generated during the build + ) + + # For now we are ignoring all the configuration specific flags. + set(nvcc_flags) + CUDA_PARSE_NVCC_OPTIONS(nvcc_flags ${options}) + if(CUDA_64_BIT_DEVICE_CODE) + list(APPEND nvcc_flags -m64) + else() + list(APPEND nvcc_flags -m32) + endif() + # If -ccbin, --compiler-bindir has been specified, don't do anything. Otherwise add it here. + list( FIND nvcc_flags "-ccbin" ccbin_found0 ) + list( FIND nvcc_flags "--compiler-bindir" ccbin_found1 ) + if( ccbin_found0 LESS 0 AND ccbin_found1 LESS 0 AND CUDA_HOST_COMPILER ) + # Match VERBATIM check below. + if(CUDA_HOST_COMPILER MATCHES "\\$\\(VCInstallDir\\)") + list(APPEND nvcc_flags -ccbin "\"${CUDA_HOST_COMPILER}\"") + else() + list(APPEND nvcc_flags -ccbin "${CUDA_HOST_COMPILER}") + endif() + endif() + + # Create a list of flags specified by CUDA_NVCC_FLAGS_${CONFIG} and CMAKE_${CUDA_C_OR_CXX}_FLAGS* + set(config_specific_flags) + set(flags) + foreach(config ${CUDA_configuration_types}) + string(TOUPPER ${config} config_upper) + # Add config specific flags + foreach(f ${CUDA_NVCC_FLAGS_${config_upper}}) + list(APPEND config_specific_flags $<$:${f}>) + endforeach() + set(important_host_flags) + _cuda_get_important_host_flags(important_host_flags "${CMAKE_${CUDA_C_OR_CXX}_FLAGS_${config_upper}}") + foreach(f ${important_host_flags}) + list(APPEND flags $<$:-Xcompiler> $<$:${f}>) + endforeach() + endforeach() + # Add CMAKE_${CUDA_C_OR_CXX}_FLAGS + set(important_host_flags) + _cuda_get_important_host_flags(important_host_flags "${CMAKE_${CUDA_C_OR_CXX}_FLAGS}") + foreach(f ${important_host_flags}) + list(APPEND flags -Xcompiler ${f}) + endforeach() + + # Add our general CUDA_NVCC_FLAGS with the configuration specifig flags + set(nvcc_flags ${CUDA_NVCC_FLAGS} ${config_specific_flags} ${nvcc_flags}) + + file(RELATIVE_PATH output_file_relative_path "${CMAKE_BINARY_DIR}" "${output_file}") + + # Some generators don't handle the multiple levels of custom command + # dependencies correctly (obj1 depends on file1, obj2 depends on obj1), so + # we work around that issue by compiling the intermediate link object as a + # pre-link custom command in that situation. + set(do_obj_build_rule TRUE) + if (MSVC_VERSION GREATER 1599 AND MSVC_VERSION LESS 1800) + # VS 2010 and 2012 have this problem. + set(do_obj_build_rule FALSE) + endif() + + set(_verbatim VERBATIM) + if(nvcc_flags MATCHES "\\$\\(VCInstallDir\\)") + set(_verbatim "") + endif() + + if (do_obj_build_rule) + add_custom_command( + OUTPUT ${output_file} + DEPENDS ${object_files} + COMMAND ${CUDA_NVCC_EXECUTABLE} ${nvcc_flags} -dlink ${object_files} -o ${output_file} + ${flags} + COMMENT "Building NVCC intermediate link file ${output_file_relative_path}" + ${_verbatim} + ) + else() + get_filename_component(output_file_dir "${output_file}" DIRECTORY) + add_custom_command( + TARGET ${cuda_target} + PRE_LINK + COMMAND ${CMAKE_COMMAND} -E echo "Building NVCC intermediate link file ${output_file_relative_path}" + COMMAND ${CMAKE_COMMAND} -E make_directory "${output_file_dir}" + COMMAND ${CUDA_NVCC_EXECUTABLE} ${nvcc_flags} ${flags} -dlink ${object_files} -o "${output_file}" + ${_verbatim} + ) + endif() + endif() +endfunction() + +############################################################################### +############################################################################### +# ADD LIBRARY +############################################################################### +############################################################################### +macro(CUDA_ADD_LIBRARY cuda_target) + + CUDA_ADD_CUDA_INCLUDE_ONCE() + + # Separate the sources from the options + CUDA_GET_SOURCES_AND_OPTIONS(_sources _cmake_options _options ${ARGN}) + CUDA_BUILD_SHARED_LIBRARY(_cuda_shared_flag ${ARGN}) + # Create custom commands and targets for each file. + CUDA_WRAP_SRCS( ${cuda_target} OBJ _generated_files ${_sources} + ${_cmake_options} ${_cuda_shared_flag} + OPTIONS ${_options} ) + + # Compute the file name of the intermedate link file used for separable + # compilation. + CUDA_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME(link_file ${cuda_target} "${${cuda_target}_SEPARABLE_COMPILATION_OBJECTS}") + + # Add the library. + add_library(${cuda_target} ${_cmake_options} + ${_generated_files} + ${_sources} + ${link_file} + ) + + # Add a link phase for the separable compilation if it has been enabled. If + # it has been enabled then the ${cuda_target}_SEPARABLE_COMPILATION_OBJECTS + # variable will have been defined. + CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS("${link_file}" ${cuda_target} "${_options}" "${${cuda_target}_SEPARABLE_COMPILATION_OBJECTS}") + + target_link_libraries(${cuda_target} + ${CUDA_LIBRARIES} + ) + + if(CUDA_SEPARABLE_COMPILATION) + target_link_libraries(${cuda_target} + ${CUDA_cudadevrt_LIBRARY} + ) + endif() + + # We need to set the linker language based on what the expected generated file + # would be. CUDA_C_OR_CXX is computed based on CUDA_HOST_COMPILATION_CPP. + set_target_properties(${cuda_target} + PROPERTIES + LINKER_LANGUAGE ${CUDA_C_OR_CXX} + ) + +endmacro() + + +############################################################################### +############################################################################### +# ADD EXECUTABLE +############################################################################### +############################################################################### +macro(CUDA_ADD_EXECUTABLE cuda_target) + + CUDA_ADD_CUDA_INCLUDE_ONCE() + + # Separate the sources from the options + CUDA_GET_SOURCES_AND_OPTIONS(_sources _cmake_options _options ${ARGN}) + # Create custom commands and targets for each file. + CUDA_WRAP_SRCS( ${cuda_target} OBJ _generated_files ${_sources} OPTIONS ${_options} ) + + # Compute the file name of the intermedate link file used for separable + # compilation. + CUDA_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME(link_file ${cuda_target} "${${cuda_target}_SEPARABLE_COMPILATION_OBJECTS}") + + # Add the library. + add_executable(${cuda_target} ${_cmake_options} + ${_generated_files} + ${_sources} + ${link_file} + ) + + # Add a link phase for the separable compilation if it has been enabled. If + # it has been enabled then the ${cuda_target}_SEPARABLE_COMPILATION_OBJECTS + # variable will have been defined. + CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS("${link_file}" ${cuda_target} "${_options}" "${${cuda_target}_SEPARABLE_COMPILATION_OBJECTS}") + + target_link_libraries(${cuda_target} + ${CUDA_LIBRARIES} + ) + + # We need to set the linker language based on what the expected generated file + # would be. CUDA_C_OR_CXX is computed based on CUDA_HOST_COMPILATION_CPP. + set_target_properties(${cuda_target} + PROPERTIES + LINKER_LANGUAGE ${CUDA_C_OR_CXX} + ) + +endmacro() + + +############################################################################### +############################################################################### +# (Internal) helper for manually added cuda source files with specific targets +############################################################################### +############################################################################### +macro(cuda_compile_base cuda_target format generated_files) + # Update a counter in this directory, to keep phony target names unique. + set(_cuda_target "${cuda_target}") + get_property(_counter DIRECTORY PROPERTY _cuda_internal_phony_counter) + if(_counter) + math(EXPR _counter "${_counter} + 1") + else() + set(_counter 1) + endif() + set(_cuda_target "${_cuda_target}_${_counter}") + set_property(DIRECTORY PROPERTY _cuda_internal_phony_counter ${_counter}) + + # Separate the sources from the options + CUDA_GET_SOURCES_AND_OPTIONS(_sources _cmake_options _options ${ARGN}) + + # Create custom commands and targets for each file. + CUDA_WRAP_SRCS( ${_cuda_target} ${format} _generated_files ${_sources} + ${_cmake_options} OPTIONS ${_options} PHONY) + + set( ${generated_files} ${_generated_files}) + +endmacro() + +############################################################################### +############################################################################### +# CUDA COMPILE +############################################################################### +############################################################################### +macro(CUDA_COMPILE generated_files) + cuda_compile_base(cuda_compile OBJ ${generated_files} ${ARGN}) +endmacro() + +############################################################################### +############################################################################### +# CUDA COMPILE PTX +############################################################################### +############################################################################### +macro(CUDA_COMPILE_PTX generated_files) + cuda_compile_base(cuda_compile_ptx PTX ${generated_files} ${ARGN}) +endmacro() + +############################################################################### +############################################################################### +# CUDA COMPILE FATBIN +############################################################################### +############################################################################### +macro(CUDA_COMPILE_FATBIN generated_files) + cuda_compile_base(cuda_compile_fatbin FATBIN ${generated_files} ${ARGN}) +endmacro() + +############################################################################### +############################################################################### +# CUDA COMPILE CUBIN +############################################################################### +############################################################################### +macro(CUDA_COMPILE_CUBIN generated_files) + cuda_compile_base(cuda_compile_cubin CUBIN ${generated_files} ${ARGN}) +endmacro() + + +############################################################################### +############################################################################### +# CUDA ADD CUFFT TO TARGET +############################################################################### +############################################################################### +macro(CUDA_ADD_CUFFT_TO_TARGET target) + target_link_libraries(${target} ${CUDA_cufft_LIBRARY}) +endmacro() + +############################################################################### +############################################################################### +# CUDA ADD CUBLAS TO TARGET +############################################################################### +############################################################################### +macro(CUDA_ADD_CUBLAS_TO_TARGET target) + target_link_libraries(${target} ${CUDA_cublas_LIBRARY}) +endmacro() + +############################################################################### +############################################################################### +# CUDA BUILD CLEAN TARGET +############################################################################### +############################################################################### +macro(CUDA_BUILD_CLEAN_TARGET) + # Call this after you add all your CUDA targets, and you will get a convience + # target. You should also make clean after running this target to get the + # build system to generate all the code again. + + set(cuda_clean_target_name clean_cuda_depends) + if (CMAKE_GENERATOR MATCHES "Visual Studio") + string(TOUPPER ${cuda_clean_target_name} cuda_clean_target_name) + endif() + add_custom_target(${cuda_clean_target_name} + COMMAND ${CMAKE_COMMAND} -E remove ${CUDA_ADDITIONAL_CLEAN_FILES}) + + # Clear out the variable, so the next time we configure it will be empty. + # This is useful so that the files won't persist in the list after targets + # have been removed. + set(CUDA_ADDITIONAL_CLEAN_FILES "" CACHE INTERNAL "List of intermediate files that are part of the cuda dependency scanning.") +endmacro() diff --git a/cmake/FindKMMD.cmake b/cmake/FindKMMD.cmake new file mode 100644 index 000000000..a528b6bf5 --- /dev/null +++ b/cmake/FindKMMD.cmake @@ -0,0 +1,40 @@ +# Find the (internal or external) KMMD includes and library +# This module defines the following variables: +# +# KMMD_LIB, the library needed to use KMMD (Machine Learning MD). +# KMMD_INCLUDES, directory to include so that you can #include +# KMMD_FOUND, If false, do not try to use KMMD. + +include(FindPackageHandleStandardArgs) + +message(STATUS "hints given to look for KMMD in DIR: ${KMMD_DIR}") + +find_library(KMMD_LIB libkmmd.so HINTS ${KMMD_DIR}) +message(STATUS "found KMMD?: ${KMMD_LIB}") + + +#find_path(KMMD_INCLUDES kmmd.h HINTS ${KMMD_DIR}) + +message(STATUS "found INCLUDES?: " ${KMMD_INCLUDES}) + + +if(NOT(KMMD_LIB)) + + set(FIND_KMMD_FAILURE_MESSAGE "Did not find an external KMMD library, should be able to use bundled. If you have a custom version then set the path with -DKMMD_DIR") +else() + + # check if KMMD works + #try_link_library(KMMD_WORKS + # LANGUAGE CXX + # FUNCTION hash_function + # LIBRARIES ${KMMD_LIB}) + + #if(KMMD_WORKS) + # set(FIND_KMMD_FAILURE_MESSAGE "Could not find the kmmd headers. Please set KMMD_INCLUDES to point to the directory containing the directory containing kmmd.h.") + #else() + # set(FIND_KMMD_FAILURE_MESSAGE "Could not link with KMMD.") + #endif() + +endif() + +find_package_handle_standard_args(KMMD ${FIND_KMMD_FAILURE_MESSAGE} KMMD_LIB) # KMMD_INCLUDES) diff --git a/cmake/FindNCCL.cmake b/cmake/FindNCCL.cmake index db185cb1c..0f7fdc08f 100644 --- a/cmake/FindNCCL.cmake +++ b/cmake/FindNCCL.cmake @@ -10,14 +10,30 @@ # If NCCL is found, it also creates the "nccl" imported target which is set # up to use these paths. -find_path(NCCL_INCLUDE_DIR NAMES nccl.h PATHS $ENV{NCCL_HOME}/include) -find_library(NCCL_LIBRARY NAMES nccl nccl-static PATHS $ENV{NCCL_HOME}/lib) +if(CUDA AND NOT HIP) + find_path(NCCL_INCLUDE_DIR NAMES nccl.h PATHS $ENV{NCCL_HOME}/include) + find_library(NCCL_LIBRARY NAMES nccl nccl-static PATHS $ENV{NCCL_HOME}/lib) -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(NCCL DEFAULT_MSG NCCL_INCLUDE_DIR NCCL_LIBRARY) + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(NCCL DEFAULT_MSG NCCL_INCLUDE_DIR NCCL_LIBRARY) -if(NCCL_FOUND) - add_library(nccl UNKNOWN IMPORTED) - set_property(TARGET nccl PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${NCCL_INCLUDE_DIR}) - set_property(TARGET nccl PROPERTY IMPORTED_LOCATION ${NCCL_LIBRARY}) -endif() \ No newline at end of file + if(NCCL_FOUND) + add_library(nccl UNKNOWN IMPORTED) + set_property(TARGET nccl PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${NCCL_INCLUDE_DIR}) + set_property(TARGET nccl PROPERTY IMPORTED_LOCATION ${NCCL_LIBRARY}) + endif() +endif() + +if(HIP) + find_path(NCCL_INCLUDE_DIR NAMES rccl.h PATHS $ENV{NCCL_HOME}/include) + find_library(NCCL_LIBRARY NAMES rccl PATHS $ENV{NCCL_HOME}/lib) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(NCCL DEFAULT_MSG NCCL_INCLUDE_DIR NCCL_LIBRARY) + + if(NCCL_FOUND) + add_library(nccl UNKNOWN IMPORTED) + set_property(TARGET nccl PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${NCCL_INCLUDE_DIR}) + set_property(TARGET nccl PROPERTY IMPORTED_LOCATION ${NCCL_LIBRARY}) + endif() +endif() diff --git a/cmake/FindReadline.cmake b/cmake/FindReadline.cmake index 56f7999ba..7f807325c 100644 --- a/cmake/FindReadline.cmake +++ b/cmake/FindReadline.cmake @@ -44,7 +44,11 @@ if(EXISTS "${READLINE_LIBRARY}") FUNCTION rl_initialize LIBRARIES ${READLINE_LIBRARY} INCLUDES ${READLINE_INCLUDE_DIR} - FUNC_DECLARATION "#include ") + FUNC_DECLARATION " +#include +#include +#include " + ) endif() mark_as_advanced(READLINE_INCLUDE_DIR READLINE_LIBRARY READLINE_WORKS) @@ -60,4 +64,4 @@ if(READLINE_FOUND) set_property(TARGET readline::readline PROPERTY INTERFACE_COMPILE_DEFINITIONS ${READLINE_COMPILE_DEFINITIONS}) endif() -cmake_pop_check_state() \ No newline at end of file +cmake_pop_check_state() diff --git a/cmake/FindTermcap.cmake b/cmake/FindTermcap.cmake deleted file mode 100644 index 278eef872..000000000 --- a/cmake/FindTermcap.cmake +++ /dev/null @@ -1,67 +0,0 @@ - -# Script to figure out which of the different terminal libraries (terminfo/termcap) to use to get the Terminfo functions -# We search for "tgetent", which is what the original Automake code (BASH_CHECK_LIB_TERMCAP) used. - -# Defines the following variables: -# TERMCAP_INCLUDE_DIR - include directory containing termcap headers (there are a few different ones) -# TERMCAP_LIBRARY - library to link to get termcap functions -# TERMCAP_FOUND - whether or not a library and header were found -# -# If termcap was found, this module also creates the following imported target: -# termcap::termcap - Target for termcap library - -set(TERMCAP_SYMBOL tgetent) - -# check libraries - -# skip if user defined on cache -if(NOT (DEFINED TERMCAP_LIBRARY AND EXISTS "${TERMCAP_LIBRARY}")) - - foreach(POSSIBLE_LIBRARY termcap tinfo ncurses curses gnutermcap) - - # on some systems (e.g. Anaconda's runtime), these libraries might exist but be missing the symbols we need. - # so, we have to check that they have the needed symbol. - string(TOUPPER ${POSSIBLE_LIBRARY} POSSIBLE_LIBRARY_UCASE) - find_library(${POSSIBLE_LIBRARY_UCASE}_LIBRARY NAMES ${POSSIBLE_LIBRARY} DOC "Path to a Termcap candidate library") - - if(${POSSIBLE_LIBRARY_UCASE}_LIBRARY) - - try_link_library(HAVE_TERMCAP_SYMBOL_IN_${POSSIBLE_LIBRARY_UCASE} - LANGUAGE C - FUNCTION ${TERMCAP_SYMBOL} - LIBRARIES ${${POSSIBLE_LIBRARY_UCASE}_LIBRARY}) - - if(HAVE_TERMCAP_SYMBOL_IN_${POSSIBLE_LIBRARY_UCASE}) - set(TERMCAP_LIBRARY ${${POSSIBLE_LIBRARY_UCASE}_LIBRARY} CACHE FILEPATH "Path to the library providing termcap functionality") - break() - endif() - - endif() - endforeach() -endif() - -# -------------------------------------------------------------------- - -set(TERMCAP_INCLUDE_HINTS "") - -# check headers -if(EXISTS "${TERMCAP_LIBRARY}") - # try to work backwards from the library location - get_filename_component(TERMCAP_LIBRARY_DIR "${TERMCAP_LIBRARY}" PATH) - - list(APPEND TERMCAP_INCLUDE_HINTS "${TERMCAP_LIBRARY_DIR}/../include") -endif() - -find_path(TERMCAP_INCLUDE_DIR NAMES termcap.h curses.h term.h ncurses.h HINTS ${TERMCAP_INCLUDE_HINTS}) - -# -------------------------------------------------------------------- - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Termcap REQUIRED_VARS TERMCAP_LIBRARY TERMCAP_INCLUDE_DIR) - -# create imported target -if(Termcap_FOUND AND NOT TARGET termcap::termcap) - add_library(termcap::termcap UNKNOWN IMPORTED) - set_property(TARGET termcap::termcap PROPERTY IMPORTED_LOCATION ${TERMCAP_LIBRARY}) - set_property(TARGET termcap::termcap PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${TERMCAP_INCLUDE_DIR}) -endif() \ No newline at end of file diff --git a/cmake/FindXTB.cmake b/cmake/FindXTB.cmake new file mode 100644 index 000000000..5f2a2fc44 --- /dev/null +++ b/cmake/FindXTB.cmake @@ -0,0 +1,37 @@ +# - Find XTB +# +# This module finds the XTB library on your system. +# +# Variables: +# XTB_LIBRARIES - Libraries to link to use XTB as a shared library +# XTB_INCLUDES - Path where XTB's headers can be found +# XTB_FOUND - Whether XTB was found +# +# If XTB was found, this module also creates the following imported target: +# XTB::XTB - Target for XTB's libraries + + +# find library +find_library(XTB_LIBRARY + NAMES xtb + DOC "Path to XTB library") + +# search for headers +find_path(XTB_INCLUDE_DIR + NAMES xtb.h + DOC "Path to XTB's includes. Should contain xtb.h and fortran modules; e.g., xtb_xtb_calculator.mod") + +#find_path(XTB_BUILD_DIR +# NAMES include/xtb_xtb_calculator.mod +# DOC "Path to XTB build directory containing the uninstalled XTB fortran modules, e.g. include/xtb_xtb_calculator.mod") + +find_package_handle_standard_args(XTB + REQUIRED_VARS XTB_LIBRARY XTB_INCLUDE_DIR) # XTB_BUILD_DIR + +# create imported target +if(XTB_FOUND) + add_library(xtb::xtb UNKNOWN IMPORTED) + set_property(TARGET xtb::xtb PROPERTY IMPORTED_LOCATION ${XTB_LIBRARY}) + set_property(TARGET xtb::xtb PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${XTB_INCLUDE_DIR}) + #set_property(TARGET xtb::xtb PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${XTB_BUILD_DIR}/include;${XTB_INCLUDE_DIR}") +endif() diff --git a/cmake/FixCondaShebang/FixCondaShebang.cmake b/cmake/FixCondaShebang/FixCondaShebang.cmake index d7dc5716e..1e50cf0ae 100644 --- a/cmake/FixCondaShebang/FixCondaShebang.cmake +++ b/cmake/FixCondaShebang/FixCondaShebang.cmake @@ -39,6 +39,11 @@ list(APPEND FILES_NEEDING_REPLACEMENT "${AMBER_INSTALL_DIR}/miniconda${PREFIX_RE # -------------------------------------------------------------------- include(${CMAKE_CURRENT_LIST_DIR}/../Replace-function.cmake) +# mod path in jupyter kernel json config. If not fixed, amber.jupyter fails +set(JUPYTER_KERNEL_JSON "${AMBER_INSTALL_DIR}/miniconda/share/jupyter/kernels/python3/kernel.json") +configuretime_file_replace(${JUPYTER_KERNEL_JSON} ${JUPYTER_KERNEL_JSON} TO_REPLACE "${MINICONDA_INSTALL_DIR}/bin/python" REPLACEMENT "${AMBER_INSTALL_DIR}/miniconda/bin/python") + + foreach(FILE ${FILES_NEEDING_REPLACEMENT}) configuretime_file_replace(${FILE} ${FILE} TO_REPLACE ${BUILD_TREE_SHEBANG} REPLACEMENT ${INSTALL_TREE_SHEBANG}) -endforeach() \ No newline at end of file +endforeach() diff --git a/cmake/InstallWrapped.cmake b/cmake/InstallWrapped.cmake index f1647f122..997281177 100644 --- a/cmake/InstallWrapped.cmake +++ b/cmake/InstallWrapped.cmake @@ -76,9 +76,9 @@ call %this_script_dir%\\..\\amber.bat # Calls the real ${EXECUTABLE} after setting needed environment variables. this_script_dir=\"$(cd \"$(dirname \"$0\")\" && pwd)\" -source $this_script_dir/../amber.sh +source \"$this_script_dir/../amber.sh\" -$AMBERHOME/bin/wrapped_progs/$ \"$@\"") +\"$AMBERHOME/bin/wrapped_progs/$\" \"$@\"") endif() @@ -97,4 +97,4 @@ $AMBERHOME/bin/wrapped_progs/$ \"$@\"") endforeach() -endfunction(install_executables_wrapped) \ No newline at end of file +endfunction(install_executables_wrapped) diff --git a/cmake/LICENSE b/cmake/LICENSE index 48ad8e528..e9e1741d5 100644 --- a/cmake/LICENSE +++ b/cmake/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 Amber Molecular Dynamics +Copyright (c) 2017-2022 Amber Molecular Dynamics Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/cmake/LibraryTracking.cmake b/cmake/LibraryTracking.cmake index 3d222a6ab..dcb5a1001 100644 --- a/cmake/LibraryTracking.cmake +++ b/cmake/LibraryTracking.cmake @@ -154,24 +154,25 @@ function(import_library NAME PATH) #3rd arg: INCLUDE_DIRS endif() else() - #Try to figure out whether it is shared or static. - get_lib_type(${PATH} LIB_TYPE) + #Try to figure out whether it is shared or static. + get_lib_type(${PATH} LIB_TYPE) - if("${LIB_TYPE}" STREQUAL "SHARED") - add_library(${NAME} SHARED IMPORTED GLOBAL) - else() - add_library(${NAME} STATIC IMPORTED GLOBAL) - endif() + if("${LIB_TYPE}" STREQUAL "SHARED") + add_library(${NAME} SHARED IMPORTED GLOBAL) + else() + add_library(${NAME} STATIC IMPORTED GLOBAL) + endif() - set_property(TARGET ${NAME} PROPERTY IMPORTED_LOCATION ${PATH}) - set_property(TARGET ${NAME} PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${ARGN}) + set_property(TARGET ${NAME} PROPERTY IMPORTED_LOCATION ${PATH}) + set_property(TARGET ${NAME} PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${ARGN}) - using_external_library("${PATH}") + using_external_library("${PATH}") endif() endfunction(import_library) + # Shorthand for adding one library target which corresponds to multiple linkable things. # "linkable things" can be any of 6 different types: # 1. CMake imported targets (as created by import_library() or by another module) diff --git a/cmake/LibraryUtils.cmake b/cmake/LibraryUtils.cmake index 3a40c14d2..c12d3aa33 100644 --- a/cmake/LibraryUtils.cmake +++ b/cmake/LibraryUtils.cmake @@ -14,9 +14,6 @@ endif() # Sets OUTPUT_VARAIBLE to "IMPORT", "SHARED", or "STATIC" depending on the library passed function(get_lib_type LIBRARY OUTPUT_VARIABLE) - if(NOT EXISTS ${LIBRARY}) - message(FATAL_ERROR "get_lib_type(): library ${LIBRARY} does not exist!") - endif() get_filename_component(LIB_NAME ${LIBRARY} NAME) @@ -38,6 +35,10 @@ function(get_lib_type LIBRARY OUTPUT_VARIABLE) endif() else() # MSVC, Intel, or some other Windows compiler + if(NOT EXISTS ${LIBRARY}) + message(FATAL_ERROR "get_lib_type(${${CACHE_VAR_NAME}}): library ${LIBRARY} does not exist! Libraries must exist to get their types on MSVC.") + endif() + # we have to work a little harder, and use Dumpbin to check the library type, since import and static libraries have the same extensions find_program(DUMPBIN dumpbin) @@ -98,6 +99,10 @@ endfunction(get_lib_type) # usage: resolve_cmake_library_list( ) function(resolve_cmake_library_list LIB_PATH_OUTPUT) + + # Enable for debugging prints + set(RCLL_DEBUG FALSE) + # we don't want to add generator expressions to the library tracker... string(GENEX_STRIP "${ARGN}" LIBS_TO_RESOLVE) @@ -121,8 +126,11 @@ function(resolve_cmake_library_list LIB_PATH_OUTPUT) if(NOT "${LIB_DEPENDENCIES}" STREQUAL "") - # avoid infinite recursion if somebody accidentally made an interface library depend on itself + # avoid infinite recursion if somebody accidentally made a library depend on itself list(REMOVE_ITEM LIB_DEPENDENCIES "${LIBRARY}") + if(RCLL_DEBUG) + message("Found library ${LIBRARY} with dependencies ${LIB_DEPENDENCIES}") + endif() # now parse those dependencies! resolve_cmake_library_list(INTERFACE_DEPS_LIB_PATHS ${LIB_DEPENDENCIES}) @@ -182,6 +190,16 @@ function(resolve_cmake_library_list LIB_PATH_OUTPUT) # use target name if output name was not set set(LIB_NAME ${LIBRARY}) endif() + + # Check if the PREFIX target property was changed by remove_prefix + get_property(LIB_PREFIX TARGET ${LIBRARY} PROPERTY PREFIX) + if("${LIB_PREFIX}" STREQUAL "") + string(REGEX REPLACE "^lib" "" LIB_NAME ${LIB_NAME}) + endif() + + if(RCLL_DEBUG) + message("${LIBRARY} detected as CMake target with output name ${LIB_NAME}") + endif() list(APPEND LIB_PATHS ${LIB_NAME}) endif() @@ -189,13 +207,16 @@ function(resolve_cmake_library_list LIB_PATH_OUTPUT) else() # otherwise it's a library name to find on the linker search path (using CMake in "naive mode") + if(RCLL_DEBUG) + message("Not a known library: ${LIBRARY}") + endif() list(APPEND LIB_PATHS ${LIBRARY}) endif() endforeach() # debugging code - if(FALSE) + if(RCLL_DEBUG) message("resolve_cmake_library_list(${LIBS_TO_RESOLVE}):") message(" -> ${LIB_PATHS}") endif() @@ -220,11 +241,16 @@ function(get_linker_name LIBRARY_PATH OUTPUT_VARIABLE) get_lib_type(${LIBRARY_PATH} LIB_TYPE) if("${LIB_TYPE}" STREQUAL "IMPORT") - string(REGEX REPLACE "${CMAKE_IMPORT_LIBRARY_SUFFIX}$" "" LIBNAME ${LIBNAME}) + string(REGEX REPLACE "${CMAKE_IMPORT_LIBRARY_SUFFIX}\$" "" LIBNAME ${LIBNAME}) elseif("${LIB_TYPE}" STREQUAL "STATIC") string(REGEX REPLACE "${CMAKE_STATIC_LIBRARY_SUFFIX}\$" "" LIBNAME ${LIBNAME}) else() string(REGEX REPLACE "${CMAKE_SHARED_LIBRARY_SUFFIX}\$" "" LIBNAME ${LIBNAME}) + + # Also handle tbd libraries on OS X + if(TARGET_OSX) + string(REGEX REPLACE ".tbd\$" "" LIBNAME ${LIBNAME}) + endif() endif() set(${OUTPUT_VARIABLE} ${LIBNAME} PARENT_SCOPE) @@ -249,7 +275,7 @@ macro(resolved_lib_list_to_link_line LINK_LINE_VAR DIRS_VAR) # ARGN: LIB_PATH_LI string(TOLOWER "${FRAMEWORK_BASENAME}" FRAMEWORK_BASENAME_LCASE) list(APPEND ${LINK_LINE_VAR} "-framework" "${FRAMEWORK_BASENAME_LCASE}") - elseif(EXISTS "${LIBRARY}") + elseif(IS_ABSOLUTE "${LIBRARY}") if(NOT IS_DIRECTORY "${LIBRARY}") # full path to library diff --git a/cmake/NetlibConfig.cmake b/cmake/NetlibConfig.cmake index 4d426d7e5..657b57812 100644 --- a/cmake/NetlibConfig.cmake +++ b/cmake/NetlibConfig.cmake @@ -1,35 +1,35 @@ -# This script sets up a target based on the math libraries currently configured: -# netlib -- linear algebra libraries (blas and lapack), arpack, and whatever supporting math libraries are necessary. -# do NOT link any of the netlib libraries directly except through the netlib target. That will not work when MKL is enabled. -# Also, make ABSOLUTELY sure that fftw is AHEAD OF netlib in the link order of any targets that use them together. -# This is so that it overrides MKL's weird partial fftw interface. If you do not do this, you may get undefined behavior. - -set(NETLIB_LIBRARIES "") - -# basic linear algebra libraries -if(mkl_ENABLED) - list(APPEND NETLIB_LIBRARIES ${MKL_FORTRAN_LIBRARIES}) - - #this affects all Amber programs - add_definitions(-DMKL) -else() - list(APPEND NETLIB_LIBRARIES blas lapack) -endif() - -# arpack -if(arpack_ENABLED) - list(APPEND NETLIB_LIBRARIES arpack) -endif() - -# if the system lacks a C99 complex library, use our own implementation -if(c9x-complex_ENABLED) - list(APPEND NETLIB_LIBRARIES mc) -endif() - -# link system math library if it exists -list(APPEND NETLIB_LIBRARIES C::Math) - - -# -------------------------------------------------------------------- - -import_libraries(netlib LIBRARIES ${NETLIB_LIBRARIES}) +# This script sets up a target based on the math libraries currently configured: +# netlib -- linear algebra libraries (blas and lapack), arpack, and whatever supporting math libraries are necessary. +# do NOT link any of the netlib libraries directly except through the netlib target. That will not work when MKL is enabled. +# Also, make ABSOLUTELY sure that fftw is AHEAD OF netlib in the link order of any targets that use them together. +# This is so that it overrides MKL's weird partial fftw interface. If you do not do this, you may get undefined behavior. + +set(NETLIB_LIBRARIES "") + +# basic linear algebra libraries +if(mkl_ENABLED) + list(APPEND NETLIB_LIBRARIES ${MKL_FORTRAN_LIBRARIES}) + + #this affects all Amber programs + add_definitions(-DMKL) +else() + list(APPEND NETLIB_LIBRARIES blas lapack) +endif() + +# arpack +if(arpack_ENABLED) + list(APPEND NETLIB_LIBRARIES arpack) +endif() + +# if the system lacks a C99 complex library, use our own implementation +if(c9x-complex_ENABLED) + list(APPEND NETLIB_LIBRARIES mc) +endif() + +# link system math library if it exists +list(APPEND NETLIB_LIBRARIES C::Math) + + +# -------------------------------------------------------------------- + +import_libraries(netlib LIBRARIES ${NETLIB_LIBRARIES}) diff --git a/cmake/OpenMPConfig.cmake b/cmake/OpenMPConfig.cmake index 67b3e4761..786d90748 100644 --- a/cmake/OpenMPConfig.cmake +++ b/cmake/OpenMPConfig.cmake @@ -1,108 +1,111 @@ -#Cmake config file for OpenMP -option(OPENMP "Use OpenMP for shared-memory parallelization." FALSE) - -include(ParallelizationConfig) - -if(OPENMP) - if(DRAGONEGG) - message(FATAL_ERROR "OpenMP is not compatible with Dragonegg. Disable one or the other to build.") - endif() - - find_package(OpenMP) - - # check that OpenMP was found for each enabled language - foreach(LANG ${ENABLED_LANGUAGES}) - if(NOT OpenMP_${LANG}_FOUND) - message(FATAL_ERROR "You requested OpenMP support, but your ${LANG} compiler doesn't seem to support OpenMP. Please set OPENMP to FALSE, or switch to a compiler that supports it.") - endif() - endforeach() - - foreach(LANG ${ENABLED_LANGUAGES}) - # add libraries to library tracker - using_external_libraries(${OpenMP_${LANG}_LIBRARIES}) - endforeach() - - # Add OpenMP support to an object library - function(openmp_object_library TARGET LANGUAGE) - - # Note: In CMake 3.12, you can link a target to an object library directly - # to apply its interface properties. However, we don't have that feature yet. - target_compile_options(${TARGET} PRIVATE $) - target_include_directories(${TARGET} PUBLIC $) - endfunction() - - # make an OpenMP version of the thing passed - # also allows switching out sources if needed - # INSTALL - causes the new target to get installed in the OpenMP component to the default location (BINDIR etc) - # usage: make_openmp_version( LANGUAGES [] [SWAP_SOURCES TO ] [INSTALL]) - function(make_openmp_version TARGET NEW_NAME) - - # parse arguments - # -------------------------------------------------------------------- - cmake_parse_arguments(MAKE_OPENMP "INSTALL" "" "LANGUAGES;SWAP_SOURCES;TO" ${ARGN}) - - if("${MAKE_OPENMP_LANGUAGES}" STREQUAL "") - message(FATAL_ERROR "Incorrect usage. At least one LANGUAGE should be provided.") - endif() - - if(NOT "${MAKE_OPENMP_UNPARSED_ARGUMENTS}" STREQUAL "") - message(FATAL_ERROR "Incorrect usage. Extra arguments provided.") - endif() - - - # figure out if it's an object library, and if so, use openmp_object_library() - get_property(TARGET_TYPE TARGET ${TARGET} PROPERTY TYPE) - - if("${TARGET_TYPE}" STREQUAL "OBJECT_LIBRARY") - set(IS_OBJECT_LIBRARY TRUE) - else() - set(IS_OBJECT_LIBRARY FALSE) - endif() - - if("${ARGN}" STREQUAL "") - message(FATAL_ERROR "make_openmp_version(): you must specify at least one LANGUAGE") - endif() - - # make a new one - # -------------------------------------------------------------------- - if("${MAKE_OPENMP_SWAP_SOURCES}" STREQUAL "" AND "${MAKE_OPENMP_TO}" STREQUAL "") - copy_target(${TARGET} ${NEW_NAME}) - else() - copy_target(${TARGET} ${NEW_NAME} SWAP_SOURCES ${MAKE_OPENMP_SWAP_SOURCES} TO ${MAKE_OPENMP_TO}) - endif() - - # this ensures that the new version builds after all of the target's dependencies - # that have been manually added with add_dependencies() have been satisfied. - # Yes it is a bit of an ugly hack, but since we can't copy dependencies, this is the next-best thing. - add_dependencies(${NEW_NAME} ${TARGET}) - - # apply OpenMP flags - # -------------------------------------------------------------------- - foreach(LANG ${MAKE_OPENMP_LANGUAGES}) - # validate arguments - if(NOT ("${LANG}" STREQUAL "C" OR "${LANG}" STREQUAL "CXX" OR "${LANG}" STREQUAL "Fortran")) - message(FATAL_ERROR "make_openmp_version(): invalid argument: ${LANG} is not a LANGUAGE") - endif() - - if(IS_OBJECT_LIBRARY) - openmp_object_library(${NEW_NAME} ${LANG}) - else() - target_link_libraries(${NEW_NAME} OpenMP::OpenMP_${LANG}) - endif() - - endforeach() - - # install if necessary - # -------------------------------------------------------------------- - if(MAKE_OPENMP_INSTALL) - if("${TARGET_TYPE}" STREQUAL "EXECUTABLE") - install(TARGETS ${NEW_NAME} DESTINATION ${BINDIR} COMPONENT OpenMP) - else() - install_libraries(${NEW_NAME} COMPONENT OpenMP) - endif() - endif() - - endfunction(make_openmp_version) - -endif() - +#Cmake config file for OpenMP +option(OPENMP "Use OpenMP for shared-memory parallelization." FALSE) + +include(ParallelizationConfig) + +if(OPENMP) + if(DRAGONEGG) + message(FATAL_ERROR "OpenMP is not compatible with Dragonegg. Disable one or the other to build.") + endif() + + find_package(OpenMPFixed) + + # check that OpenMP was found for each enabled language + foreach(LANG ${ENABLED_LANGUAGES}) + if(NOT OpenMP_${LANG}_FOUND) + message(FATAL_ERROR "You requested OpenMP support, but your ${LANG} compiler doesn't seem to support OpenMP. Please set OPENMP to FALSE, or switch to a compiler that supports it.") + endif() + endforeach() + + foreach(LANG ${ENABLED_LANGUAGES}) + # add libraries to library tracker + using_external_libraries(${OpenMP_${LANG}_LIBRARIES}) + endforeach() + + # Add OpenMP support to an object library + macro(openmp_object_library TARGET LANGUAGE) + if(MCPAR_WORKAROUND_ENABLED) + # use generator expression + set_property(TARGET ${TARGET} PROPERTY COMPILE_OPTIONS $<$:${OpenMP_${LANGUAGE}_OPTIONS}>) + else() + set_property(TARGET ${TARGET} PROPERTY COMPILE_OPTIONS ${OpenMP_${LANGUAGE}_OPTIONS}) + endif() + + target_include_directories(${TARGET} PUBLIC ${OpenMP_${LANGUAGE}_INCLUDE_PATH}) + endmacro() + + # make an OpenMP version of the thing passed + # also allows switching out sources if needed + # INSTALL - causes the new target to get installed in the OpenMP component to the default location (BINDIR etc) + # usage: make_openmp_version( LANGUAGES [] [SWAP_SOURCES TO ] [INSTALL]) + function(make_openmp_version TARGET NEW_NAME) + + # parse arguments + # -------------------------------------------------------------------- + cmake_parse_arguments(MAKE_OPENMP "INSTALL" "" "LANGUAGES;SWAP_SOURCES;TO" ${ARGN}) + + if("${MAKE_OPENMP_LANGUAGES}" STREQUAL "") + message(FATAL_ERROR "Incorrect usage. At least one LANGUAGE should be provided.") + endif() + + if(NOT "${MAKE_OPENMP_UNPARSED_ARGUMENTS}" STREQUAL "") + message(FATAL_ERROR "Incorrect usage. Extra arguments provided.") + endif() + + + # figure out if it's an object library, and if so, use openmp_object_library() + get_property(TARGET_TYPE TARGET ${TARGET} PROPERTY TYPE) + + if("${TARGET_TYPE}" STREQUAL "OBJECT_LIBRARY") + set(IS_OBJECT_LIBRARY TRUE) + else() + set(IS_OBJECT_LIBRARY FALSE) + endif() + + if("${ARGN}" STREQUAL "") + message(FATAL_ERROR "make_openmp_version(): you must specify at least one LANGUAGE") + endif() + + # make a new one + # -------------------------------------------------------------------- + if("${MAKE_OPENMP_SWAP_SOURCES}" STREQUAL "" AND "${MAKE_OPENMP_TO}" STREQUAL "") + copy_target(${TARGET} ${NEW_NAME}) + else() + copy_target(${TARGET} ${NEW_NAME} SWAP_SOURCES ${MAKE_OPENMP_SWAP_SOURCES} TO ${MAKE_OPENMP_TO}) + endif() + + # this ensures that the new version builds after all of the target's dependencies have been satisfied. + # Yes it is a bit of an ugly hack, but since we can't copy dependencies, this is the next-best thing. + add_dependencies(${NEW_NAME} ${TARGET}) + + # apply OpenMP flags + # -------------------------------------------------------------------- + foreach(LANG ${MAKE_OPENMP_LANGUAGES}) + # validate arguments + if(NOT ("${LANG}" STREQUAL "C" OR "${LANG}" STREQUAL "CXX" OR "${LANG}" STREQUAL "Fortran")) + message(FATAL_ERROR "make_openmp_version(): invalid argument: ${LANG} is not a LANGUAGE") + endif() + + if(IS_OBJECT_LIBRARY) + openmp_object_library(${NEW_NAME} ${LANG}) + else() + string(TOLOWER ${LANG} LANG_LOWERCASE) + target_link_libraries(${NEW_NAME} openmp_${LANG_LOWERCASE}) + endif() + + endforeach() + + # install if necessary + # -------------------------------------------------------------------- + if(MAKE_OPENMP_INSTALL) + if("${TARGET_TYPE}" STREQUAL "EXECUTABLE") + install(TARGETS ${NEW_NAME} DESTINATION ${BINDIR} COMPONENT OpenMP) + else() + install_libraries(${NEW_NAME} COMPONENT OpenMP) + endif() + endif() + + endfunction(make_openmp_version) + +endif() + diff --git a/cmake/PMEMDCompilerFlags.cmake b/cmake/PMEMDCompilerFlags.cmake index 4bdf0d919..d516f659c 100644 --- a/cmake/PMEMDCompilerFlags.cmake +++ b/cmake/PMEMDCompilerFlags.cmake @@ -44,7 +44,6 @@ set(PMEMD_DEFAULT_PRECISION SPFP) #------------------------------------------------------------------------------- if(${CMAKE_C_COMPILER_ID} STREQUAL "Intel") - if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") @@ -61,9 +60,26 @@ if(${CMAKE_C_COMPILER_ID} STREQUAL "Intel") list(APPEND PMEMD_CFLAGS -xHost) endif() endif() - endif() +elseif({CMAKE_C_COMPILER_ID} STREQUAL "IntelLLVM") + + if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") + + set(PMEMD_CFLAGS -O3 -mdynamic-no-pic -no-prec-div -ipo -xHost) + + else() + + set(PMEMD_CFLAGS -ipo -O3) + + if(SSE) + if(NOT "${SSE_TYPES}" STREQUAL "") + list(APPEND PMEMD_CFLAGS "-ax${SSE_TYPES}") + else() + list(APPEND PMEMD_CFLAGS -xHost) + endif() + endif() + endif() else() #use regular compiler optimization flags @@ -206,7 +222,20 @@ endif() option(GTI "Use GTI version of pmemd.cuda instead of AFE version" TRUE) if(CUDA) - set(PMEMD_NVCC_FLAGS -use_fast_math -O3) + if(HIP) + set(PMEMD_NVCC_FLAGS -O3) + # list(APPEND PMEMD_NVCC_FLAGS -ffast-math) + + list(APPEND PMEMD_NVCC_FLAGS -std=c++14) + + if(DISABLE_WARNINGS) + list(APPEND PMEMD_NVCC_FLAGS -w) + endif() + else() + set(PMEMD_NVCC_FLAGS -use_fast_math -O3) + + list(APPEND PMEMD_NVCC_FLAGS --std c++11) + endif() set(PMEMD_CUDA_DEFINES -DCUDA) @@ -218,12 +247,21 @@ if(CUDA) message(STATUS "Building the AFE version of pmemd.cuda") endif() - list(APPEND PMEMD_NVCC_FLAGS --std c++11) + if(MPI) list(APPEND PMEMD_NVCC_FLAGS -DMPICH_IGNORE_CXX_SEEK) - endif() + option(MVAPICH2GDR_GPU_DIRECT_COMM "Use MVAPICH2-GDR for inter-GPU communications. \ +This requires using MVAPICH2-GDR version 2.3.7 or later as your MPI." FALSE) +# TODO determine how to check for MVAPICH2-GDR +# if(MVAPICH2GDR_GPU_DIRECT_COMM AND NOT MVAPICH2GDR_GPU_DIRECT_COMM_ENABLED) +# message(FATAL_ERROR "MVAPICH2GDR_GPU_DIRECT_COMM is selected for inter-GPU communications but MVAPICH2-GDR was not found.") +# endif() + if(MVAPICH2GDR_GPU_DIRECT_COMM) + list(APPEND PMEMD_CUDA_DEFINES -DMVAPICH2GDR_GPU_DIRECT_COMM) + endif() + endif() option(NCCL "Use NCCL for inter-GPU communications." FALSE) if(NCCL AND NOT nccl_ENABLED) @@ -234,6 +272,10 @@ if(CUDA) list(APPEND PMEMD_CUDA_DEFINES -DNCCL) endif() + option(VKFFT "Use VkFFT instead of cuFFT/hipFFT" FALSE) + if(VKFFT) + list(APPEND PMEMD_CUDA_DEFINES -DVKFFT) + endif() endif() diff --git a/cmake/ParallelizationConfig.cmake b/cmake/ParallelizationConfig.cmake index a22b4d598..bef14ce5f 100644 --- a/cmake/ParallelizationConfig.cmake +++ b/cmake/ParallelizationConfig.cmake @@ -5,4 +5,32 @@ if(OPENMP OR MPI) set(PARALLEL TRUE) else() set(PARALLEL FALSE) +endif() + + +if(NOT DEFINED PARALLELIZATION_CONFIG_INCLUDED) + set(PARALLELIZATION_CONFIG_INCLUDED TRUE) + # -------------------------------------------------------------------- + # Mixing Compiler Parallelization Workaround + # -------------------------------------------------------------------- + + # Since cmake-buildscripts v1.1, MPI and OpenMP compiler flags are passed around via targets (mpi_cxx, openmp_fortran, etc.). + # All is fine and dandy when this setup is used to build single-language programs. + # However, we get in trouble when mixed language programs (like sff or pmemd) use OpenMP and MPI because flags for different compilers will get jammed together. + # The fix is to use CMake's $ generator expression so that the flags will be deleted if they are passed to the wrong compiler. + # However, this doesn't work on CMake < 3.3, or with Visual Studio, so we have to warn the user appropriately + + set(MCPAR_WORKAROUND_ENABLED FALSE) + + if(MIXING_COMPILERS AND PARALLEL) + if("${CMAKE_GENERATOR}" MATCHES "Visual Studio" AND ("${CMAKE_VERSION}" VERSION_LESS 3.10 OR "${CMAKE_VERSION}" VERSION_EQUAL 3.10)) + message(WARNING "You are using parallelization, and are mixing compilers from different vendors. This is not supported with Visual Studio with this CMake version \ +due to a CMake technical limitation. \ +You may get compiler errors caused by the wrong flags getting passed to compilers on mixed-language programs. To build in this configuration, please use NMake or JOM, or upgrade to \ +CMake >= 3.11.") + else() + set(MCPAR_WORKAROUND_ENABLED TRUE) + endif() + endif() + endif() \ No newline at end of file diff --git a/cmake/Policies.cmake b/cmake/Policies.cmake index 1c9e3e120..b974e1c3a 100644 --- a/cmake/Policies.cmake +++ b/cmake/Policies.cmake @@ -1,5 +1,5 @@ # set all policies added in 3.8.1 or earlier to NEW behavior -cmake_policy(VERSION 3.9.0) +cmake_policy(VERSION 3.8.1) if(POLICY CMP0073) #NEW: don't generate xxx_LIB_DEPENDS cache entries (which screw up the build when switching between bundled and external libraries) diff --git a/cmake/PythonBuildConfig.cmake b/cmake/PythonBuildConfig.cmake index bef91b98f..24486c729 100644 --- a/cmake/PythonBuildConfig.cmake +++ b/cmake/PythonBuildConfig.cmake @@ -70,8 +70,7 @@ skip building Python packages, or set DOWNLOAD_MINICONDA to TRUE to create a pyt # -------------------------------------------------------------------- # tkinter's capitalization changes based on the python version check_python_package(tkinter HAVE_TKINTER) - check_python_package(Tkinter HAVE_TKINTER) - + if(NOT HAVE_TKINTER) message(FATAL_ERROR "Could not find the Python Tkinter package. You must install tk through your package manager (python-tk/python3-tk on Ubuntu, tk on Arch),\ and the tkinter Python package will get installed. If you cannot get Tkinter, disable BUILD_PYTHON to skip building Python packages, or enable DOWNLOAD_MINICONDA.") @@ -169,22 +168,14 @@ skip building Python packages, or set DOWNLOAD_MINICONDA to TRUE to create a pyt cmake_parse_arguments(IPL "" "BUILD_DIR" "SCRIPT_ARGS" ${ARGN}) - if("${IPL_BUILD_DIR}" STREQUAL "") - # use default build dir - set(IPL_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/python-build) - endif() - list_to_space_separated(SCRIPT_ARGS_SPC ${IPL_SCRIPT_ARGS}) - + install(CODE " ${FIX_BACKSLASHES_CMD} execute_process( COMMAND \"${CMAKE_COMMAND}\" -E env - ${PYTHONPATH_SET_CMD} \"${PYTHON_EXECUTABLE}\" - ./setup.py build -b \"${IPL_BUILD_DIR}\" - install -f ${PYTHON_PREFIX_ARG} - \"--install-scripts=\${CMAKE_INSTALL_PREFIX_BS}bin\" + ./setup.py install -f ${PYTHON_PREFIX_ARG} --single-version-externally-managed --root / ${SCRIPT_ARGS_SPC} WORKING_DIRECTORY \"${CMAKE_CURRENT_SOURCE_DIR}\")" COMPONENT Python) diff --git a/cmake/PythonInterpreterConfig.cmake b/cmake/PythonInterpreterConfig.cmake index c3ff54ea4..e5c068d31 100644 --- a/cmake/PythonInterpreterConfig.cmake +++ b/cmake/PythonInterpreterConfig.cmake @@ -57,21 +57,29 @@ if(DOWNLOAD_MINICONDA) unset(ENV{_CONDA_PYTHON2}) endif() - set(MINICONDA_VERSION latest) - option(MINICONDA_USE_PY3 "If true, Amber will download a Python 3 miniconda when DOWNLOAD_MINICONDA is enabled. Otherwise, Python 2.7 Miniconda will get downloaded." TRUE) - + # Workaround for CentOS-7 & AmberTools23: + # - add the option to install a specific version of miniconda + # - add the MINICONDA_AUTO variable to track this later on (UseMiniconda.cmake) + # Recommended miniconda version for CentOS 7 (as of 2023-04): py38_4.12.0 + if(NOT DEFINED MINICONDA_VERSION) + set(MINICONDA_VERSION latest) + set(MINICONDA_AUTO TRUE) + else() + set(MINICONDA_AUTO FALSE) + endif() + include(UseMiniconda) download_and_use_miniconda() - + set(PYTHON_EXECUTABLE ${MINICONDA_PYTHON}) set(HAS_PYTHON TRUE) - + if(HOST_WINDOWS) list(APPEND CMAKE_PROGRAM_PATH "${MINICONDA_INSTALL_DIR}" "${MINICONDA_INSTALL_DIR}/Scripts") else() list(APPEND CMAKE_PROGRAM_PATH "${MINICONDA_INSTALL_DIR}/bin") endif() - + else() option(USE_CONDA_LIBS "Use system libraries from a found Anaconda installation" FALSE) diff --git a/cmake/Replace-runtime.cmake b/cmake/Replace-runtime.cmake index bf8b1b41e..26a7372d2 100644 --- a/cmake/Replace-runtime.cmake +++ b/cmake/Replace-runtime.cmake @@ -1,23 +1,23 @@ -#cmake script run as a custom command to do textual replaces at build time -#eliminates the need for sed - -#usage: define the following variables on the command line and run the scripts: -#INPUTFILE - file to input -#OUTPUTFILE - file to output -#TO_REPLACE - list of strings to be replaced -#REPLACEMENT - list of text to replace with -# The first element of TO_REPLACE is matched with the first element of REPLACEMENT, and so on -file(READ ${INPUTFILE} INPUT_TEXT) - -foreach(TO_REPLACE_STRING ${TO_REPLACE}) - - #get the index of the current to_replace string - list(FIND TO_REPLACE ${TO_REPLACE_STRING} REPLACE_INDEX) - - #look up the corresponding replacement string - list(GET REPLACEMENT ${REPLACE_INDEX} REPLACEMENT_STRING) - - string(REPLACE ${TO_REPLACE_STRING} ${REPLACEMENT_STRING} INPUT_TEXT "${INPUT_TEXT}") -endforeach() - +#cmake script run as a custom command to do textual replaces at build time +#eliminates the need for sed + +#usage: define the following variables on the command line and run the scripts: +#INPUTFILE - file to input +#OUTPUTFILE - file to output +#TO_REPLACE - list of strings to be replaced +#REPLACEMENT - list of text to replace with +# The first element of TO_REPLACE is matched with the first element of REPLACEMENT, and so on +file(READ ${INPUTFILE} INPUT_TEXT) + +foreach(TO_REPLACE_STRING ${TO_REPLACE}) + + #get the index of the current to_replace string + list(FIND TO_REPLACE ${TO_REPLACE_STRING} REPLACE_INDEX) + + #look up the corresponding replacement string + list(GET REPLACEMENT ${REPLACE_INDEX} REPLACEMENT_STRING) + + string(REPLACE ${TO_REPLACE_STRING} ${REPLACEMENT_STRING} INPUT_TEXT "${INPUT_TEXT}") +endforeach() + file(WRITE ${OUTPUTFILE} "${INPUT_TEXT}") \ No newline at end of file diff --git a/cmake/RunnablePrograms.cmake b/cmake/RunnablePrograms.cmake index 436494236..937dc03ca 100644 --- a/cmake/RunnablePrograms.cmake +++ b/cmake/RunnablePrograms.cmake @@ -3,9 +3,8 @@ # Must be included after MPIConfig -set(EXECUTABLES_TO_IMPORT ucpp utilMakeHelp nab2c mpinab2c rule_parse) - -set(EXECUTABLES_TO_IMPORT_REQUIRED TRUE TRUE TRUE TRUE ${MPI} TRUE) # true if the corresponding executable is needed to build Amber +set(EXECUTABLES_TO_IMPORT utilMakeHelp) +set(EXECUTABLES_TO_IMPORT_REQUIRED TRUE) # true if the corresponding executable is needed to build Amber if(USE_HOST_TOOLS) @@ -52,4 +51,4 @@ else() set(RUNNABLE_${EXECUTABLE} ${EXECUTABLE}) set(HAVE_RUNNABLE_${EXECUTABLE} TRUE) endforeach() -endif() \ No newline at end of file +endif() diff --git a/cmake/SanderConfig.cmake b/cmake/SanderConfig.cmake index 8b9ac940b..2eb30f306 100644 --- a/cmake/SanderConfig.cmake +++ b/cmake/SanderConfig.cmake @@ -23,6 +23,24 @@ if(BUILD_SANDER_PUPIL AND pupil_DISABLED) message(FATAL_ERROR "You enabled sander's PUPIL support, but PUPIL was not found.") endif() +# ------------------------------------------------------------- +# QUICK + +if(HIP) +#disable QUICK for HIP for now +option(BUILD_QUICK "Enable building QUICK and its associated sander variant." FALSE) +else() +option(BUILD_QUICK "Enable building QUICK and its associated sander variant." TRUE) +endif() +# ------------------------------------------------------------- +# reaxff-puremd (QMMM) + +option(BUILD_REAXFF_PUREMD "Enable building reaxff-puremd." FALSE) + +# ------------------------------------------------------------- +# ffq + +option(BUILD_FFQ "Enable building ffq." FALSE) #--------------------------------------------------- # make the SANDER report for the build report @@ -56,4 +74,13 @@ if(MPI) endif() endif() -list_to_space_separated(SANDER_VARIANTS_STRING ${SANDER_VARIANTS}) \ No newline at end of file +if(BUILD_QUICK) + if(MPI) + list(APPEND SANDER_VARIANTS QUICK-MPI) + endif() + if(CUDA) + list(APPEND SANDER_VARIANTS QUICK-CUDA) + endif() +endif() + +list_to_space_separated(SANDER_VARIANTS_STRING ${SANDER_VARIANTS}) diff --git a/cmake/Shorthand.cmake b/cmake/Shorthand.cmake index 5efe96335..9c34b50f9 100644 --- a/cmake/Shorthand.cmake +++ b/cmake/Shorthand.cmake @@ -9,23 +9,21 @@ function(install_libraries) # LIBRARIES... cmake_parse_arguments( INSTALL_LIBS "" - "SUBDIR;COMPONENT;EXPORT" + "SUBDIR;COMPONENT" "" ${ARGN}) - if(NOT "${INSTALL_LIBS_COMPONENT}" STREQUAL "") - set(COMPONENT_ARG COMPONENT ${INSTALL_LIBS_COMPONENT}) - endif() - if(NOT "${INSTALL_LIBS_EXPORT}" STREQUAL "") - set(EXPORT_ARG EXPORT ${INSTALL_LIBS_EXPORT}) - endif() - - install(TARGETS ${INSTALL_LIBS_UNPARSED_ARGUMENTS} - ${COMPONENT_ARG} - ${EXPORT_ARG} + if("${INSTALL_LIBS_COMPONENT}" STREQUAL "") + install(TARGETS ${INSTALL_LIBS_UNPARSED_ARGUMENTS} + RUNTIME DESTINATION ${DLLDIR} + ARCHIVE DESTINATION ${LIBDIR}/${INSTALL_LIBS_SUBDIR} + LIBRARY DESTINATION ${LIBDIR}/${INSTALL_LIBS_SUBDIR}) + else() + install(TARGETS ${INSTALL_LIBS_UNPARSED_ARGUMENTS} COMPONENT ${INSTALL_LIBS_COMPONENT} RUNTIME DESTINATION ${DLLDIR} ARCHIVE DESTINATION ${LIBDIR}/${INSTALL_LIBS_SUBDIR} LIBRARY DESTINATION ${LIBDIR}/${INSTALL_LIBS_SUBDIR}) + endif() endfunction(install_libraries) #Shorthand for linking multiple targets to one or more libraries. diff --git a/cmake/TryLinkLibrary.cmake b/cmake/TryLinkLibrary.cmake index 90eeb1237..21f7d312a 100644 --- a/cmake/TryLinkLibrary.cmake +++ b/cmake/TryLinkLibrary.cmake @@ -36,10 +36,11 @@ By default, source code for a void no-argument function prototype is generated a FUNC_DECLARATION - Optional code to use in place of the default function declaration in C and CXX. Must prepare the named function to be called later in the code. Can be multiline. Can also include the library's header if that is easier to work with. FUNC_CALL - Optional code to use to call the function. Can be multiline. NOTE: CMake argument passing weirdness prevents a trailing semicolon from being passed in FUNC_CALL. For C and C++, a trailing semicolon is added to the code passed. -Under some conditions, if it appears that nonexistant libraries were passed to the LIBRARIES argument, the check will immediately report false since preceding code has clearly failed to find -the needed libraries. This will happen if: +Under some conditions, if it appears that nonexistant libraries were passed to the LIBRARIES argument or nonexistant directories were passed to INCLUDES, the check will immediately +report false since preceding code has clearly failed to find the needed libraries. This will happen if: * A library is not a target and ends in -NOTFOUND * A library is an imported target name (containing "::"), but does not currently exist +* An include ends in -NOTFOUND The following variables may be set before calling this macro to modify the way the check is run: @@ -150,6 +151,13 @@ int main(int argc, char** args) endif() endforeach() + # Also check for NOTFOUND includes + foreach(INCLUDE ${TLL_INCLUDES}) + if("${INCLUDE}" MATCHES "-NOTFOUND$") + set(MISSING_LIBRARIES TRUE) + endif() + endforeach() + if(MISSING_LIBRARIES) set(${RESULT_VAR} FALSE PARENT_SCOPE) return() diff --git a/cmake/UseMiniconda.cmake b/cmake/UseMiniconda.cmake index 03bfd1754..a903a0618 100644 --- a/cmake/UseMiniconda.cmake +++ b/cmake/UseMiniconda.cmake @@ -15,13 +15,9 @@ function(download_and_use_miniconda) set(MINICONDA_INSTALL_DIR ${MINICONDA_TEMP_DIR}/install) set(MINICONDA_INSTALL_DIR ${MINICONDA_TEMP_DIR}/install PARENT_SCOPE) # need to keep this around for install_minconda() - - if(MINICONDA_USE_PY3) - set(PYTHON_MAJOR_RELEASE 3) - else() - set(PYTHON_MAJOR_RELEASE 2) - endif() - + + set(PYTHON_MAJOR_RELEASE 3) + set(MINICONDA_STAMP_FILE ${CMAKE_BINARY_DIR}/CMakeFiles/miniconda-setup-py${PYTHON_MAJOR_RELEASE}-v${MINICONDA_VERSION}.stamp) # figure out executable paths @@ -48,12 +44,8 @@ function(download_and_use_miniconda) return() endif() - if(MINICONDA_USE_PY3) - message(STATUS "Downloading Python 3 Miniconda") - else() - message(STATUS "Downloading Python 2.7 Miniconda") - endif() - + message(STATUS "Downloading Python 3 Miniconda") + # Figure out the OS part of the URL if(TARGET_OSX) message(STATUS "Detected Mac OS X operating system. Downloading the Mac installer") @@ -77,8 +69,13 @@ function(download_and_use_miniconda) # Figure out the bitiness part of the URL if(TARGET_OSX) - # OS X does not have a 32 bit miniconda - set(CONTINUUM_BITS "x86_64") + if("${TARGET_ARCH}" STREQUAL "x86_64") + message(STATUS "Using 64 bit miniconda") + set(CONTINUUM_BITS "x86_64") + elseif("${TARGET_ARCH}" MATCHES "arm64.*") + message(STATUS "Using arm64 miniconda") + set(CONTINUUM_BITS "arm64") + endif() else() if("${TARGET_ARCH}" STREQUAL "x86_64") message(STATUS "Using 64 bit miniconda") @@ -86,6 +83,9 @@ function(download_and_use_miniconda) elseif("${TARGET_ARCH}" STREQUAL "i386") message(STATUS "Using 32 bit miniconda") set(CONTINUUM_BITS "x86") + elseif("${TARGET_ARCH}" MATCHES "arm64") + message(STATUS "Using arm64 miniconda") + set(CONTINUUM_BITS "aarch64") else() message(WARNING "Unable to detect machine bits. Falling back to downloading 32 bit x86 Miniconda.") set(CONTINUUM_BITS "x86") @@ -137,7 +137,7 @@ function(download_and_use_miniconda) string(REPLACE "/" "\\" MINICONDA_INSTALL_DIR_BACKSLASHES "${MINICONDA_INSTALL_DIR}") set(MINICONDA_INSTALLER_COMMANDLINE ${MINICONDA_INSTALLER} /AddToPath=0 /S "/D=${MINICONDA_INSTALL_DIR_BACKSLASHES}") else() - set(MINICONDA_INSTALLER_COMMANDLINE ${CMAKE_COMMAND} -E env ${CMAKE_ENV_ARGS} ${MINICONDA_INSTALLER} -b -p "${MINICONDA_INSTALL_DIR}") + set(MINICONDA_INSTALLER_COMMANDLINE bash ${MINICONDA_INSTALLER} -b -p "${MINICONDA_INSTALL_DIR}") endif() execute_process(COMMAND ${MINICONDA_INSTALLER_COMMANDLINE} @@ -148,13 +148,13 @@ function(download_and_use_miniconda) message(STATUS "Updating and installing required and optional packages...") - - execute_process(COMMAND ${CONDA} update conda -y) - execute_process(COMMAND ${MINICONDA_PYTHON} -m pip install pip --upgrade) - if (MINICONDA_USE_PY3) - # Revert setuptools as a temporary workaround to recent changes to path mangling behavior - execute_process(COMMAND ${MINICONDA_PYTHON} -m pip install setuptools==47.3.1) + + # if the miniconda version has been specified (-DMINICONDA_VERSION=...) + # then do not update conda + if(MINICONDA_AUTO) + execute_process(COMMAND ${CONDA} update conda -y) endif() + execute_process(COMMAND ${MINICONDA_PYTHON} -m pip install pip --upgrade) # Prefer non-mkl packages. # This is because if Amber is using MKL, when Python programs run they will try to talk to two @@ -162,6 +162,9 @@ function(download_and_use_miniconda) # Amber was linked with. # So, to fix this, we make sure Miniconda is not using MKL. execute_process(COMMAND ${CONDA} install -y nomkl) + + execute_process(COMMAND ${CONDA} install -y -c conda-forge f90nml mrcfile pdb2pqr) + execute_process(COMMAND ${CONDA} install -y pandas) execute_process(COMMAND ${CONDA} install -y -q conda-build numpy scipy cython=0.29 ipython notebook pytest RESULT_VARIABLE PACKAGE_INSTALL_RETVAL) @@ -247,7 +250,10 @@ function(install_miniconda) installtime_create_symlink(${CMAKE_INSTALL_POSTFIX}miniconda/bin/conda ${BINDIR}/amber.conda Python) installtime_create_symlink(${CMAKE_INSTALL_POSTFIX}miniconda/bin/ipython ${BINDIR}/amber.ipython Python) installtime_create_symlink(${CMAKE_INSTALL_POSTFIX}miniconda/bin/jupyter ${BINDIR}/amber.jupyter Python) - installtime_create_symlink(${CMAKE_INSTALL_POSTFIX}miniconda/bin/pip ${BINDIR}/amber.pip Python) + installtime_create_symlink(${CMAKE_INSTALL_POSTFIX}miniconda/bin/pdb2pqr ${BINDIR}/pdb2pqr Python) + installtime_create_symlink(${CMAKE_INSTALL_POSTFIX}miniconda/bin/propka3 ${BINDIR}/propka3 Python) + # Some users don't seem to end up with a miniconda/bin/pip file: + # installtime_create_symlink(${CMAKE_INSTALL_POSTFIX}miniconda/bin/pip ${BINDIR}/amber.pip Python) endif() add_subdirectory(${CMAKE_SOURCE_DIR}/cmake/FixCondaShebang) diff --git a/cmake/VerifyCompilerConfig.cmake b/cmake/VerifyCompilerConfig.cmake index cf41f355f..4a4a7ad1e 100644 --- a/cmake/VerifyCompilerConfig.cmake +++ b/cmake/VerifyCompilerConfig.cmake @@ -1,6 +1,7 @@ # This file is run during 2nd init to check the results of AmberCompilerConfig. -# the necessity for this check is discussed here: https://github.com/Amber-MD/CMakeConfigScripts/issues/4 +# the necessity for this check is discussed here: +# https://github.com/Amber-MD/CMakeConfigScripts/issues/4 if("${COMPILER}" STREQUAL GNU) foreach(LANG C CXX) @@ -17,6 +18,27 @@ CMAKE_C_COMPILER and CMAKE_CXX_COMPILER to point to gcc and g++ and use AUTO for ") endif() endforeach() + +# check minimum GNU compiler versions: + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) + message(STATUS "") + message("************************************************************") + message("Error: Amber requires at least g++-6.0") + message("See https://ambermd.org/Installation.php for more info") + message("************************************************************") + message(STATUS "") + message(FATAL_ERROR) + endif() + if (CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 6.0) + message(STATUS "") + message("************************************************************") + message("Error: Amber requires at least gfortran-6.0") + message("See https://ambermd.org/Installation.php for more info") + message("************************************************************") + message(STATUS "") + message(FATAL_ERROR) + endif() + endif() # try to detect and work around issue #92: https://gitlab.ambermd.org/amber/amber/issues/92 diff --git a/cmake/WhichTools.cmake b/cmake/WhichTools.cmake index a5c112d07..a28b2e7ad 100644 --- a/cmake/WhichTools.cmake +++ b/cmake/WhichTools.cmake @@ -10,7 +10,9 @@ # There are many, many reasons that you would want a tool not to build, and in some cases more than one can occur at the same time # For that reason, and because order matters, we use a blacklist model for deciding what tools to build. # We start with all of them enabled (except the ones not in release builds), and pare down this list for various reasons in the logic below. -set(AMBER_TOOLS +set(AMBER_TOOLS + + #3rd party programs: see 3rdPartyTools.cmake # utility routines and libraries: gbnsr6 @@ -31,6 +33,7 @@ sqm reduce sebomd emil +kmmd ndiff-2.00 gem.pmemd xray @@ -43,7 +46,6 @@ ambpdb pbsa sff rism -nab etc # mdgx: @@ -64,15 +66,25 @@ paramfit # FEW FEW -# amberlite -amberlite - # cphstats and cestats cphstats # quick quick +# cew +cew + +# tcpb +tcpb-cpp +tcpb-cpp/pytcpb + +# reaxff-puremd +reaxff_puremd + +# ffq +ffq + # nfe-umbrella-slice nfe-umbrella-slice @@ -85,7 +97,6 @@ mmpbsa_py pymsmt pysander pytraj -pymdgx pdb4amber packmol_memgen @@ -95,6 +106,11 @@ moft # pmemd gpu_utils pmemd + +# nabc +nabc + +fe-toolkit ) # list of tools in the src directory instead of AmberTools/src @@ -105,9 +121,7 @@ set(TOOLS_IN_SRC if(NOT AMBER_RELEASE) # these tools are in the git version of amber, but not in the released source list(APPEND AMBER_TOOLS - chamber - ptraj - nabc) + ptraj) endif() # save an unaltered copy for disable_all_tools_except() @@ -170,22 +184,23 @@ endmacro(tool_depends) # tool dependencies (manually determined by looking through every single CMake script) # -------------------------------------------------------------------- tool_depends(addles lib) -tool_depends(amberlite nab) tool_depends(antechamber cifparse) -tool_depends(etc nab) +tool_depends(FEW mm_pbsa) tool_depends(gbnsr6 sff) -tool_depends(mm_pbsa nab lib) -tool_depends(mmpbsa_py nab lib) -tool_depends(nab sff pbsa cifparse) -tool_depends(nabc sff pbsa cifparse) +tool_depends(mm_pbsa nabc sff pbsa cifparse lib) +tool_depends(mmpbsa_py nabc lib) +tool_depends(nabc sff pbsa) tool_depends(nmode lib) tool_depends(nmr_aux cifparse lib) tool_depends(pbsa sander lib) -tool_depends(pymdgx mdgx) tool_depends(pysander sander) tool_depends(pytraj cpptraj) -tool_depends(quick sqm) -tool_depends(rism nab lib) +tool_depends(tcpb-cpp sqm) +tool_depends(tcpb-cpp/pytcpb tcpb-cpp) +tool_depends(cew lib) +tool_depends(quick sqm cew) +tool_depends(reaxff_puremd sqm) +tool_depends(rism lib) tool_depends(sander sqm pbsa sebomd emil lib) tool_depends(sebomd sander lib) tool_depends(sff pbsa) @@ -195,8 +210,6 @@ tool_depends(pmemd emil) # extra dependencies if FFT is enabled if(USE_FFT) - tool_depends(nab rism) - tool_depends(sff rism) tool_depends(sander rism) tool_depends(sebomd rism) endif() @@ -216,12 +229,12 @@ if(USE_FFT) message(FATAL_ERROR "RISM and PBSA FFT solver currently not built with cray compilers. Please disable USE_FFT.") endif() else() - disable_tools("Requires FFTW, but USE_FFT is disabled." rism mdgx) + disable_tools("Requires FFTW, but USE_FFT is disabled." rism mdgx moft) endif() #Python programs (controlled by BUILD_PYTHON option in PythonConfig.cmake) if(NOT BUILD_PYTHON) - disable_tools("Python programs are disabled" pysander pytraj pysmt mmpbsa_py parmed pymdgx packmol_memgen) + disable_tools("Python programs are disabled" pysander pytraj pymsmt mmpbsa_py parmed packmol_memgen tcpb-cpp/pytcpb) endif() if(STATIC) @@ -251,8 +264,22 @@ endif() # in-development programs option(BUILD_INDEV "Build Amber programs which are still being developed. These probably contain bugs, and may not be finished.") -if(NOT BUILD_INDEV) - disable_tools("In-development programs are disabled." quick pymdgx) + +if(NOT BUILD_QUICK) # note: option declared in SanderConfig.cmake to resolve circular dependency + disable_tool(quick "BUILD_QUICK is not enabled") + disable_tool(cew "BUILD_QUICK is not enabled") +endif() + +if(NOT BUILD_TCPB) # note: option declared in $AMBERHOME/CMakeLists.txt + disable_tools("BUILD_TCPB is not enabled" tcpb-cpp tcpb-cpp/pytcpb) +endif() + +if(NOT BUILD_REAXFF_PUREMD) # note: option declared in SanderConfig.cmake to resolve circular dependency + disable_tool(reaxff_puremd "BUILD_REAXFF_PUREMD is not enabled") +endif() + +if(NOT BUILD_FFQ) # note: option declared in SanderConfig.cmake to resolve circular dependency + disable_tool(ffq "BUILD_FFQ is not enabled") endif() if(NOT BUILD_SANDER_API) @@ -264,7 +291,7 @@ if(NOT BUILD_SANDER_LES) endif() if(CROSSCOMPILE) - disable_tools("Python programs with native libraries can't be cross-compiled (see Amber bug #337)" pysander pytraj pymdgx parmed) + disable_tools("Python programs with native libraries can't be cross-compiled (see Amber bug #337)" pysander pytraj parmed tcpb-cpp/pytcpb) endif() if(MINGW) @@ -287,15 +314,20 @@ if(NOT CUDA) disable_tool(gpu_utils "Requires CUDA") endif() +if(KMMD_DIR) + disable_tool(kmmd "Using external KMMD_DIR, so not building") +endif() + + # -------------------------------------------------------------------- # Disable certain sets of programs due to the build type # -------------------------------------------------------------------- if(CRAY) # In cray parallel modes, almost all tools are disabled. if(MPI) - disable_all_tools_except("Not supported on Cray in MPI mode" etc sff cpptraj cifparse mdgx nab rism parmed mmpbsa_py) + disable_all_tools_except("Not supported on Cray in MPI mode" etc sff cpptraj cifparse mdgx rism parmed tcpb-cpp/pytcpb mmpbsa_py) elseif(OPENMP) - disable_all_tools_except("Not supported on Cray in OpenMP mode" sff cifparse nab rism cpptraj pytraj saxs paramfit) + disable_all_tools_except("Not supported on Cray in OpenMP mode" sff cifparse rism cpptraj pytraj saxs paramfit) else() disable_tools("Not supported on Cray in serial mode" @@ -305,8 +337,10 @@ if(CRAY) nmr_aux etc mmpbsa - amberlite - quick) + quick + cew + tcpb-cpp + tcpb-cpp/pytcpb) endif() endif() diff --git a/cmake/get_prefix_relative_pythonpath.py b/cmake/get_prefix_relative_pythonpath.py index 93c8224ce..f391aa0ea 100644 --- a/cmake/get_prefix_relative_pythonpath.py +++ b/cmake/get_prefix_relative_pythonpath.py @@ -1,14 +1,14 @@ #!/usr/bin/env python # Script to find the python module install path relative to the base path that the interpreter is installed to. -import distutils.dist -import distutils.command.install +import setuptools.dist +import setuptools.command.install # use fake prefix which we can replace later, and which is unlikely to be in the real path REPLACE_PREFIX="/placeholder_to_be_replaced_with_real_prefix" -distrib = distutils.dist.Distribution() -install_cmd = distutils.command.install.install(distrib) +distrib = setuptools.dist.Distribution() +install_cmd = setuptools.command.install.install(distrib) install_cmd.prefix = REPLACE_PREFIX install_cmd.finalize_options() print(install_cmd.install_purelib.replace(REPLACE_PREFIX, "")) \ No newline at end of file diff --git a/cmake/gzip.cmake b/cmake/gzip.cmake index 77f9ebc5f..3c5cfb1bd 100644 --- a/cmake/gzip.cmake +++ b/cmake/gzip.cmake @@ -1,40 +1,40 @@ -# macro for uncompressing gzipped files. Can utilize (p)7zip and gunzip. -# un-gzips SOURCE into DESTINATION -# This does not create a target to force DESTINATION to be built, use add_custom_target to do that. - -#figure out which ungz command to use -find_program(GUNZIP_LOCATION gunzip DOC "Path to gunzip program. Set either this one, GZIP_LOCATION, or 7Z_LOCATION to build amber.") -find_program(GZIP_LOCATION gzip DOC "Path to gzip program. Set either this one, GUNZIP_LOCATION, or 7Z_LOCATION to build amber.") - -find_program(7Z_LOCATION 7z 7za DOC "Path to the (p)7-zip command line program, either 7z or 7za. Set either this one, GZIP_LOCATION, or GUNZIP_LOCATION to build amber.") - -if(GZIP_LOCATION) - set(UNZIP_COMMAND ${GZIP_LOCATION} -dc) -elseif(GUNZIP_LOCATION) - set(UNZIP_COMMAND ${GUNZIP_LOCATION} -c) -elseif(7Z_LOCATION) - set(UNZIP_COMMAND ${7Z_LOCATION} -x -so) -else() - #cause the searches to be repeated - unset(GZIP_LOCATION CACHE) - unset(GUNZIP_LOCATION CACHE) - unset(7Z_LOCATION CACHE) - - if(WIN32) - message(SEND_ERROR "A gzip unarchiver is required to build AMBER, but was not found. Please install gzip or 7-zip and set GZIP_LOCATION, GUNZIP_LOCATION, or 7Z_LOCATION to the gzip or 7z executable.") - else() - message(SEND_ERROR "A gzip unarchiver is required to build AMBER, but was not found. Please install gzip, gunzip, or p7zip.") - endif() -endif() - -#message(STATUS "Un-gzip command: ${UNZIP_COMMAND}") - -macro(ungzip_file SOURCE DESTINATION) - - add_custom_command( - OUTPUT ${DESTINATION} - COMMAND ${UNZIP_COMMAND} ${SOURCE} > ${DESTINATION} - DEPENDS ${ZIPPED_DATAFILE} - VERBATIM) - +# macro for uncompressing gzipped files. Can utilize (p)7zip and gunzip. +# un-gzips SOURCE into DESTINATION +# This does not create a target to force DESTINATION to be built, use add_custom_target to do that. + +#figure out which ungz command to use +find_program(GUNZIP_LOCATION gunzip DOC "Path to gunzip program. Set either this one, GZIP_LOCATION, or 7Z_LOCATION to build amber.") +find_program(GZIP_LOCATION gzip DOC "Path to gzip program. Set either this one, GUNZIP_LOCATION, or 7Z_LOCATION to build amber.") + +find_program(7Z_LOCATION 7z 7za DOC "Path to the (p)7-zip command line program, either 7z or 7za. Set either this one, GZIP_LOCATION, or GUNZIP_LOCATION to build amber.") + +if(GZIP_LOCATION) + set(UNZIP_COMMAND ${GZIP_LOCATION} -dc) +elseif(GUNZIP_LOCATION) + set(UNZIP_COMMAND ${GUNZIP_LOCATION} -c) +elseif(7Z_LOCATION) + set(UNZIP_COMMAND ${7Z_LOCATION} -x -so) +else() + #cause the searches to be repeated + unset(GZIP_LOCATION CACHE) + unset(GUNZIP_LOCATION CACHE) + unset(7Z_LOCATION CACHE) + + if(WIN32) + message(SEND_ERROR "A gzip unarchiver is required to build AMBER, but was not found. Please install gzip or 7-zip and set GZIP_LOCATION, GUNZIP_LOCATION, or 7Z_LOCATION to the gzip or 7z executable.") + else() + message(SEND_ERROR "A gzip unarchiver is required to build AMBER, but was not found. Please install gzip, gunzip, or p7zip.") + endif() +endif() + +#message(STATUS "Un-gzip command: ${UNZIP_COMMAND}") + +macro(ungzip_file SOURCE DESTINATION) + + add_custom_command( + OUTPUT ${DESTINATION} + COMMAND ${UNZIP_COMMAND} ${SOURCE} > ${DESTINATION} + DEPENDS ${ZIPPED_DATAFILE} + VERBATIM) + endmacro(ungzip_file) \ No newline at end of file diff --git a/cmake/hanjianwei/FindMKL.cmake b/cmake/hanjianwei/FindMKL.cmake index a3d04cc02..bed52f672 100644 --- a/cmake/hanjianwei/FindMKL.cmake +++ b/cmake/hanjianwei/FindMKL.cmake @@ -191,10 +191,10 @@ endif() ############################ OpenMP Library ########################## if(MKL_MULTI_THREADED) - find_package(OpenMP) + find_package(OpenMPFixed) # NOTE: we don't want to link against the imported targets, because that would apply OpenMP compile flags to anything linked to MKL - set(MKL_OMP_LIBRARY ${OpenMP_C_FLAGS}) + set(MKL_OMP_LIBRARY ${OpenMP_C_OPTIONS} ${OpenMP_C_LIBRARIES}) else() set(MKL_OMP_LIBRARY "") endif() @@ -277,7 +277,7 @@ endif() find_package(CMath) list(APPEND MKL_NEEDED_LIBNAMES CMath_FOUND) -# Build the final library lists +# Build the final library lists set(MKL_LIBRARIES ${LIB_LIST_PREFIX} mkl::core mkl::threading mkl::interface ${LIB_LIST_SUFFIX} ${MKL_LIBDL} ${MKL_PTHREAD_LIB} ${MKL_OMP_LIBRARY} C::Math) set(MKL_FORTRAN_LIBRARIES ${LIB_LIST_PREFIX} mkl::core mkl::threading mkl::fortran_interface ${LIB_LIST_SUFFIX} ${MKL_LIBDL} ${MKL_PTHREAD_LIB} ${MKL_OMP_LIBRARY} C::Math) diff --git a/cmake/nab.cmake b/cmake/nab.cmake deleted file mode 100644 index 481241d2f..000000000 --- a/cmake/nab.cmake +++ /dev/null @@ -1,125 +0,0 @@ -#Macro which invokes nab2c and compiles .nab files into .c files - -# It is used instead of the nab wrapper program because -# the nab wrapper is hardcoded to use the installed directory structure, and would need significant changes to work with the CMake structure - -# It's also just kind of nice to build the c files in CMake instead of through NAB - -# the directory where the nab headers are in the source tree -set(NAB_HEADER_DIR ${CMAKE_SOURCE_DIR}/AmberTools/src/nab) - -#compiles NAB_FILES into GENERATED_C_FILES -#add GENERATED_C_FILES as source code to a target -#usage: nab_compile( [MPI] ) -function(nab_compile GENERATED_C_FILES) - - cmake_parse_arguments(NABCOMP "MPI" "" "" ${ARGN}) - - #create the intermediates dir if it doesn't exist - if(NABCOMP_MPI) - set(C_FILES_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/mpinabfiles") - else() - set(C_FILES_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/nabfiles") - endif() - - - file(MAKE_DIRECTORY ${C_FILES_DIR}) - - #turn include directories into preprocessor arguments - if(DEFINED NAB_INCLUDE_DIRS) - foreach(INCDIR ${NAB_INCLUDE_DIRS}) - list(APPEND CPP_ARGS "-I${INCDIR}") - endforeach() - endif() - - list(APPEND CPP_ARGS "-I${NAB_HEADER_DIR}") - - if(DEFINED NAB_DEFINITIONS) - foreach(DEFINITION ${NAB_DEFINITIONS}) - list(APPEND CPP_ARGS "-D${DEFINITION}") - endforeach() - endif() - - if(NABCOMP_MPI) - set(NAB2C_EXECUTABLE ${RUNNABLE_mpinab2c}) - else() - set(NAB2C_EXECUTABLE ${RUNNABLE_nab2c}) - endif() - - #set up build rules for each nab file - foreach(NAB_FILE ${NABCOMP_UNPARSED_ARGUMENTS}) - get_filename_component(NAB_FILENAME ${NAB_FILE} NAME) - - strip_last_extension(NAB_FILE_BASENAME ${NAB_FILENAME}) - #we use .i because it is the extension GCC uses for preprocessed intermediates - set(PREPROCESSED_INTERMEDIATE ${C_FILES_DIR}/${NAB_FILENAME}.i) - - set(GENERATED_C_FILE ${C_FILES_DIR}/${NAB_FILE_BASENAME}.c) - - add_custom_command(OUTPUT ${PREPROCESSED_INTERMEDIATE} - COMMAND ${RUNNABLE_ucpp} ${CPP_ARGS} -l -o ${PREPROCESSED_INTERMEDIATE} "${CMAKE_CURRENT_SOURCE_DIR}/${NAB_FILE}" - VERBATIM - DEPENDS ${NAB_FILE} - IMPLICIT_DEPENDS C ${NAB_FILE} #try to scan #include dependencies of nab file - COMMENT "[NAB] Preprocessing ${NAB_FILENAME}" - WORKING_DIRECTORY ${C_FILES_DIR}) - - add_custom_command(OUTPUT ${GENERATED_C_FILE} - COMMAND ${NAB2C_EXECUTABLE} -nfname ${NAB_FILENAME} < ${PREPROCESSED_INTERMEDIATE} - VERBATIM - DEPENDS ${PREPROCESSED_INTERMEDIATE} ${NAB2C_EXECUTABLE} - COMMENT "[NAB] Compiling ${NAB_FILENAME}" - WORKING_DIRECTORY ${C_FILES_DIR}) - - list(APPEND ${GENERATED_C_FILES} ${GENERATED_C_FILE}) - set_property(SOURCE ${GENERATED_C_FILE} PROPERTY COMPILE_FLAGS -w) # NAB generates code that triggers compile warnings, so standard procedure is to disable all warnings - - endforeach() - - set(${GENERATED_C_FILES} ${${GENERATED_C_FILES}} PARENT_SCOPE) - -endfunction() - -#function which condenses the four lines of boilerplate to create a nab executable into one line. -#you pass it an executable target name, a list of nab sources, and a list of C sources, and it will create the -#executable and set up the nab sources to be compiled. - -#The targets it creates are regular executable targets, so they can be linked to and installed. - -#If the MPI argument is passed, mpinab will be used. - -#usage: add_nab_executable( NAB_SOURCES [C_SOURCES ] [MPI]) -function(add_nab_executable EXE_NAME) - - #parse the arguents - cmake_parse_arguments( - "ADD_NABEXE" - "MPI" - "" - "NAB_SOURCES;C_SOURCES" - ${ARGN}) - - if(${ADD_NABEXE_NAB_SOURCES} STREQUAL "") - message(SEND_ERROR "Incorrect arguments: No nab sources provided.") - endif() - - if(NOT ${ADD_NABEXE_UNPARSED_ARGUMENTS} STREQUAL "") - message(SEND_ERROR "Usage error: Unknown arguments provided.") - endif() - - #create the executable - if(ADD_NABEXE_MPI) - nab_compile(${EXE_NAME}_COMPILED_NAB ${ADD_NABEXE_NAB_SOURCES} MPI) - else() - nab_compile(${EXE_NAME}_COMPILED_NAB ${ADD_NABEXE_NAB_SOURCES}) - endif() - - add_executable(${EXE_NAME} ${${EXE_NAME}_COMPILED_NAB} ${ADD_NABEXE_C_SOURCES}) - - if(ADD_NABEXE_MPI) - target_link_libraries(${EXE_NAME} libnab_mpi mpi_c) - else() - target_link_libraries(${EXE_NAME} libnab) - endif() - -endfunction(add_nab_executable) \ No newline at end of file diff --git a/cmake/patched-cmake-modules/CheckConstantExists.cmake b/cmake/patched-cmake-modules/CheckConstantExists.cmake index bb8a5880f..bf4276025 100644 --- a/cmake/patched-cmake-modules/CheckConstantExists.cmake +++ b/cmake/patched-cmake-modules/CheckConstantExists.cmake @@ -1,115 +1,115 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -# AMBER: adapted from CheckSymbolExists. Amazingly, this functionality is not available in the CMake standard library. - -#[=======================================================================[.rst: -CheckConstantExists ------------------ - -Provides a macro to check if something exists as a predefined constant or enum value in ``C``. - -.. command:: check_constant_exists - - :: - - check_constant_exists( ) - - Check that the ```` globally defined variable OR enum - is available after including given header ```` and store the - result in a ````. Specify the list - of files in one argument as a semicolon-separated list. - ```` will be created as an internal cache variable. - If the symbol is a global constant, then it must be available for linking. - -The following variables may be set before calling this macro to modify -the way the check is run: - -``CMAKE_REQUIRED_FLAGS`` - string of compile command line flags -``CMAKE_REQUIRED_DEFINITIONS`` - list of macros to define (-DFOO=bar) -``CMAKE_REQUIRED_INCLUDES`` - list of include directories -``CMAKE_REQUIRED_LIBRARIES`` - list of libraries to link -``CMAKE_REQUIRED_QUIET`` - execute quietly without messages -#]=======================================================================] - -macro(CHECK_CONSTANT_EXISTS CONSTANT FILES VARIABLE) - if(CMAKE_C_COMPILER_LOADED) - _CHECK_CONSTANT_EXISTS("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckConstantExists.c" "${CONSTANT}" "${FILES}" "${VARIABLE}" ) - elseif(CMAKE_CXX_COMPILER_LOADED) - _CHECK_CONSTANT_EXISTS("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckConstantExists.cxx" "${CONSTANT}" "${FILES}" "${VARIABLE}" ) - else() - message(FATAL_ERROR "CHECK_CONSTANT_EXISTS needs either C or CXX language enabled") - endif() -endmacro() - -macro(_CHECK_CONSTANT_EXISTS SOURCEFILE CONSTANT FILES VARIABLE) - if(NOT DEFINED "${VARIABLE}" OR "x${${VARIABLE}}" STREQUAL "x${VARIABLE}") - set(CMAKE_CONFIGURABLE_FILE_CONTENT "/* */\n") - set(MACRO_CHECK_CONSTANT_EXISTS_FLAGS ${CMAKE_REQUIRED_FLAGS}) - if(CMAKE_REQUIRED_LIBRARIES) - set(CHECK_CONSTANT_EXISTS_LIBS - LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) - else() - set(CHECK_CONSTANT_EXISTS_LIBS) - endif() - if(CMAKE_REQUIRED_INCLUDES) - set(CMAKE_CONSTANT_EXISTS_INCLUDES - "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}") - else() - set(CMAKE_CONSTANT_EXISTS_INCLUDES) - endif() - foreach(FILE ${FILES}) - set(CMAKE_CONFIGURABLE_FILE_CONTENT "${CMAKE_CONFIGURABLE_FILE_CONTENT} #include <${FILE}>\n") - endforeach() - - set(CMAKE_CONFIGURABLE_FILE_CONTENT "${CMAKE_CONFIGURABLE_FILE_CONTENT} -int main(int argc, char** argv) -{ - (void)argv; - return argc = ${CONSTANT}; -} -") - - configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in" - "${SOURCEFILE}" @ONLY) - - if(NOT CMAKE_REQUIRED_QUIET) - message(STATUS "Looking for ${CONSTANT} as #define or enum") - endif() - try_compile(${VARIABLE} - ${CMAKE_BINARY_DIR} - "${SOURCEFILE}" - COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} - ${CHECK_CONSTANT_EXISTS_LIBS} - CMAKE_FLAGS - -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_CONSTANT_EXISTS_FLAGS} - "${CMAKE_CONSTANT_EXISTS_INCLUDES}" - OUTPUT_VARIABLE OUTPUT) - if(${VARIABLE}) - if(NOT CMAKE_REQUIRED_QUIET) - message(STATUS "Looking for ${CONSTANT} as #define or enum - found") - endif() - set(${VARIABLE} 1 CACHE INTERNAL "Have constant ${CONSTANT}") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the ${CONSTANT} " - "exist passed with the following output:\n" - "${OUTPUT}\nFile ${SOURCEFILE}:\n" - "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n") - else() - if(NOT CMAKE_REQUIRED_QUIET) - message(STATUS "Looking for ${CONSTANT} as #define or enum - not found") - endif() - set(${VARIABLE} "" CACHE INTERNAL "Have constant ${CONSTANT}") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the ${CONSTANT} " - "exist failed with the following output:\n" - "${OUTPUT}\nFile ${SOURCEFILE}:\n" - "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n") - endif() - endif() +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +# AMBER: adapted from CheckSymbolExists. Amazingly, this functionality is not available in the CMake standard library. + +#[=======================================================================[.rst: +CheckConstantExists +----------------- + +Provides a macro to check if something exists as a predefined constant or enum value in ``C``. + +.. command:: check_constant_exists + + :: + + check_constant_exists( ) + + Check that the ```` globally defined variable OR enum + is available after including given header ```` and store the + result in a ````. Specify the list + of files in one argument as a semicolon-separated list. + ```` will be created as an internal cache variable. + If the symbol is a global constant, then it must be available for linking. + +The following variables may be set before calling this macro to modify +the way the check is run: + +``CMAKE_REQUIRED_FLAGS`` + string of compile command line flags +``CMAKE_REQUIRED_DEFINITIONS`` + list of macros to define (-DFOO=bar) +``CMAKE_REQUIRED_INCLUDES`` + list of include directories +``CMAKE_REQUIRED_LIBRARIES`` + list of libraries to link +``CMAKE_REQUIRED_QUIET`` + execute quietly without messages +#]=======================================================================] + +macro(CHECK_CONSTANT_EXISTS CONSTANT FILES VARIABLE) + if(CMAKE_C_COMPILER_LOADED) + _CHECK_CONSTANT_EXISTS("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckConstantExists.c" "${CONSTANT}" "${FILES}" "${VARIABLE}" ) + elseif(CMAKE_CXX_COMPILER_LOADED) + _CHECK_CONSTANT_EXISTS("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckConstantExists.cxx" "${CONSTANT}" "${FILES}" "${VARIABLE}" ) + else() + message(FATAL_ERROR "CHECK_CONSTANT_EXISTS needs either C or CXX language enabled") + endif() +endmacro() + +macro(_CHECK_CONSTANT_EXISTS SOURCEFILE CONSTANT FILES VARIABLE) + if(NOT DEFINED "${VARIABLE}" OR "x${${VARIABLE}}" STREQUAL "x${VARIABLE}") + set(CMAKE_CONFIGURABLE_FILE_CONTENT "/* */\n") + set(MACRO_CHECK_CONSTANT_EXISTS_FLAGS ${CMAKE_REQUIRED_FLAGS}) + if(CMAKE_REQUIRED_LIBRARIES) + set(CHECK_CONSTANT_EXISTS_LIBS + LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) + else() + set(CHECK_CONSTANT_EXISTS_LIBS) + endif() + if(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_CONSTANT_EXISTS_INCLUDES + "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}") + else() + set(CMAKE_CONSTANT_EXISTS_INCLUDES) + endif() + foreach(FILE ${FILES}) + set(CMAKE_CONFIGURABLE_FILE_CONTENT "${CMAKE_CONFIGURABLE_FILE_CONTENT} #include <${FILE}>\n") + endforeach() + + set(CMAKE_CONFIGURABLE_FILE_CONTENT "${CMAKE_CONFIGURABLE_FILE_CONTENT} +int main(int argc, char** argv) +{ + (void)argv; + return argc = ${CONSTANT}; +} +") + + configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in" + "${SOURCEFILE}" @ONLY) + + if(NOT CMAKE_REQUIRED_QUIET) + message(STATUS "Looking for ${CONSTANT} as #define or enum") + endif() + try_compile(${VARIABLE} + ${CMAKE_BINARY_DIR} + "${SOURCEFILE}" + COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} + ${CHECK_CONSTANT_EXISTS_LIBS} + CMAKE_FLAGS + -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_CONSTANT_EXISTS_FLAGS} + "${CMAKE_CONSTANT_EXISTS_INCLUDES}" + OUTPUT_VARIABLE OUTPUT) + if(${VARIABLE}) + if(NOT CMAKE_REQUIRED_QUIET) + message(STATUS "Looking for ${CONSTANT} as #define or enum - found") + endif() + set(${VARIABLE} 1 CACHE INTERNAL "Have constant ${CONSTANT}") + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Determining if the ${CONSTANT} " + "exist passed with the following output:\n" + "${OUTPUT}\nFile ${SOURCEFILE}:\n" + "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n") + else() + if(NOT CMAKE_REQUIRED_QUIET) + message(STATUS "Looking for ${CONSTANT} as #define or enum - not found") + endif() + set(${VARIABLE} "" CACHE INTERNAL "Have constant ${CONSTANT}") + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Determining if the ${CONSTANT} " + "exist failed with the following output:\n" + "${OUTPUT}\nFile ${SOURCEFILE}:\n" + "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n") + endif() + endif() endmacro() \ No newline at end of file diff --git a/cmake/patched-cmake-modules/Copyright.txt b/cmake/patched-cmake-modules/Copyright.txt index 07fdf5a3f..897e78960 100644 --- a/cmake/patched-cmake-modules/Copyright.txt +++ b/cmake/patched-cmake-modules/Copyright.txt @@ -1,122 +1,122 @@ -CMake - Cross Platform Makefile Generator -Copyright 2000-2017 Kitware, Inc. and Contributors -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -* Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -* Neither the name of Kitware, Inc. nor the names of Contributors - may be used to endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ------------------------------------------------------------------------------- - -The following individuals and institutions are among the Contributors: - -* Aaron C. Meadows -* Aleksey Avdeev -* Alexander Neundorf -* Alexander Smorkalov -* Alexey Sokolov -* Alex Turbov -* Andreas Pakulat -* Andreas Schneider -* André Rigland Brodtkorb -* Axel Huebl, Helmholtz-Zentrum Dresden - Rossendorf -* Benjamin Eikel -* Bjoern Ricks -* Brad Hards -* Christopher Harvey -* Christoph Grüninger -* Clement Creusot -* Daniel Blezek -* Daniel Pfeifer -* Enrico Scholz -* Eran Ifrah -* Esben Mose Hansen, Ange Optimization ApS -* Geoffrey Viola -* Google Inc -* Gregor Jasny -* Helio Chissini de Castro -* Ilya Lavrenov -* Insight Software Consortium -* Jan Woetzel -* Kelly Thompson -* Konstantin Podsvirov -* Mario Bensi -* Mathieu Malaterre -* Matthaeus G. Chajdas -* Matthias Kretz -* Matthias Maennich -* Miguel A. Figueroa-Villanueva -* Mike Jackson -* Mike McQuaid -* Nicolas Bock -* Nicolas Despres -* Nikita Krupen'ko -* OpenGamma Ltd. -* Per Øyvind Karlsen -* Peter Collingbourne -* Petr Gotthard -* Philip Lowman -* Philippe Proulx -* Raffi Enficiaud, Max Planck Society -* Raumfeld -* Roger Leigh -* Rolf Eike Beer -* Roman Donchenko -* Roman Kharitonov -* Ruslan Baratov -* Sebastian Holtermann -* Stephen Kelly -* Sylvain Joubert -* Thomas Sondergaard -* Tobias Hunger -* Todd Gamblin -* Tristan Carel -* University of Dundee -* Vadim Zhukov -* Will Dicharry - -See version control history for details of individual contributions. - -The above copyright and license notice applies to distributions of -CMake in source and binary form. Third-party software packages supplied -with CMake under compatible licenses provide their own copyright notices -documented in corresponding subdirectories or source files. - ------------------------------------------------------------------------------- - -CMake was initially developed by Kitware with the following sponsorship: - - * National Library of Medicine at the National Institutes of Health - as part of the Insight Segmentation and Registration Toolkit (ITK). - - * US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel - Visualization Initiative. - - * National Alliance for Medical Image Computing (NAMIC) is funded by the - National Institutes of Health through the NIH Roadmap for Medical Research, - Grant U54 EB005149. - +CMake - Cross Platform Makefile Generator +Copyright 2000-2017 Kitware, Inc. and Contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +* Neither the name of Kitware, Inc. nor the names of Contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +------------------------------------------------------------------------------ + +The following individuals and institutions are among the Contributors: + +* Aaron C. Meadows +* Aleksey Avdeev +* Alexander Neundorf +* Alexander Smorkalov +* Alexey Sokolov +* Alex Turbov +* Andreas Pakulat +* Andreas Schneider +* André Rigland Brodtkorb +* Axel Huebl, Helmholtz-Zentrum Dresden - Rossendorf +* Benjamin Eikel +* Bjoern Ricks +* Brad Hards +* Christopher Harvey +* Christoph Grüninger +* Clement Creusot +* Daniel Blezek +* Daniel Pfeifer +* Enrico Scholz +* Eran Ifrah +* Esben Mose Hansen, Ange Optimization ApS +* Geoffrey Viola +* Google Inc +* Gregor Jasny +* Helio Chissini de Castro +* Ilya Lavrenov +* Insight Software Consortium +* Jan Woetzel +* Kelly Thompson +* Konstantin Podsvirov +* Mario Bensi +* Mathieu Malaterre +* Matthaeus G. Chajdas +* Matthias Kretz +* Matthias Maennich +* Miguel A. Figueroa-Villanueva +* Mike Jackson +* Mike McQuaid +* Nicolas Bock +* Nicolas Despres +* Nikita Krupen'ko +* OpenGamma Ltd. +* Per Øyvind Karlsen +* Peter Collingbourne +* Petr Gotthard +* Philip Lowman +* Philippe Proulx +* Raffi Enficiaud, Max Planck Society +* Raumfeld +* Roger Leigh +* Rolf Eike Beer +* Roman Donchenko +* Roman Kharitonov +* Ruslan Baratov +* Sebastian Holtermann +* Stephen Kelly +* Sylvain Joubert +* Thomas Sondergaard +* Tobias Hunger +* Todd Gamblin +* Tristan Carel +* University of Dundee +* Vadim Zhukov +* Will Dicharry + +See version control history for details of individual contributions. + +The above copyright and license notice applies to distributions of +CMake in source and binary form. Third-party software packages supplied +with CMake under compatible licenses provide their own copyright notices +documented in corresponding subdirectories or source files. + +------------------------------------------------------------------------------ + +CMake was initially developed by Kitware with the following sponsorship: + + * National Library of Medicine at the National Institutes of Health + as part of the Insight Segmentation and Registration Toolkit (ITK). + + * US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel + Visualization Initiative. + + * National Alliance for Medical Image Computing (NAMIC) is funded by the + National Institutes of Health through the NIH Roadmap for Medical Research, + Grant U54 EB005149. + * Kitware, Inc. \ No newline at end of file diff --git a/cmake/patched-cmake-modules/FindBLASFixed.cmake b/cmake/patched-cmake-modules/FindBLASFixed.cmake index d7d4360a3..17ce6af90 100644 --- a/cmake/patched-cmake-modules/FindBLASFixed.cmake +++ b/cmake/patched-cmake-modules/FindBLASFixed.cmake @@ -1,527 +1,527 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -# AMBER: MKL support has been removed from this file so that it doesn't conflict with FindMKL -# We also provide this to allow OpenBLAS to be used with older CMake versions - -#.rst: -# FindBLAS -# -------- -# -# Find BLAS library -# -# This module finds an installed fortran library that implements the -# BLAS linear-algebra interface (see http://www.netlib.org/blas/). The -# list of libraries searched for is taken from the autoconf macro file, -# acx_blas.m4 (distributed at -# http://ac-archive.sourceforge.net/ac-archive/acx_blas.html). -# -# This module sets the following variables: -# -# :: -# -# BLAS_FOUND - set to true if a library implementing the BLAS interface -# is found -# BLAS_LINKER_FLAGS - uncached list of required linker flags (excluding -l -# and -L). -# BLAS_LIBRARIES - uncached list of libraries (using full path name) to -# link against to use BLAS -# BLAS95_LIBRARIES - uncached list of libraries (using full path name) -# to link against to use BLAS95 interface -# BLAS95_FOUND - set to true if a library implementing the BLAS f95 interface -# is found -# BLA_STATIC if set on this determines what kind of linkage we do (static) -# BLA_VENDOR if set checks only the specified vendor, if not set checks -# all the possibilities -# BLA_F95 if set on tries to find the f95 interfaces for BLAS/LAPACK -# -# ######### ## List of vendors (BLA_VENDOR) valid in this module # -# Goto,OpenBLAS,ATLAS PhiPACK,CXML,DXML,SunPerf,SCSL,SGIMATH,IBMESSL, -# ACML,ACML_MP,ACML_GPU,Apple, NAS, Generic - -include(CMakePushCheckState) - -cmake_push_check_state() - -if(DEFINED ENV{BLA_VENDOR}) - set(BLA_VENDOR_DEFAULT $ENV{BLA_VENDOR}) -else() - set(BLA_VENDOR_DEFAULT "All") -endif () - -set(BLA_VENDOR ${BLA_VENDOR_DEFAULT} CACHE STRING "BLAS vendor to use for BLAS and Lapack. Valid values: All, Goto, OpenBLAS, ATLAS, PhiPACK, CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic") -validate_configuration_enum(BLA_VENDOR All Goto OpenBLAS ATLAS PhiPACK CXML DXML SunPerf SCSL SGIMATH IBMESSL ACML ACML_MP ACML_GPU Apple NAS Generic) - -if(DEFINED BLAS_FIND_QUIETLY) - set(CMAKE_REQUIRED_QUIET ${BLAS_FIND_QUIETLY}) -endif() - -set(_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) - -# Check the language being used -if( NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED) ) - if(BLAS_FIND_REQUIRED) - message(FATAL_ERROR "FindBLAS requires Fortran, C, or C++ to be enabled.") - else() - message(STATUS "Looking for BLAS... - NOT found (Unsupported languages)") - return() - endif() -endif() - -macro(Check_Fortran_Libraries LIBRARIES _prefix _name _flags _list _thread) - # This macro checks for the existence of the combination of fortran libraries - # given by _list. If the combination is found, this macro checks (using the - # Check_Fortran_Function_Exists macro) whether can link against that library - # combination using the name of a routine given by _name using the linker - # flags given by _flags. If the combination of libraries is found and passes - # the link test, LIBRARIES is set to the list of complete library paths that - # have been found. Otherwise, LIBRARIES is set to FALSE. - - # N.B. _prefix is the prefix applied to the names of all cached variables that - # are generated internally and marked advanced by this macro. - - set(_libdir ${ARGN}) - - set(_libraries_work TRUE) - set(${LIBRARIES}) - set(_combined_name) - - foreach(_library ${_list}) - set(_combined_name ${_combined_name}_${_library}) - - if(_libraries_work) - if (BLA_STATIC) - if (WIN32) - set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) - endif () - if (APPLE) - set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) - else () - set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) - endif () - else () - if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - # for ubuntu's libblas3gf and liblapack3gf packages - set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf) - endif () - endif () - find_library(${_prefix}_${_library}_LIBRARY - NAMES ${_library}) - - #message("DEBUG: ${_prefix}_${_library}_LIBRARY: ${${_prefix}_${_library}_LIBRARY}, PATHS: ${_libdir}, NAMES: ${_library}") - mark_as_advanced(${_prefix}_${_library}_LIBRARY) - set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) - set(_libraries_work ${${_prefix}_${_library}_LIBRARY}) - endif() - endforeach() - if(_libraries_work) - # Test this combination of libraries. - set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_thread}) - #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}") - if (CMAKE_Fortran_COMPILER_LOADED) - check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS) - else() - check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS) - - # try without the underscore - if(NOT ${_prefix}${_combined_name}_WORKS) - check_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS_NOUNDERSCORE) - if(${_prefix}${_combined_name}_WORKS_NOUNDERSCORE) - set(${_prefix}${_combined_name}_WORKS TRUE CACHE BOOL "" FORCE) - endif() - endif() - endif() - set(CMAKE_REQUIRED_LIBRARIES) - mark_as_advanced(${_prefix}${_combined_name}_WORKS) - set(_libraries_work ${${_prefix}${_combined_name}_WORKS}) - endif() - if(NOT _libraries_work) - set(${LIBRARIES} FALSE) - endif() - #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}") -endmacro() - -set(BLAS_LINKER_FLAGS) -set(BLAS_LIBRARIES) -set(BLAS95_LIBRARIES) - -if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - # gotoblas (http://www.tacc.utexas.edu/tacc-projects/gotoblas2) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "goto2" - "" - ) - endif() -endif () - -if (BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - # OpenBLAS (http://www.openblas.net) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "openblas" - "" - ) - endif() -endif () - -if (BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - # BLAS in ATLAS library? (http://math-atlas.sourceforge.net/) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - dgemm - "" - "f77blas;atlas" - "" - ) - endif() -endif () - -# BLAS in PhiPACK libraries? (requires generic BLAS lib, too) -if (BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "sgemm;dgemm;blas" - "" - ) - endif() -endif () - -# BLAS in Alpha CXML library? -if (BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "cxml" - "" - ) - endif() -endif () - -# BLAS in Alpha DXML library? (now called CXML, see above) -if (BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "dxml" - "" - ) - endif() -endif () - -# BLAS in Sun Performance library? -if (BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "-xlic_lib=sunperf" - "sunperf;sunmath" - "" - ) - if(BLAS_LIBRARIES) - set(BLAS_LINKER_FLAGS "-xlic_lib=sunperf") - endif() - endif() -endif () - -# BLAS in SCSL library? (SGI/Cray Scientific Library) -if (BLA_VENDOR STREQUAL "SCSL" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "scsl" - "" - ) - endif() -endif () - -# BLAS in SGIMATH library? -if (BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "complib.sgimath" - "" - ) - endif() -endif () - -# BLAS in IBM ESSL library? (requires generic BLAS lib, too) -if (BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "essl;blas" - "" - ) - endif() -endif () - -#BLAS in acml library? -if (BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All") - if( ((BLA_VENDOR STREQUAL "ACML") AND (NOT BLAS_ACML_LIB_DIRS)) OR - ((BLA_VENDOR STREQUAL "ACML_MP") AND (NOT BLAS_ACML_MP_LIB_DIRS)) OR - ((BLA_VENDOR STREQUAL "ACML_GPU") AND (NOT BLAS_ACML_GPU_LIB_DIRS)) - ) - # try to find acml in "standard" paths - if( WIN32 ) - file( GLOB _ACML_ROOT "C:/AMD/acml*/ACML-EULA.txt" ) - else() - file( GLOB _ACML_ROOT "/opt/acml*/ACML-EULA.txt" ) - endif() - if( WIN32 ) - file( GLOB _ACML_GPU_ROOT "C:/AMD/acml*/GPGPUexamples" ) - else() - file( GLOB _ACML_GPU_ROOT "/opt/acml*/GPGPUexamples" ) - endif() - list(GET _ACML_ROOT 0 _ACML_ROOT) - if(NOT "${_ACML_GPU_ROOT}" STREQUAL "") - list(GET _ACML_GPU_ROOT 0 _ACML_GPU_ROOT) - endif() - - if( _ACML_ROOT ) - get_filename_component( _ACML_ROOT ${_ACML_ROOT} PATH ) - if( SIZEOF_INTEGER EQUAL 8 ) - set( _ACML_PATH_SUFFIX "_int64" ) - else() - set( _ACML_PATH_SUFFIX "" ) - endif() - if( CMAKE_Fortran_COMPILER_ID STREQUAL "Intel" ) - set( _ACML_COMPILER32 "ifort32" ) - set( _ACML_COMPILER64 "ifort64" ) - elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "SunPro" ) - set( _ACML_COMPILER32 "sun32" ) - set( _ACML_COMPILER64 "sun64" ) - elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "PGI" ) - set( _ACML_COMPILER32 "pgi32" ) - if( WIN32 ) - set( _ACML_COMPILER64 "win64" ) - else() - set( _ACML_COMPILER64 "pgi64" ) - endif() - elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "Open64" ) - # 32 bit builds not supported on Open64 but for code simplicity - # We'll just use the same directory twice - set( _ACML_COMPILER32 "open64_64" ) - set( _ACML_COMPILER64 "open64_64" ) - elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "NAG" ) - set( _ACML_COMPILER32 "nag32" ) - set( _ACML_COMPILER64 "nag64" ) - else() - set( _ACML_COMPILER32 "gfortran32" ) - set( _ACML_COMPILER64 "gfortran64" ) - endif() - - if( BLA_VENDOR STREQUAL "ACML_MP" ) - set(_ACML_MP_LIB_DIRS - "${_ACML_ROOT}/${_ACML_COMPILER32}_mp${_ACML_PATH_SUFFIX}/lib" - "${_ACML_ROOT}/${_ACML_COMPILER64}_mp${_ACML_PATH_SUFFIX}/lib" ) - else() - set(_ACML_LIB_DIRS - "${_ACML_ROOT}/${_ACML_COMPILER32}${_ACML_PATH_SUFFIX}/lib" - "${_ACML_ROOT}/${_ACML_COMPILER64}${_ACML_PATH_SUFFIX}/lib" ) - endif() - endif() - elseif(BLAS_${BLA_VENDOR}_LIB_DIRS) - set(_${BLA_VENDOR}_LIB_DIRS ${BLAS_${BLA_VENDOR}_LIB_DIRS}) - endif() - - if( BLA_VENDOR STREQUAL "ACML_MP" ) - foreach( BLAS_ACML_MP_LIB_DIRS ${_ACML_MP_LIB_DIRS}) - check_fortran_libraries ( - BLAS_LIBRARIES - BLAS - sgemm - "" "acml_mp;acml_mv" "" ${BLAS_ACML_MP_LIB_DIRS} - ) - if( BLAS_LIBRARIES ) - break() - endif() - endforeach() - elseif( BLA_VENDOR STREQUAL "ACML_GPU" ) - foreach( BLAS_ACML_GPU_LIB_DIRS ${_ACML_GPU_LIB_DIRS}) - check_fortran_libraries ( - BLAS_LIBRARIES - BLAS - sgemm - "" "acml;acml_mv;CALBLAS" "" ${BLAS_ACML_GPU_LIB_DIRS} - ) - if( BLAS_LIBRARIES ) - break() - endif() - endforeach() - elseif(DEFINED _ACML_LIB_DIRS) - foreach( BLAS_ACML_LIB_DIRS ${_ACML_LIB_DIRS} ) - check_fortran_libraries ( - BLAS_LIBRARIES - BLAS - sgemm - "" "acml;acml_mv" "" ${BLAS_ACML_LIB_DIRS} - ) - if( BLAS_LIBRARIES ) - break() - endif() - endforeach() - endif() - - # Either acml or acml_mp should be in LD_LIBRARY_PATH but not both - if(NOT BLAS_LIBRARIES) - - if(WIN32) - set(ACML_NAME libacml_dll) - else() - set(ACML_NAME acml) - endif() - - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - ${ACML_NAME} - "" - "${_ACML_ROOT}/ifort64/lib" - ) - endif() - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "acml_mp;acml_mv" - "" - ) - endif() - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "acml;acml_mv;CALBLAS" - "" - ) - endif() -endif () # ACML - -# Apple BLAS library? -if (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All") -if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - dgemm - "" - "Accelerate" - "" - ) - endif() -endif () - -if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All") - if ( NOT BLAS_LIBRARIES ) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - dgemm - "" - "vecLib" - "" - ) - endif () -endif () -# Generic BLAS library? -if (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "blas" - "" - ) - endif() -endif () - - -if(BLA_F95) - if(BLAS95_LIBRARIES) - set(BLAS95_FOUND TRUE) - else() - set(BLAS95_FOUND FALSE) - endif() - - if(NOT BLAS_FIND_QUIETLY) - if(BLAS95_FOUND) - message(STATUS "A library with BLAS95 API found.") - else() - if(BLAS_FIND_REQUIRED) - message(FATAL_ERROR - "A required library with BLAS95 API not found. Please specify library location.") - else() - message(STATUS - "A library with BLAS95 API not found. Please specify library location.") - endif() - endif() - endif() - set(BLAS_FOUND TRUE) - set(BLAS_LIBRARIES "${BLAS95_LIBRARIES}") -else() - if(BLAS_LIBRARIES) - set(BLAS_FOUND TRUE) - else() - set(BLAS_FOUND FALSE) - endif() - - if(NOT BLAS_FIND_QUIETLY) - if(BLAS_FOUND) - message(STATUS "A library with BLAS API found.") - else() - if(BLAS_FIND_REQUIRED) - message(FATAL_ERROR - "A required library with BLAS API not found. Please specify library location." - ) - else() - message(STATUS - "A library with BLAS API not found. Please specify library location." - ) - endif() - endif() - endif() -endif() - -cmake_pop_check_state() +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +# AMBER: MKL support has been removed from this file so that it doesn't conflict with FindMKL +# We also provide this to allow OpenBLAS to be used with older CMake versions + +#.rst: +# FindBLAS +# -------- +# +# Find BLAS library +# +# This module finds an installed fortran library that implements the +# BLAS linear-algebra interface (see http://www.netlib.org/blas/). The +# list of libraries searched for is taken from the autoconf macro file, +# acx_blas.m4 (distributed at +# http://ac-archive.sourceforge.net/ac-archive/acx_blas.html). +# +# This module sets the following variables: +# +# :: +# +# BLAS_FOUND - set to true if a library implementing the BLAS interface +# is found +# BLAS_LINKER_FLAGS - uncached list of required linker flags (excluding -l +# and -L). +# BLAS_LIBRARIES - uncached list of libraries (using full path name) to +# link against to use BLAS +# BLAS95_LIBRARIES - uncached list of libraries (using full path name) +# to link against to use BLAS95 interface +# BLAS95_FOUND - set to true if a library implementing the BLAS f95 interface +# is found +# BLA_STATIC if set on this determines what kind of linkage we do (static) +# BLA_VENDOR if set checks only the specified vendor, if not set checks +# all the possibilities +# BLA_F95 if set on tries to find the f95 interfaces for BLAS/LAPACK +# +# ######### ## List of vendors (BLA_VENDOR) valid in this module # +# Goto,OpenBLAS,ATLAS PhiPACK,CXML,DXML,SunPerf,SCSL,SGIMATH,IBMESSL, +# ACML,ACML_MP,ACML_GPU,Apple, NAS, Generic + +include(CMakePushCheckState) + +cmake_push_check_state() + +if(DEFINED ENV{BLA_VENDOR}) + set(BLA_VENDOR_DEFAULT $ENV{BLA_VENDOR}) +else() + set(BLA_VENDOR_DEFAULT "All") +endif () + +set(BLA_VENDOR ${BLA_VENDOR_DEFAULT} CACHE STRING "BLAS vendor to use for BLAS and Lapack. Valid values: All, Goto, OpenBLAS, ATLAS, PhiPACK, CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic") +validate_configuration_enum(BLA_VENDOR All Goto OpenBLAS ATLAS PhiPACK CXML DXML SunPerf SCSL SGIMATH IBMESSL ACML ACML_MP ACML_GPU Apple NAS Generic) + +if(DEFINED BLAS_FIND_QUIETLY) + set(CMAKE_REQUIRED_QUIET ${BLAS_FIND_QUIETLY}) +endif() + +set(_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + +# Check the language being used +if( NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED) ) + if(BLAS_FIND_REQUIRED) + message(FATAL_ERROR "FindBLAS requires Fortran, C, or C++ to be enabled.") + else() + message(STATUS "Looking for BLAS... - NOT found (Unsupported languages)") + return() + endif() +endif() + +macro(Check_Fortran_Libraries LIBRARIES _prefix _name _flags _list _thread) + # This macro checks for the existence of the combination of fortran libraries + # given by _list. If the combination is found, this macro checks (using the + # Check_Fortran_Function_Exists macro) whether can link against that library + # combination using the name of a routine given by _name using the linker + # flags given by _flags. If the combination of libraries is found and passes + # the link test, LIBRARIES is set to the list of complete library paths that + # have been found. Otherwise, LIBRARIES is set to FALSE. + + # N.B. _prefix is the prefix applied to the names of all cached variables that + # are generated internally and marked advanced by this macro. + + set(_libdir ${ARGN}) + + set(_libraries_work TRUE) + set(${LIBRARIES}) + set(_combined_name) + + foreach(_library ${_list}) + set(_combined_name ${_combined_name}_${_library}) + + if(_libraries_work) + if (BLA_STATIC) + if (WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif () + if (APPLE) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else () + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif () + else () + if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + # for ubuntu's libblas3gf and liblapack3gf packages + set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf) + endif () + endif () + find_library(${_prefix}_${_library}_LIBRARY + NAMES ${_library}) + + #message("DEBUG: ${_prefix}_${_library}_LIBRARY: ${${_prefix}_${_library}_LIBRARY}, PATHS: ${_libdir}, NAMES: ${_library}") + mark_as_advanced(${_prefix}_${_library}_LIBRARY) + set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) + set(_libraries_work ${${_prefix}_${_library}_LIBRARY}) + endif() + endforeach() + if(_libraries_work) + # Test this combination of libraries. + set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_thread}) + #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}") + if (CMAKE_Fortran_COMPILER_LOADED) + check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS) + else() + check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS) + + # try without the underscore + if(NOT ${_prefix}${_combined_name}_WORKS) + check_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS_NOUNDERSCORE) + if(${_prefix}${_combined_name}_WORKS_NOUNDERSCORE) + set(${_prefix}${_combined_name}_WORKS TRUE CACHE BOOL "" FORCE) + endif() + endif() + endif() + set(CMAKE_REQUIRED_LIBRARIES) + mark_as_advanced(${_prefix}${_combined_name}_WORKS) + set(_libraries_work ${${_prefix}${_combined_name}_WORKS}) + endif() + if(NOT _libraries_work) + set(${LIBRARIES} FALSE) + endif() + #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}") +endmacro() + +set(BLAS_LINKER_FLAGS) +set(BLAS_LIBRARIES) +set(BLAS95_LIBRARIES) + +if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") + if(NOT BLAS_LIBRARIES) + # gotoblas (http://www.tacc.utexas.edu/tacc-projects/gotoblas2) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "goto2" + "" + ) + endif() +endif () + +if (BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All") + if(NOT BLAS_LIBRARIES) + # OpenBLAS (http://www.openblas.net) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "openblas" + "" + ) + endif() +endif () + +if (BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All") + if(NOT BLAS_LIBRARIES) + # BLAS in ATLAS library? (http://math-atlas.sourceforge.net/) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + dgemm + "" + "f77blas;atlas" + "" + ) + endif() +endif () + +# BLAS in PhiPACK libraries? (requires generic BLAS lib, too) +if (BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All") + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "sgemm;dgemm;blas" + "" + ) + endif() +endif () + +# BLAS in Alpha CXML library? +if (BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All") + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "cxml" + "" + ) + endif() +endif () + +# BLAS in Alpha DXML library? (now called CXML, see above) +if (BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All") + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "dxml" + "" + ) + endif() +endif () + +# BLAS in Sun Performance library? +if (BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All") + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "-xlic_lib=sunperf" + "sunperf;sunmath" + "" + ) + if(BLAS_LIBRARIES) + set(BLAS_LINKER_FLAGS "-xlic_lib=sunperf") + endif() + endif() +endif () + +# BLAS in SCSL library? (SGI/Cray Scientific Library) +if (BLA_VENDOR STREQUAL "SCSL" OR BLA_VENDOR STREQUAL "All") + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "scsl" + "" + ) + endif() +endif () + +# BLAS in SGIMATH library? +if (BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All") + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "complib.sgimath" + "" + ) + endif() +endif () + +# BLAS in IBM ESSL library? (requires generic BLAS lib, too) +if (BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All") + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "essl;blas" + "" + ) + endif() +endif () + +#BLAS in acml library? +if (BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All") + if( ((BLA_VENDOR STREQUAL "ACML") AND (NOT BLAS_ACML_LIB_DIRS)) OR + ((BLA_VENDOR STREQUAL "ACML_MP") AND (NOT BLAS_ACML_MP_LIB_DIRS)) OR + ((BLA_VENDOR STREQUAL "ACML_GPU") AND (NOT BLAS_ACML_GPU_LIB_DIRS)) + ) + # try to find acml in "standard" paths + if( WIN32 ) + file( GLOB _ACML_ROOT "C:/AMD/acml*/ACML-EULA.txt" ) + else() + file( GLOB _ACML_ROOT "/opt/acml*/ACML-EULA.txt" ) + endif() + if( WIN32 ) + file( GLOB _ACML_GPU_ROOT "C:/AMD/acml*/GPGPUexamples" ) + else() + file( GLOB _ACML_GPU_ROOT "/opt/acml*/GPGPUexamples" ) + endif() + list(GET _ACML_ROOT 0 _ACML_ROOT) + if(NOT "${_ACML_GPU_ROOT}" STREQUAL "") + list(GET _ACML_GPU_ROOT 0 _ACML_GPU_ROOT) + endif() + + if( _ACML_ROOT ) + get_filename_component( _ACML_ROOT ${_ACML_ROOT} PATH ) + if( SIZEOF_INTEGER EQUAL 8 ) + set( _ACML_PATH_SUFFIX "_int64" ) + else() + set( _ACML_PATH_SUFFIX "" ) + endif() + if( CMAKE_Fortran_COMPILER_ID STREQUAL "Intel" ) + set( _ACML_COMPILER32 "ifort32" ) + set( _ACML_COMPILER64 "ifort64" ) + elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "SunPro" ) + set( _ACML_COMPILER32 "sun32" ) + set( _ACML_COMPILER64 "sun64" ) + elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "PGI" ) + set( _ACML_COMPILER32 "pgi32" ) + if( WIN32 ) + set( _ACML_COMPILER64 "win64" ) + else() + set( _ACML_COMPILER64 "pgi64" ) + endif() + elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "Open64" ) + # 32 bit builds not supported on Open64 but for code simplicity + # We'll just use the same directory twice + set( _ACML_COMPILER32 "open64_64" ) + set( _ACML_COMPILER64 "open64_64" ) + elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "NAG" ) + set( _ACML_COMPILER32 "nag32" ) + set( _ACML_COMPILER64 "nag64" ) + else() + set( _ACML_COMPILER32 "gfortran32" ) + set( _ACML_COMPILER64 "gfortran64" ) + endif() + + if( BLA_VENDOR STREQUAL "ACML_MP" ) + set(_ACML_MP_LIB_DIRS + "${_ACML_ROOT}/${_ACML_COMPILER32}_mp${_ACML_PATH_SUFFIX}/lib" + "${_ACML_ROOT}/${_ACML_COMPILER64}_mp${_ACML_PATH_SUFFIX}/lib" ) + else() + set(_ACML_LIB_DIRS + "${_ACML_ROOT}/${_ACML_COMPILER32}${_ACML_PATH_SUFFIX}/lib" + "${_ACML_ROOT}/${_ACML_COMPILER64}${_ACML_PATH_SUFFIX}/lib" ) + endif() + endif() + elseif(BLAS_${BLA_VENDOR}_LIB_DIRS) + set(_${BLA_VENDOR}_LIB_DIRS ${BLAS_${BLA_VENDOR}_LIB_DIRS}) + endif() + + if( BLA_VENDOR STREQUAL "ACML_MP" ) + foreach( BLAS_ACML_MP_LIB_DIRS ${_ACML_MP_LIB_DIRS}) + check_fortran_libraries ( + BLAS_LIBRARIES + BLAS + sgemm + "" "acml_mp;acml_mv" "" ${BLAS_ACML_MP_LIB_DIRS} + ) + if( BLAS_LIBRARIES ) + break() + endif() + endforeach() + elseif( BLA_VENDOR STREQUAL "ACML_GPU" ) + foreach( BLAS_ACML_GPU_LIB_DIRS ${_ACML_GPU_LIB_DIRS}) + check_fortran_libraries ( + BLAS_LIBRARIES + BLAS + sgemm + "" "acml;acml_mv;CALBLAS" "" ${BLAS_ACML_GPU_LIB_DIRS} + ) + if( BLAS_LIBRARIES ) + break() + endif() + endforeach() + elseif(DEFINED _ACML_LIB_DIRS) + foreach( BLAS_ACML_LIB_DIRS ${_ACML_LIB_DIRS} ) + check_fortran_libraries ( + BLAS_LIBRARIES + BLAS + sgemm + "" "acml;acml_mv" "" ${BLAS_ACML_LIB_DIRS} + ) + if( BLAS_LIBRARIES ) + break() + endif() + endforeach() + endif() + + # Either acml or acml_mp should be in LD_LIBRARY_PATH but not both + if(NOT BLAS_LIBRARIES) + + if(WIN32) + set(ACML_NAME libacml_dll) + else() + set(ACML_NAME acml) + endif() + + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + ${ACML_NAME} + "" + "${_ACML_ROOT}/ifort64/lib" + ) + endif() + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "acml_mp;acml_mv" + "" + ) + endif() + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "acml;acml_mv;CALBLAS" + "" + ) + endif() +endif () # ACML + +# Apple BLAS library? +if (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All") +if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + dgemm + "" + "Accelerate" + "" + ) + endif() +endif () + +if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All") + if ( NOT BLAS_LIBRARIES ) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + dgemm + "" + "vecLib" + "" + ) + endif () +endif () +# Generic BLAS library? +if (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All") + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "blas" + "" + ) + endif() +endif () + + +if(BLA_F95) + if(BLAS95_LIBRARIES) + set(BLAS95_FOUND TRUE) + else() + set(BLAS95_FOUND FALSE) + endif() + + if(NOT BLAS_FIND_QUIETLY) + if(BLAS95_FOUND) + message(STATUS "A library with BLAS95 API found.") + else() + if(BLAS_FIND_REQUIRED) + message(FATAL_ERROR + "A required library with BLAS95 API not found. Please specify library location.") + else() + message(STATUS + "A library with BLAS95 API not found. Please specify library location.") + endif() + endif() + endif() + set(BLAS_FOUND TRUE) + set(BLAS_LIBRARIES "${BLAS95_LIBRARIES}") +else() + if(BLAS_LIBRARIES) + set(BLAS_FOUND TRUE) + else() + set(BLAS_FOUND FALSE) + endif() + + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_FOUND) + message(STATUS "A library with BLAS API found.") + else() + if(BLAS_FIND_REQUIRED) + message(FATAL_ERROR + "A required library with BLAS API not found. Please specify library location." + ) + else() + message(STATUS + "A library with BLAS API not found. Please specify library location." + ) + endif() + endif() + endif() +endif() + +cmake_pop_check_state() set(CMAKE_FIND_LIBRARY_SUFFIXES ${_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) \ No newline at end of file diff --git a/cmake/patched-cmake-modules/FindLAPACKFixed.cmake b/cmake/patched-cmake-modules/FindLAPACKFixed.cmake index 29776b57d..9ccc9f403 100644 --- a/cmake/patched-cmake-modules/FindLAPACKFixed.cmake +++ b/cmake/patched-cmake-modules/FindLAPACKFixed.cmake @@ -1,292 +1,292 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -# AMBER: Removed MKL support to prevent conflicts with FindMKL.cmake, normalized indentation - -#.rst: -# FindLAPACK -# ---------- -# -# Find LAPACK library -# -# This module finds an installed fortran library that implements the -# LAPACK linear-algebra interface (see http://www.netlib.org/lapack/). -# -# The approach follows that taken for the autoconf macro file, -# acx_lapack.m4 (distributed at -# http://ac-archive.sourceforge.net/ac-archive/acx_lapack.html). -# -# This module sets the following variables: -# -# :: -# -# LAPACK_FOUND - set to true if a library implementing the LAPACK interface -# is found -# LAPACK_LINKER_FLAGS - uncached list of required linker flags (excluding -l -# and -L). -# LAPACK_LIBRARIES - uncached list of libraries (using full path name) to -# link against to use LAPACK -# LAPACK95_LIBRARIES - uncached list of libraries (using full path name) to -# link against to use LAPACK95 -# LAPACK95_FOUND - set to true if a library implementing the LAPACK f95 -# interface is found -# BLA_STATIC if set on this determines what kind of linkage we do (static) -# BLA_VENDOR if set checks only the specified vendor, if not set checks -# all the possibilities -# BLA_F95 if set on tries to find the f95 interfaces for BLAS/LAPACK -# -# ## List of vendors (BLA_VENDOR) valid in this module: -# OpenBLAS, ACML,Apple, NAS, Generic - -set(_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) - -# Check the language being used -if( NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED) ) - if(LAPACK_FIND_REQUIRED) - message(FATAL_ERROR "FindLAPACK requires Fortran, C, or C++ to be enabled.") - else() - message(STATUS "Looking for LAPACK... - NOT found (Unsupported languages)") - return() - endif() -endif() - - -include(CMakePushCheckState) - -cmake_push_check_state() - -if(DEFINED LAPACK_FIND_QUIETLY) - set(CMAKE_REQUIRED_QUIET ${LAPACK_FIND_QUIETLY}) -endif() - -set(LAPACK_FOUND FALSE) -set(LAPACK95_FOUND FALSE) - -# TODO: move this stuff to separate module - -macro(Check_Lapack_Libraries LIBRARIES _prefix _name _flags _list _blas _threads) - # This macro checks for the existence of the combination of fortran libraries - # given by _list. If the combination is found, this macro checks (using the - # Check_Fortran_Function_Exists macro) whether can link against that library - # combination using the name of a routine given by _name using the linker - # flags given by _flags. If the combination of libraries is found and passes - # the link test, LIBRARIES is set to the list of complete library paths that - # have been found. Otherwise, LIBRARIES is set to FALSE. - - # N.B. _prefix is the prefix applied to the names of all cached variables that - # are generated internally and marked advanced by this macro. - - set(_libraries_work TRUE) - set(${LIBRARIES}) - set(_combined_name) - if (NOT _libdir) - if (WIN32) - set(_libdir ENV LIB) - elseif (APPLE) - set(_libdir ENV DYLD_LIBRARY_PATH) - else () - set(_libdir ENV LD_LIBRARY_PATH) - endif () - endif () - foreach(_library ${_list}) - set(_combined_name ${_combined_name}_${_library}) - - if(_libraries_work) - if (BLA_STATIC) - if (WIN32) - set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) - endif () - if (APPLE) - set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) - else () - set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) - endif () - else () - if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - # for ubuntu's libblas3gf and liblapack3gf packages - set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf) - endif () - endif () - find_library(${_prefix}_${_library}_LIBRARY - NAMES ${_library} - PATHS ${_libdir} - ) - mark_as_advanced(${_prefix}_${_library}_LIBRARY) - set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) - set(_libraries_work ${${_prefix}_${_library}_LIBRARY}) - endif() - endforeach() - - if(_libraries_work) - # Test this combination of libraries. - if(UNIX AND BLA_STATIC) - set(CMAKE_REQUIRED_LIBRARIES ${_flags} "-Wl,--start-group" ${${LIBRARIES}} ${_blas} "-Wl,--end-group" ${_threads}) - else() - set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas} ${_threads}) - endif() - # message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}") - if (NOT CMAKE_Fortran_COMPILER_LOADED) - check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS) - else () - check_fortran_function_exists(${_name} ${_prefix}${_combined_name}_WORKS) - endif () - set(CMAKE_REQUIRED_LIBRARIES) - mark_as_advanced(${_prefix}${_combined_name}_WORKS) - set(_libraries_work ${${_prefix}${_combined_name}_WORKS}) - #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}") - endif() - - if(_libraries_work) - set(${LIBRARIES} ${${LIBRARIES}} ${_blas} ${_threads}) - else() - set(${LIBRARIES} FALSE) - endif() - -endmacro() - - -set(LAPACK_LINKER_FLAGS) -set(LAPACK_LIBRARIES) -set(LAPACK95_LIBRARIES) - - -if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) - find_package(BLASFixed) -else() - find_package(BLASFixed REQUIRED) -endif() - -if(BLAS_FOUND) - set(LAPACK_LINKER_FLAGS ${BLAS_LINKER_FLAGS}) - - if(BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") - if(NOT LAPACK_LIBRARIES) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "goto2" - "${BLAS_LIBRARIES}" - "" - ) - endif() - endif () - - if(BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All") - if(NOT LAPACK_LIBRARIES) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "openblas" - "${BLAS_LIBRARIES}" - "" - ) - endif() - endif() - - #acml lapack - if (BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All") - if (BLAS_LIBRARIES MATCHES ".+acml.+") - set (LAPACK_LIBRARIES ${BLAS_LIBRARIES}) - endif () - endif () - - # Apple LAPACK library? - if(BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All") - if(NOT LAPACK_LIBRARIES) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "Accelerate" - "${BLAS_LIBRARIES}" - "" - ) - endif() - endif () - if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All") - if ( NOT LAPACK_LIBRARIES ) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "vecLib" - "${BLAS_LIBRARIES}" - "" - ) - endif () - endif () - # Generic LAPACK library? - if (BLA_VENDOR STREQUAL "Generic" OR - BLA_VENDOR STREQUAL "ATLAS" OR - BLA_VENDOR STREQUAL "All") - if ( NOT LAPACK_LIBRARIES ) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "lapack" - "${BLAS_LIBRARIES}" - "" - ) - endif () - endif () -else() - message(STATUS "LAPACK requires BLAS") -endif() - -if(BLA_F95) - if(LAPACK95_LIBRARIES) - set(LAPACK95_FOUND TRUE) - else() - set(LAPACK95_FOUND FALSE) - endif() - if(NOT LAPACK_FIND_QUIETLY) - if(LAPACK95_FOUND) - message(STATUS "A library with LAPACK95 API found.") - else() - if(LAPACK_FIND_REQUIRED) - message(FATAL_ERROR - "A required library with LAPACK95 API not found. Please specify library location." - ) - else() - message(STATUS - "A library with LAPACK95 API not found. Please specify library location." - ) - endif() - endif() - endif() - set(LAPACK_FOUND "${LAPACK95_FOUND}") - set(LAPACK_LIBRARIES "${LAPACK95_LIBRARIES}") -else() - if(LAPACK_LIBRARIES) - set(LAPACK_FOUND TRUE) - else() - set(LAPACK_FOUND FALSE) - endif() - - if(NOT LAPACK_FIND_QUIETLY) - if(LAPACK_FOUND) - message(STATUS "A library with LAPACK API found.") - else() - if(LAPACK_FIND_REQUIRED) - message(FATAL_ERROR - "A required library with LAPACK API not found. Please specify library location." - ) - else() - message(STATUS - "A library with LAPACK API not found. Please specify library location." - ) - endif() - endif() - endif() -endif() - -cmake_pop_check_state() +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +# AMBER: Removed MKL support to prevent conflicts with FindMKL.cmake, normalized indentation + +#.rst: +# FindLAPACK +# ---------- +# +# Find LAPACK library +# +# This module finds an installed fortran library that implements the +# LAPACK linear-algebra interface (see http://www.netlib.org/lapack/). +# +# The approach follows that taken for the autoconf macro file, +# acx_lapack.m4 (distributed at +# http://ac-archive.sourceforge.net/ac-archive/acx_lapack.html). +# +# This module sets the following variables: +# +# :: +# +# LAPACK_FOUND - set to true if a library implementing the LAPACK interface +# is found +# LAPACK_LINKER_FLAGS - uncached list of required linker flags (excluding -l +# and -L). +# LAPACK_LIBRARIES - uncached list of libraries (using full path name) to +# link against to use LAPACK +# LAPACK95_LIBRARIES - uncached list of libraries (using full path name) to +# link against to use LAPACK95 +# LAPACK95_FOUND - set to true if a library implementing the LAPACK f95 +# interface is found +# BLA_STATIC if set on this determines what kind of linkage we do (static) +# BLA_VENDOR if set checks only the specified vendor, if not set checks +# all the possibilities +# BLA_F95 if set on tries to find the f95 interfaces for BLAS/LAPACK +# +# ## List of vendors (BLA_VENDOR) valid in this module: +# OpenBLAS, ACML,Apple, NAS, Generic + +set(_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + +# Check the language being used +if( NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED) ) + if(LAPACK_FIND_REQUIRED) + message(FATAL_ERROR "FindLAPACK requires Fortran, C, or C++ to be enabled.") + else() + message(STATUS "Looking for LAPACK... - NOT found (Unsupported languages)") + return() + endif() +endif() + + +include(CMakePushCheckState) + +cmake_push_check_state() + +if(DEFINED LAPACK_FIND_QUIETLY) + set(CMAKE_REQUIRED_QUIET ${LAPACK_FIND_QUIETLY}) +endif() + +set(LAPACK_FOUND FALSE) +set(LAPACK95_FOUND FALSE) + +# TODO: move this stuff to separate module + +macro(Check_Lapack_Libraries LIBRARIES _prefix _name _flags _list _blas _threads) + # This macro checks for the existence of the combination of fortran libraries + # given by _list. If the combination is found, this macro checks (using the + # Check_Fortran_Function_Exists macro) whether can link against that library + # combination using the name of a routine given by _name using the linker + # flags given by _flags. If the combination of libraries is found and passes + # the link test, LIBRARIES is set to the list of complete library paths that + # have been found. Otherwise, LIBRARIES is set to FALSE. + + # N.B. _prefix is the prefix applied to the names of all cached variables that + # are generated internally and marked advanced by this macro. + + set(_libraries_work TRUE) + set(${LIBRARIES}) + set(_combined_name) + if (NOT _libdir) + if (WIN32) + set(_libdir ENV LIB) + elseif (APPLE) + set(_libdir ENV DYLD_LIBRARY_PATH) + else () + set(_libdir ENV LD_LIBRARY_PATH) + endif () + endif () + foreach(_library ${_list}) + set(_combined_name ${_combined_name}_${_library}) + + if(_libraries_work) + if (BLA_STATIC) + if (WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif () + if (APPLE) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else () + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif () + else () + if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + # for ubuntu's libblas3gf and liblapack3gf packages + set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf) + endif () + endif () + find_library(${_prefix}_${_library}_LIBRARY + NAMES ${_library} + PATHS ${_libdir} + ) + mark_as_advanced(${_prefix}_${_library}_LIBRARY) + set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) + set(_libraries_work ${${_prefix}_${_library}_LIBRARY}) + endif() + endforeach() + + if(_libraries_work) + # Test this combination of libraries. + if(UNIX AND BLA_STATIC) + set(CMAKE_REQUIRED_LIBRARIES ${_flags} "-Wl,--start-group" ${${LIBRARIES}} ${_blas} "-Wl,--end-group" ${_threads}) + else() + set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas} ${_threads}) + endif() + # message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}") + if (NOT CMAKE_Fortran_COMPILER_LOADED) + check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS) + else () + check_fortran_function_exists(${_name} ${_prefix}${_combined_name}_WORKS) + endif () + set(CMAKE_REQUIRED_LIBRARIES) + mark_as_advanced(${_prefix}${_combined_name}_WORKS) + set(_libraries_work ${${_prefix}${_combined_name}_WORKS}) + #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}") + endif() + + if(_libraries_work) + set(${LIBRARIES} ${${LIBRARIES}} ${_blas} ${_threads}) + else() + set(${LIBRARIES} FALSE) + endif() + +endmacro() + + +set(LAPACK_LINKER_FLAGS) +set(LAPACK_LIBRARIES) +set(LAPACK95_LIBRARIES) + + +if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) + find_package(BLASFixed) +else() + find_package(BLASFixed REQUIRED) +endif() + +if(BLAS_FOUND) + set(LAPACK_LINKER_FLAGS ${BLAS_LINKER_FLAGS}) + + if(BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") + if(NOT LAPACK_LIBRARIES) + check_lapack_libraries( + LAPACK_LIBRARIES + LAPACK + cheev + "" + "goto2" + "${BLAS_LIBRARIES}" + "" + ) + endif() + endif () + + if(BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All") + if(NOT LAPACK_LIBRARIES) + check_lapack_libraries( + LAPACK_LIBRARIES + LAPACK + cheev + "" + "openblas" + "${BLAS_LIBRARIES}" + "" + ) + endif() + endif() + + #acml lapack + if (BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All") + if (BLAS_LIBRARIES MATCHES ".+acml.+") + set (LAPACK_LIBRARIES ${BLAS_LIBRARIES}) + endif () + endif () + + # Apple LAPACK library? + if(BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All") + if(NOT LAPACK_LIBRARIES) + check_lapack_libraries( + LAPACK_LIBRARIES + LAPACK + cheev + "" + "Accelerate" + "${BLAS_LIBRARIES}" + "" + ) + endif() + endif () + if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All") + if ( NOT LAPACK_LIBRARIES ) + check_lapack_libraries( + LAPACK_LIBRARIES + LAPACK + cheev + "" + "vecLib" + "${BLAS_LIBRARIES}" + "" + ) + endif () + endif () + # Generic LAPACK library? + if (BLA_VENDOR STREQUAL "Generic" OR + BLA_VENDOR STREQUAL "ATLAS" OR + BLA_VENDOR STREQUAL "All") + if ( NOT LAPACK_LIBRARIES ) + check_lapack_libraries( + LAPACK_LIBRARIES + LAPACK + cheev + "" + "lapack" + "${BLAS_LIBRARIES}" + "" + ) + endif () + endif () +else() + message(STATUS "LAPACK requires BLAS") +endif() + +if(BLA_F95) + if(LAPACK95_LIBRARIES) + set(LAPACK95_FOUND TRUE) + else() + set(LAPACK95_FOUND FALSE) + endif() + if(NOT LAPACK_FIND_QUIETLY) + if(LAPACK95_FOUND) + message(STATUS "A library with LAPACK95 API found.") + else() + if(LAPACK_FIND_REQUIRED) + message(FATAL_ERROR + "A required library with LAPACK95 API not found. Please specify library location." + ) + else() + message(STATUS + "A library with LAPACK95 API not found. Please specify library location." + ) + endif() + endif() + endif() + set(LAPACK_FOUND "${LAPACK95_FOUND}") + set(LAPACK_LIBRARIES "${LAPACK95_LIBRARIES}") +else() + if(LAPACK_LIBRARIES) + set(LAPACK_FOUND TRUE) + else() + set(LAPACK_FOUND FALSE) + endif() + + if(NOT LAPACK_FIND_QUIETLY) + if(LAPACK_FOUND) + message(STATUS "A library with LAPACK API found.") + else() + if(LAPACK_FIND_REQUIRED) + message(FATAL_ERROR + "A required library with LAPACK API not found. Please specify library location." + ) + else() + message(STATUS + "A library with LAPACK API not found. Please specify library location." + ) + endif() + endif() + endif() +endif() + +cmake_pop_check_state() set(CMAKE_FIND_LIBRARY_SUFFIXES ${_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) \ No newline at end of file diff --git a/cmake/patched-cmake-modules/FindOpenMPFixed.cmake b/cmake/patched-cmake-modules/FindOpenMPFixed.cmake new file mode 100644 index 000000000..f6d2cdb3e --- /dev/null +++ b/cmake/patched-cmake-modules/FindOpenMPFixed.cmake @@ -0,0 +1,463 @@ +# AMBER: backported CMake 3.9's FindOpenMP to work on CMake 3.1 +# Also renamed the targets to "openmp_" for simplicity (I hate how verbose the normal names are), and added OpenMP__OPTIONS + +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#.rst: +# FindOpenMP +# ---------- +# +# Finds OpenMP support +# +# This module can be used to detect OpenMP support in a compiler. If +# the compiler supports OpenMP, the flags required to compile with +# OpenMP support are returned in variables for the different languages. +# The variables may be empty if the compiler does not need a special +# flag to support OpenMP. +# +# Variables +# ^^^^^^^^^ +# +# This module will set the following variables per language in your +# project, where ```` is one of C, CXX, or Fortran: +# +# ``OpenMP__FOUND`` +# Variable indicating if OpenMP support for ```` was detected. +# ``OpenMP__FLAGS`` +# OpenMP compiler flags for ````, separated by spaces. +# ``OpenMP__OPTIONS`` +# OpenMP compiler flags for ````, separated by semicolons. +# +# For linking with OpenMP code written in ````, the following +# variables are provided: +# +# ``OpenMP__LIB_NAMES`` +# :ref:`;-list ` of libraries for OpenMP programs for ````. +# ``OpenMP__LIBRARY`` +# Location of the individual libraries needed for OpenMP support in ````. +# ``OpenMP__LIBRARIES`` +# A list of libraries needed to link with OpenMP code written in ````. +# +# Additionally, the module provides :prop_tgt:`IMPORTED` targets: +# +# ``openmp_`` +# Target for using OpenMP from ````. +# +# Specifically for Fortran, the module sets the following variables: +# +# ``OpenMP_Fortran_HAVE_OMPLIB_HEADER`` +# Boolean indicating if OpenMP is accessible through ``omp_lib.h``. +# ``OpenMP_Fortran_HAVE_OMPLIB_MODULE`` +# Boolean indicating if OpenMP is accessible through the ``omp_lib`` Fortran module. +# +# The module will also try to provide the OpenMP version variables: +# +# ``OpenMP__SPEC_DATE`` +# Date of the OpenMP specification implemented by the ```` compiler. +# ``OpenMP__VERSION_MAJOR`` +# Major version of OpenMP implemented by the ```` compiler. +# ``OpenMP__VERSION_MINOR`` +# Minor version of OpenMP implemented by the ```` compiler. +# ``OpenMP__VERSION`` +# OpenMP version implemented by the ```` compiler. +# +# The specification date is formatted as given in the OpenMP standard: +# ``yyyymm`` where ``yyyy`` and ``mm`` represents the year and month of +# the OpenMP specification implemented by the ```` compiler. +# +# Backward Compatibility +# ^^^^^^^^^^^^^^^^^^^^^^ +# +# For backward compatibility with older versions of FindOpenMP, these +# variables are set, but deprecated:: +# +# OpenMP_FOUND +# +# In new projects, please use the ``OpenMP__XXX`` equivalents. + +cmake_policy(PUSH) + +function(_OPENMP_FLAG_CANDIDATES LANG) + if(NOT OpenMP_${LANG}_FLAG) + unset(OpenMP_FLAG_CANDIDATES) + + set(OMP_FLAG_GNU "-fopenmp") + set(OMP_FLAG_Clang "-fopenmp=libomp" "-fopenmp=libiomp5" "-fopenmp") + set(OMP_FLAG_HP "+Oopenmp") + if(WIN32) + set(OMP_FLAG_Intel "-Qopenmp") + elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Intel" AND + "${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS "15.0.0.20140528") + set(OMP_FLAG_Intel "-openmp") + else() + set(OMP_FLAG_Intel "-qopenmp") + endif() + set(OMP_FLAG_MIPSpro "-mp") + set(OMP_FLAG_MSVC "-openmp") + set(OMP_FLAG_PathScale "-openmp") + set(OMP_FLAG_NAG "-openmp") + set(OMP_FLAG_Absoft "-openmp") + set(OMP_FLAG_PGI "-mp") + set(OMP_FLAG_SunPro "-xopenmp") + set(OMP_FLAG_XL "-qsmp=omp") + # Cray compiles with OpenMP automatically + set(OMP_FLAG_Cray " ") + + # If we know the correct flags, use those + if(DEFINED OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}) + set(OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}") + # Fall back to reasonable default tries otherwise + else() + set(OpenMP_FLAG_CANDIDATES "-openmp" "-fopenmp" "-mp" " ") + endif() + set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE) + else() + set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_${LANG}_FLAG}" PARENT_SCOPE) + endif() +endfunction() + +# sample openmp source code to test +set(OpenMP_C_CXX_TEST_SOURCE +" +#include +int main() { +#ifndef _OPENMP + breaks_on_purpose +#endif +} +") + +# in Fortran, an implementation may provide an omp_lib.h header +# or omp_lib module, or both (OpenMP standard, section 3.1) +# Furthmore !$ is the Fortran equivalent of #ifdef _OPENMP (OpenMP standard, 2.2.2) +# Without the conditional compilation, some compilers (e.g. PGI) might compile OpenMP code +# while not actually enabling OpenMP, building code sequentially +set(OpenMP_Fortran_TEST_SOURCE + " + program test + @OpenMP_Fortran_INCLUDE_LINE@ + !$ integer :: n + n = omp_get_num_threads() + end program test + " +) + +function(_OPENMP_WRITE_SOURCE_FILE LANG SRC_FILE_CONTENT_VAR SRC_FILE_NAME SRC_FILE_FULLPATH) + set(WORK_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP) + if("${LANG}" STREQUAL "C") + set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.c") + file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}") + elseif("${LANG}" STREQUAL "CXX") + set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.cpp") + file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}") + elseif("${LANG}" STREQUAL "Fortran") + set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.f90") + file(WRITE "${SRC_FILE}_in" "${OpenMP_Fortran_${SRC_FILE_CONTENT_VAR}}") + configure_file("${SRC_FILE}_in" "${SRC_FILE}" @ONLY) + endif() + set(${SRC_FILE_FULLPATH} "${SRC_FILE}" PARENT_SCOPE) +endfunction() + +include(${CMAKE_ROOT}/Modules/CMakeParseImplicitLinkInfo.cmake) + +function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR) + _OPENMP_FLAG_CANDIDATES("${LANG}") + _OPENMP_WRITE_SOURCE_FILE("${LANG}" "TEST_SOURCE" OpenMPTryFlag _OPENMP_TEST_SRC) + + foreach(OPENMP_FLAG IN LISTS OpenMP_${LANG}_FLAG_CANDIDATES) + set(OPENMP_FLAGS_TEST "${OPENMP_FLAG}") + if(CMAKE_${LANG}_VERBOSE_FLAG) + string(APPEND OPENMP_FLAGS_TEST " ${CMAKE_${LANG}_VERBOSE_FLAG}") + endif() + string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}") + try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC} + CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}" + OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT + ) + + if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}) + set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE) + + if(CMAKE_${LANG}_VERBOSE_FLAG) + unset(OpenMP_${LANG}_IMPLICIT_LIBRARIES) + unset(OpenMP_${LANG}_IMPLICIT_LINK_DIRS) + unset(OpenMP_${LANG}_IMPLICIT_FWK_DIRS) + unset(OpenMP_${LANG}_LOG_VAR) + + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Detecting ${LANG} OpenMP compiler ABI info compiled with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n") + + cmake_parse_implicit_link_info("${OpenMP_TRY_COMPILE_OUTPUT}" + OpenMP_${LANG}_IMPLICIT_LIBRARIES + OpenMP_${LANG}_IMPLICIT_LINK_DIRS + OpenMP_${LANG}_IMPLICIT_FWK_DIRS + OpenMP_${LANG}_LOG_VAR + "${CMAKE_${LANG}_IMPLICIT_OBJECT_REGEX}" + ) + + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Parsed ${LANG} OpenMP implicit link information from above output:\n${OpenMP_${LANG}_LOG_VAR}\n\n") + + unset(_OPENMP_LIB_NAMES) + foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_IMPLICIT_LIBRARIES) + + list_contains(HAS_IMPLICIT_LIB "${_OPENMP_IMPLICIT_LIB}" ${CMAKE_${LANG}_IMPLICIT_LINK_LIBRARIES}) + if(NOT HAS_IMPLICIT_LIB) + find_library(OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY + NAMES "${_OPENMP_IMPLICIT_LIB}" + HINTS ${OpenMP_${LANG}_IMPLICIT_LINK_DIRS} + ) + mark_as_advanced(OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY) + list(APPEND _OPENMP_LIB_NAMES ${_OPENMP_IMPLICIT_LIB}) + endif() + endforeach() + set("${OPENMP_LIB_NAMES_VAR}" "${_OPENMP_LIB_NAMES}" PARENT_SCOPE) + else() + # The Intel compiler on windows has no verbose mode, so we need to treat it explicitly + if("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "Intel" AND "${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") + set("${OPENMP_LIB_NAMES_VAR}" "libiomp5md" PARENT_SCOPE) + find_library(OpenMP_libiomp5md_LIBRARY + NAMES "libiomp5md" + HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES} + ) + mark_as_advanced(OpenMP_libiomp5md_LIBRARY) + else() + set("${OPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE) + endif() + endif() + break() + endif() + set("${OPENMP_LIB_NAMES_VAR}" "NOTFOUND" PARENT_SCOPE) + set("${OPENMP_FLAG_VAR}" "NOTFOUND" PARENT_SCOPE) + endforeach() +endfunction() + +set(OpenMP_C_CXX_CHECK_VERSION_SOURCE +" +#include +#include +const char ompver_str[] = { 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M', + 'P', '-', 'd', 'a', 't', 'e', '[', + ('0' + ((_OPENMP/100000)%10)), + ('0' + ((_OPENMP/10000)%10)), + ('0' + ((_OPENMP/1000)%10)), + ('0' + ((_OPENMP/100)%10)), + ('0' + ((_OPENMP/10)%10)), + ('0' + ((_OPENMP/1)%10)), + ']', '\\0' }; +int main() +{ + puts(ompver_str); +} +") + +set(OpenMP_Fortran_CHECK_VERSION_SOURCE +" + program omp_ver + @OpenMP_Fortran_INCLUDE_LINE@ + integer, parameter :: zero = ichar('0') + integer, parameter :: ompv = openmp_version + character, dimension(24), parameter :: ompver_str =& + (/ 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M', 'P', '-',& + 'd', 'a', 't', 'e', '[',& + char(zero + mod(ompv/100000, 10)),& + char(zero + mod(ompv/10000, 10)),& + char(zero + mod(ompv/1000, 10)),& + char(zero + mod(ompv/100, 10)),& + char(zero + mod(ompv/10, 10)),& + char(zero + mod(ompv/1, 10)), ']' /) + print *, ompver_str + end program omp_ver +") + +function(_OPENMP_GET_SPEC_DATE LANG SPEC_DATE) + _OPENMP_WRITE_SOURCE_FILE("${LANG}" "CHECK_VERSION_SOURCE" OpenMPCheckVersion _OPENMP_TEST_SRC) + + set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP/ompver_${LANG}.bin") + string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}") + try_compile(OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG} "${CMAKE_BINARY_DIR}" "${_OPENMP_TEST_SRC}" + CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenMP_${LANG}_FLAGS}" + COPY_FILE ${BIN_FILE}) + + if(${OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG}}) + file(STRINGS ${BIN_FILE} specstr LIMIT_COUNT 1 REGEX "INFO:OpenMP-date") + set(regex_spec_date ".*INFO:OpenMP-date\\[0*([^]]*)\\].*") + if("${specstr}" MATCHES "${regex_spec_date}") + set(${SPEC_DATE} "${CMAKE_MATCH_1}" PARENT_SCOPE) + endif() + endif() +endfunction() + +macro(_OPENMP_SET_VERSION_BY_SPEC_DATE LANG) + set(OpenMP_SPEC_DATE_MAP + # Combined versions, 2.5 onwards + "201511=4.5" + "201307=4.0" + "201107=3.1" + "200805=3.0" + "200505=2.5" + # C/C++ version 2.0 + "200203=2.0" + # Fortran version 2.0 + "200011=2.0" + # Fortran version 1.1 + "199911=1.1" + # C/C++ version 1.0 (there's no 1.1 for C/C++) + "199810=1.0" + # Fortran version 1.0 + "199710=1.0" + ) + + string(REGEX MATCHALL "${OpenMP_${LANG}_SPEC_DATE}=([0-9]+)\\.([0-9]+)" _version_match "${OpenMP_SPEC_DATE_MAP}") + if(NOT _version_match STREQUAL "") + set(OpenMP_${LANG}_VERSION_MAJOR ${CMAKE_MATCH_1}) + set(OpenMP_${LANG}_VERSION_MINOR ${CMAKE_MATCH_2}) + set(OpenMP_${LANG}_VERSION "${OpenMP_${LANG}_VERSION_MAJOR}.${OpenMP_${LANG}_VERSION_MINOR}") + else() + unset(OpenMP_${LANG}_VERSION_MAJOR) + unset(OpenMP_${LANG}_VERSION_MINOR) + unset(OpenMP_${LANG}_VERSION) + endif() + unset(_version_match) + unset(OpenMP_SPEC_DATE_MAP) +endmacro() + +foreach(LANG IN ITEMS C CXX) + if(CMAKE_${LANG}_COMPILER_LOADED) + if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND" + OR NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND") + _OPENMP_GET_FLAGS("${LANG}" "${LANG}" OpenMP_${LANG}_FLAGS_WORK OpenMP_${LANG}_LIB_NAMES_WORK) + endif() + + set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}" + CACHE STRING "${LANG} compiler flags for OpenMP parallelization") + set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}" + CACHE STRING "${LANG} compiler libraries for OpenMP parallelization") + mark_as_advanced(OpenMP_${LANG}_FLAGS OpenMP_${LANG}_LIB_NAMES) + endif() +endforeach() + +if(CMAKE_Fortran_COMPILER_LOADED) + if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND" + OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND" + OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE) + set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none") + _OPENMP_GET_FLAGS("Fortran" "FortranHeader" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK) + if(OpenMP_Fortran_FLAGS_WORK) + set(OpenMP_Fortran_HAVE_OMPLIB_MODULE TRUE CACHE BOOL INTERNAL "") + endif() + + set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}" + CACHE STRING "Fortran compiler flags for OpenMP parallelization") + set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}" + CACHE STRING "Fortran compiler libraries for OpenMP parallelization") + mark_as_advanced(OpenMP_Fortran_FLAGS OpenMP_Fortran_LIB_NAMES) + endif() + + if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND" + OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND" + OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER) + set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'") + _OPENMP_GET_FLAGS("Fortran" "FortranModule" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK) + if(OpenMP_Fortran_FLAGS_WORK) + set(OpenMP_Fortran_HAVE_OMPLIB_HEADER TRUE CACHE BOOL INTERNAL "") + endif() + + set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}" + CACHE STRING "Fortran compiler flags for OpenMP parallelization") + + set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES}" + CACHE STRING "Fortran compiler libraries for OpenMP parallelization") + endif() + + if(OpenMP_Fortran_HAVE_OMPLIB_MODULE) + set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none") + else() + set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'") + endif() +endif() + +set(OPENMP_FOUND TRUE) + +foreach(LANG IN ITEMS C CXX Fortran) + if(CMAKE_${LANG}_COMPILER_LOADED) + if (NOT OpenMP_${LANG}_SPEC_DATE) + _OPENMP_GET_SPEC_DATE("${LANG}" OpenMP_${LANG}_SPEC_DATE_INTERNAL) + set(OpenMP_${LANG}_SPEC_DATE "${OpenMP_${LANG}_SPEC_DATE_INTERNAL}" CACHE + INTERNAL "${LANG} compiler's OpenMP specification date") + _OPENMP_SET_VERSION_BY_SPEC_DATE("${LANG}") + endif() + + include(FindPackageHandleStandardArgs) + + set(OpenMP_${LANG}_FIND_QUIETLY ${OpenMPFixed_FIND_QUIETLY}) + set(OpenMP_${LANG}_FIND_REQUIRED ${OpenMPFixed_FIND_REQUIRED}) + set(OpenMP_${LANG}_FIND_VERSION ${OpenMPFixed_FIND_VERSION}) + set(OpenMP_${LANG}_FIND_VERSION_EXACT ${OpenMPFixed_FIND_VERSION_EXACT}) + + set(_OPENMP_${LANG}_REQUIRED_VARS OpenMP_${LANG}_FLAGS) + if("${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND") + set(_OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${LANG}_LIB_NAMES) + else() + foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES) + list(APPEND _OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY) + endforeach() + endif() + + find_package_handle_standard_args(OpenMP_${LANG} + REQUIRED_VARS OpenMP_${LANG}_FLAGS ${_OPENMP_${LANG}_REQUIRED_LIB_VARS} + VERSION_VAR OpenMP_${LANG}_VERSION + ) + + if(OpenMP_${LANG}_FOUND) + set(OpenMP_${LANG}_LIBRARIES "") + foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES) + list(APPEND OpenMP_${LANG}_LIBRARIES "${OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY}") + endforeach() + + string(TOLOWER ${LANG} LANG_LC) + + if(NOT TARGET openmp_${LANG_LC}) + add_library(openmp_${LANG_LC} INTERFACE IMPORTED) + endif() + if(OpenMP_${LANG}_FLAGS) + if(HOST_WINDOWS) + separate_arguments(OpenMP_${LANG}_OPTIONS WINDOWS_COMMAND "${OpenMP_${LANG}_FLAGS}") + else() + separate_arguments(OpenMP_${LANG}_OPTIONS UNIX_COMMAND "${OpenMP_${LANG}_FLAGS}") + endif() + + set_property(TARGET openmp_${LANG_LC} PROPERTY + INTERFACE_COMPILE_OPTIONS "${OpenMP_${LANG}_OPTIONS}") + endif() + if(OpenMP_${LANG}_LIBRARIES) + set_property(TARGET openmp_${LANG_LC} PROPERTY + INTERFACE_LINK_LIBRARIES "${OpenMP_${LANG}_LIBRARIES}") + endif() + else() + set(OPENMP_FOUND FALSE) + endif() + endif() +endforeach() + +if(CMAKE_Fortran_COMPILER_LOADED AND OpenMP_Fortran_FOUND) + if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE) + set(OpenMP_Fortran_HAVE_OMPLIB_MODULE FALSE CACHE BOOL INTERNAL "") + endif() + if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER) + set(OpenMP_Fortran_HAVE_OMPLIB_HEADER FALSE CACHE BOOL INTERNAL "") + endif() +endif() + +if(NOT ( CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED )) + message(SEND_ERROR "FindOpenMP requires the C, CXX or Fortran languages to be enabled") +endif() + +unset(OpenMP_C_CXX_TEST_SOURCE) +unset(OpenMP_Fortran_TEST_SOURCE) +unset(OpenMP_C_CXX_CHECK_VERSION_SOURCE) +unset(OpenMP_Fortran_CHECK_VERSION_SOURCE) +unset(OpenMP_Fortran_INCLUDE_LINE) + +cmake_policy(POP) \ No newline at end of file diff --git a/quick-cmake/FindHipCUDA.cmake b/quick-cmake/FindHipCUDA.cmake index 288bcf211..c6eaa1de3 100644 --- a/quick-cmake/FindHipCUDA.cmake +++ b/quick-cmake/FindHipCUDA.cmake @@ -912,7 +912,7 @@ foreach(_name IN ITEMS cufft cublas curand cusparse cusolver) endif() # If HIP wrappers exist, append those - #if(NOT _name MATCHES "(solver)") +# if(NOT _name MATCHES "(solver)") string(REGEX REPLACE "^(cu)" "hip" _hipname ${_name}) if(_name MATCHES "(fft|rand)") set(_hipnamespace "hip") @@ -929,8 +929,11 @@ foreach(_name IN ITEMS cufft cublas curand cusparse cusolver) if(_name MATCHES "(fft)") list(PREPEND CUDA_INCLUDE_DIRS ${HIPFFT_INCLUDE_DIR}) endif() +# list(PREPEND CUDA_INCLUDE_DIRS ${ROCM_PATH}/include/hipfft/) +# list(PREPEND CUDA_INCLUDE_DIRS ${ROCM_PATH}/include/hipblas/) +# list(PREPEND CUDA_INCLUDE_DIRS ${ROCM_PATH}/include/hipsparse/) endif() - #endif() +# endif() # Add legacy uppercase variables if(_name MATCHES "(fft|blas)") diff --git a/quick-cmake/QUICKCudaConfig.cmake b/quick-cmake/QUICKCudaConfig.cmake index 9705b7ae3..7e59a57e3 100644 --- a/quick-cmake/QUICKCudaConfig.cmake +++ b/quick-cmake/QUICKCudaConfig.cmake @@ -13,10 +13,12 @@ if(CUDA) if(NOT CUDA_FOUND) message(FATAL_ERROR "You turned on CUDA, but it was not found. Please set the CUDA_TOOLKIT_ROOT_DIR option to your CUDA install directory.") endif() + # cancel Amber arch flags, because quick supports different shader models set(CUDA_NVCC_FLAGS "") set(CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER}) + #SM9.0 = H100, GH200 (Hopper) set(SM90FLAGS -gencode arch=compute_90,code=sm_90) #SM8.9 = L4, L40 (Ada Lovelace) @@ -55,50 +57,58 @@ if(CUDA) if("${QUICK_USER_ARCH}" STREQUAL "") # build for all supported CUDA versions - if(${CUDA_VERSION} VERSION_EQUAL 8.0) - message(STATUS "Configuring QUICK for SM3.0, SM5.0, and SM6.0") - list(APPEND CUDA_NVCC_FLAGS ${SM30FLAGS} ${SM50FLAGS} ${SM60FLAGS}) + if(${CUDA_VERSION} VERSION_EQUAL 7.5) + message(STATUS "Configuring QUICK for SM3.0, SM3.5, SM3.7, SM5.0, SM5.2 and SM5.3") + message(STATUS "BE AWARE: CUDA 7.5 does not support GTX-1080, Titan-XP, DGX-1, V100 or other Pascal/Volta based GPUs.") + list(APPEND CUDA_NVCC_FLAGS ${SM30FLAGS} ${SM35FLAGS} ${SM37FLAGS} ${SM50FLAGS} ${SM52FLAGS} ${SM53FLAGS}) + list(APPEND CUDA_NVCC_FLAGS -DUSE_LEGACY_ATOMICS) + set(DISABLE_OPTIMIZER_CONSTANTS TRUE) + + elseif(${CUDA_VERSION} VERSION_EQUAL 8.0) + message(STATUS "Configuring QUICK for SM3.0, SM3.5, SM3.7, SM5.0, SM5.2, SM5.3, SM6.0 and SM6.1,") + message(STATUS "BE AWARE: CUDA 8.0 does not support V100, GV100, Titan-V or later GPUs") + list(APPEND CUDA_NVCC_FLAGS ${SM30FLAGS} ${SM35FLAGS} ${SM37FLAGS} ${SM50FLAGS} ${SM52FLAGS} ${SM53FLAGS} ${SM60FLAGS} ${SM61FLAGS}) list(APPEND CUDA_NVCC_FLAGS -DUSE_LEGACY_ATOMICS) set(DISABLE_OPTIMIZER_CONSTANTS TRUE) elseif((${CUDA_VERSION} VERSION_GREATER_EQUAL 9.0) AND (${CUDA_VERSION} VERSION_LESS 10.0)) - message(STATUS "Configuring QUICK for SM3.0, SM5.0, SM6.0 and SM7.0") - list(APPEND CUDA_NVCC_FLAGS ${SM30FLAGS} ${SM50FLAGS} ${SM60FLAGS} ${SM70FLAGS}) + message(STATUS "Configuring QUICK for SM3.0, SM3.5, SM3.7, SM5.0, SM5.2, SM5.3, SM6.0, SM6.1 and SM7.0") + list(APPEND CUDA_NVCC_FLAGS ${SM30FLAGS} ${SM35FLAGS} ${SM37FLAGS} ${SM50FLAGS} ${SM52FLAGS} ${SM53FLAGS} ${SM60FLAGS} ${SM61FLAGS} ${SM70FLAGS}) list(APPEND CUDA_NVCC_FLAGS -DUSE_LEGACY_ATOMICS) set(DISABLE_OPTIMIZER_CONSTANTS TRUE) elseif((${CUDA_VERSION} VERSION_GREATER_EQUAL 10.0) AND (${CUDA_VERSION} VERSION_LESS 11.0)) - message(STATUS "Configuring QUICK for SM3.0, SM5.0, SM6.0, SM7.0 and SM7.5") - list(APPEND CUDA_NVCC_FLAGS ${SM30FLAGS} ${SM50FLAGS} ${SM60FLAGS} ${SM70FLAGS} ${SM75FLAGS}) + message(STATUS "Configuring QUICK for SM3.0, SM3.5, SM3.7, SM5.0, SM5.2, SM5.3, SM6.0, SM6.1, SM7.0 and SM7.5") + list(APPEND CUDA_NVCC_FLAGS ${SM30FLAGS} ${SM35FLAGS} ${SM37FLAGS} ${SM50FLAGS} ${SM52FLAGS} ${SM53FLAGS} ${SM60FLAGS} ${SM61FLAGS} ${SM70FLAGS} ${SM75FLAGS}) list(APPEND CUDA_NVCC_FLAGS -DUSE_LEGACY_ATOMICS) set(DISABLE_OPTIMIZER_CONSTANTS TRUE) elseif((${CUDA_VERSION} VERSION_EQUAL 11.0)) - message(STATUS "Configuring QUICK for SM3.0, SM3.5, SM3.7, SM5.0, SM6.0, SM7.0, SM7.5 and SM8.0") - list(APPEND CUDA_NVCC_FLAGS ${SM30FLAGS} ${SM35FLAGS} ${SM37FLAGS} ${SM50FLAGS} ${SM60FLAGS} ${SM70FLAGS} ${SM75FLAGS} ${SM80FLAGS}) + message(STATUS "Configuring QUICK for SM3.0, SM3.5, SM3.7, SM5.0, SM5.2, SM5.3, SM6.0, SM6.1, SM7.0, SM7.5 and SM8.0") + list(APPEND CUDA_NVCC_FLAGS ${SM30FLAGS} ${SM35FLAGS} ${SM37FLAGS} ${SM50FLAGS} ${SM52FLAGS} ${SM53FLAGS} ${SM60FLAGS} ${SM61FLAGS} ${SM70FLAGS} ${SM75FLAGS} ${SM80FLAGS}) list(APPEND CUDA_NVCC_FLAGS -DUSE_LEGACY_ATOMICS) set(DISABLE_OPTIMIZER_CONSTANTS TRUE) elseif((${CUDA_VERSION} VERSION_GREATER_EQUAL 11.1) AND (${CUDA_VERSION} VERSION_LESS_EQUAL 11.7)) - message(STATUS "Configuring QUICK for SM3.5, SM3.7, SM5.0, SM6.0, SM7.0, SM7.5, SM8.0 and SM8.6") - list(APPEND CUDA_NVCC_FLAGS ${SM35FLAGS} ${SM37FLAGS} ${SM50FLAGS} ${SM60FLAGS} ${SM70FLAGS} ${SM75FLAGS} ${SM80FLAGS} ${SM86FLAGS}) + message(STATUS "Configuring QUICK for SM3.5, SM3.7, SM5.0, SM5.2, SM5.3, SM6.0, SM6.1, SM7.0, SM7.5, SM8.0 and SM8.6") + list(APPEND CUDA_NVCC_FLAGS ${SM35FLAGS} ${SM37FLAGS} ${SM50FLAGS} ${SM52FLAGS} ${SM53FLAGS} ${SM60FLAGS} ${SM61FLAGS} ${SM70FLAGS} ${SM75FLAGS} ${SM80FLAGS} ${SM86FLAGS}) list(APPEND CUDA_NVCC_FLAGS -DUSE_LEGACY_ATOMICS) set(DISABLE_OPTIMIZER_CONSTANTS TRUE) elseif((${CUDA_VERSION} VERSION_EQUAL 11.8)) - message(STATUS "Configuring QUICK for SM3.5, SM3.7, SM5.0, SM6.0, SM7.0, SM7.5, SM8.0, SM8.6, SM8.9, SM9.0") - list(APPEND CUDA_NVCC_FLAGS ${SM35FLAGS} ${SM37FLAGS} ${SM50FLAGS} ${SM60FLAGS} ${SM70FLAGS} ${SM75FLAGS} ${SM80FLAGS} ${SM86FLAGS} ${SM89FLAGS} ${SM90FLAGS}) + message(STATUS "Configuring QUICK for SM3.5, SM3.7, SM5.0, SM5.2, SM5.3, SM6.0, SM6.1, SM7.0, SM7.5, SM8.0, SM8.6, SM8.9 and SM9.0") + list(APPEND CUDA_NVCC_FLAGS ${SM35FLAGS} ${SM37FLAGS} ${SM50FLAGS} ${SM52FLAGS} ${SM53FLAGS} ${SM60FLAGS} ${SM61FLAGS} ${SM70FLAGS} ${SM75FLAGS} ${SM80FLAGS} ${SM86FLAGS} ${SM89FLAGS} ${SM90FLAGS}) list(APPEND CUDA_NVCC_FLAGS -DUSE_LEGACY_ATOMICS) set(DISABLE_OPTIMIZER_CONSTANTS TRUE) - elseif((${CUDA_VERSION} VERSION_GREATER_EQUAL 12.0) AND (${CUDA_VERSION} VERSION_LESS_EQUAL 12.3)) - message(STATUS "Configuring QUICK for SM5.0, SM6.0, SM7.0, SM7.5, SM8.0, SM8.6, SM8.9, SM9.0") - list(APPEND CUDA_NVCC_FLAGS ${SM50FLAGS} ${SM60FLAGS} ${SM70FLAGS} ${SM75FLAGS} ${SM80FLAGS} ${SM86FLAGS} ${SM89FLAGS} ${SM90FLAGS}) + elseif((${CUDA_VERSION} VERSION_GREATER_EQUAL 12.0) AND (${CUDA_VERSION} VERSION_LESS 12.5)) + message(STATUS "Configuring QUICK for SM5.0, SM5.2, SM5.3, SM6.0, SM6.1, SM7.0, SM7.5, SM8.0, SM8.6, SM8.9 and SM9.0") + list(APPEND CUDA_NVCC_FLAGS ${SM50FLAGS} ${SM52FLAGS} ${SM53FLAGS} ${SM60FLAGS} ${SM61FLAGS} ${SM70FLAGS} ${SM75FLAGS} ${SM80FLAGS} ${SM86FLAGS} ${SM89FLAGS} ${SM90FLAGS}) list(APPEND CUDA_NVCC_FLAGS -DUSE_LEGACY_ATOMICS) set(DISABLE_OPTIMIZER_CONSTANTS TRUE) else() - message(FATAL_ERROR "Error: Unsupported CUDA version. ${PROJECT_NAME} requires CUDA version >= 8.0 and <= 12.3. Please upgrade your CUDA installation or disable building with CUDA.") + message(FATAL_ERROR "Error: Unsupported CUDA version. ${PROJECT_NAME} requires CUDA version >= 8.0 and <= 12.4. Please upgrade your CUDA installation or disable building with CUDA.") endif() else() @@ -170,6 +180,67 @@ if(CUDA) endif() endif() + + # check maximum GNU compiler versions wrt cuda: + # PROGRAMMER WARNING: This code is NOT trivial. Before you + # modify it, read and understand it and the stackoverflow link ! + # https://stackoverflow.com/questions/6622454/cuda-incompatible-with-my-gcc-version + # VERSION_EQUAL 10 means 10.0, so use ranges to compare major versions. + if ( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" AND ( + ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.3 + AND CUDA_VERSION VERSION_GREATER_EQUAL 12.4 + AND CUDA_VERSION VERSION_LESS_EQUAL 12.4 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.3 + AND CUDA_VERSION VERSION_GREATER_EQUAL 12.1 + AND CUDA_VERSION VERSION_LESS_EQUAL 12.3 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.2 + AND CUDA_VERSION VERSION_GREATER_EQUAL 12 + AND CUDA_VERSION VERSION_LESS_EQUAL 12 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12 + AND CUDA_VERSION VERSION_GREATER_EQUAL 11.4.1 + AND CUDA_VERSION VERSION_LESS_EQUAL 11.8 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 11 + AND CUDA_VERSION VERSION_GREATER_EQUAL 11.1 + AND CUDA_VERSION VERSION_LESS_EQUAL 11.4.0 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10 + AND CUDA_VERSION VERSION_GREATER_EQUAL 11 + AND CUDA_VERSION VERSION_LESS_EQUAL 11 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9 + AND CUDA_VERSION VERSION_GREATER_EQUAL 10.1 + AND CUDA_VERSION VERSION_LESS_EQUAL 10.2 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8 + AND CUDA_VERSION VERSION_GREATER_EQUAL 9.2 + AND CUDA_VERSION VERSION_LESS_EQUAL 10.0 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7 + AND CUDA_VERSION VERSION_GREATER_EQUAL 9.0 + AND CUDA_VERSION VERSION_LESS_EQUAL 9.1 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6 + AND CUDA_VERSION VERSION_GREATER_EQUAL 8 + AND CUDA_VERSION VERSION_LESS_EQUAL 8 ) + OR ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5 + AND CUDA_VERSION VERSION_GREATER_EQUAL 7 + AND CUDA_VERSION VERSION_LESS_EQUAL 7 ) + ) ) + message(STATUS "Checking CUDA and GNU versions -- compatible") + elseif ( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" AND ( + CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13.2 + OR CUDA_VERSION VERSION_GREATER 12.4 + ) ) + message(STATUS "Checking CUDA and GNU versions -- compatibility unknown") + message(STATUS " See https://stackoverflow.com/questions/6622454/cuda-incompatible-with-my-gcc-version") + elseif ( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" ) + message(STATUS "") + message("************************************************************") + message("Error: Incompatible CUDA and GNU versions") + message(" ${CMAKE_CXX_COMPILER_VERSION}") + message(" ${CMAKE_CXX_COMPILER_VERSION_MAJOR}") + message("See https://stackoverflow.com/questions/6622454/cuda-incompatible-with-my-gcc-version") + message("************************************************************") + message(STATUS "") + message(FATAL_ERROR) + else() + message(STATUS "Checking CUDA and compiler versions -- compatibility unknown") + endif() set(CUDA_PROPAGATE_HOST_FLAGS FALSE) @@ -224,6 +295,9 @@ if(CUDA) endif() +#option(HIP "Build ${PROJECT_NAME} with HIP GPU acceleration support." FALSE) +#option(HIP_RDC "Build relocatable device code, also known as separate compilation mode." FALSE) +#option(HIP_WARP64 "Build for CDNA AMD GPUs (warp size 64) or RDNA (warp size 32)" TRUE) if(HIP) # HIP builds currently unavailable (TODO: fix post release) message(FATAL_ERROR "Error: HIP support is currently unavailable in this QUICK release. Support will be added back in a future release.") @@ -250,9 +324,13 @@ if(HIP) endif() - list(APPEND AMD_HIP_FLAGS -fPIC) + list(APPEND AMD_HIP_FLAGS -fPIC -std=c++14) set(TARGET_ID_SUPPORT ON) +# if(HIP_WARP64) +# add_compile_definitions(QUICK_PLATFORM_AMD_WARP64) +# endif() + # HIP codes currently do not support f-functions with -DUSE_LEGACY_ATOMICS targets (gfx906 and gfx908) if(ENABLEF AND (("${QUICK_USER_ARCH}" STREQUAL "") OR ("${QUICK_USER_ARCH}" MATCHES "gfx906") OR ("${QUICK_USER_ARCH}" MATCHES "gfx908"))) message(FATAL_ERROR "Error: Unsupported HIP options (ENABLEF with -DUSE_LEGACY_ATOMICS). ${PROJECT_NAME} support for f-functions requires newer HIP architecture targets not using LEGACY_ATOMICS. Please specify architectures with QUICK_USER_ARCH not needing LEGACY_ATOMICS (post-gfx908) or disable f-function support.") @@ -288,6 +366,15 @@ if(HIP) set(CMAKE_CXX_COMPILER ${HIP_HIPCC_EXECUTABLE}) set(CMAKE_CXX_LINKER ${HIP_HIPCC_EXECUTABLE}) +# if(HIP_RDC) +# # Only hipcc can link a library compiled using RDC mode +# # -Wl,--unresolved-symbols=ignore-in-object-files is added after +# # because CMAKE_SHARED_LINKER_FLAGS contains -Wl,--no-undefined, but we link +# # the whole program with all external shared libs later. +# set(CMAKE_HIP_CREATE_SHARED_LIBRARY "${CUDA_NVCC_EXECUTABLE} -fgpu-rdc --hip-link -Wl,--unresolved-symbols=ignore-in-object-files -Wl,-soname, -o ") +# # set(CMAKE_CXX_CREATE_SHARED_LIBRARY "${CUDA_NVCC_EXECUTABLE} -fgpu-rdc --hip-link -Wl,--unresolved-symbols=ignore-in-object-files -o ") +# endif() + import_library(cublas "${CUDA_cublas_LIBRARY}") import_library(cusolver "${CUDA_cusolver_LIBRARY}")