mark_as_advanced(GMX_COOL_QUOTES)
gmx_add_cache_dependency(GMX_COOL_QUOTES BOOL "NOT GMX_FAHCORE" OFF)
-option(GMX_USE_OPENCL "Enable OpenCL acceleration" OFF)
-
option(GMX_INSTALL_LEGACY_API "Install legacy headers" OFF)
-# The earliest version of the CUDA toolkit that supports c++14 is 9.0
-set(REQUIRED_CUDA_VERSION 9.0)
-set(REQUIRED_CUDA_COMPUTE_CAPABILITY 3.0)
-
-# OpenCL required version: 1.2 or newer
-set(REQUIRED_OPENCL_MIN_VERSION_MAJOR 1)
-set(REQUIRED_OPENCL_MIN_VERSION_MINOR 2)
-set(REQUIRED_OPENCL_MIN_VERSION ${REQUIRED_OPENCL_MIN_VERSION_MAJOR}.${REQUIRED_OPENCL_MIN_VERSION_MINOR})
-
-if(NOT GMX_USE_OPENCL)
- # CUDA detection is done only if GMX_USE_OPENCL is OFF.
- include(gmxManageGPU)
- set(GMX_USE_CUDA ${GMX_GPU})
- if(GMX_GPU)
- set(GMX_GPU_ACCELERATION_FRAMEWORK "GMX_GPU_CUDA")
- else()
- set(GMX_GPU_ACCELERATION_FRAMEWORK "GMX_GPU_NONE")
- endif()
-else()
- #Now the OpenCL path (for both AMD and NVIDIA)
- if(GMX_GPU)
- include(gmxManageOpenCL)
- set(GMX_GPU_ACCELERATION_FRAMEWORK "GMX_GPU_OPENCL")
- else()
- message(FATAL_ERROR "OpenCL requested but GPU option is not enabled (try -DGMX_GPU=on) ")
- endif()
-endif()
+gmx_option_multichoice(
+ GMX_GPU
+ "Framework for GPU acceleration"
+ None
+ None CUDA OpenCL)
gmx_option_multichoice(
GMX_SIMD
include(gmxManageLmfit)
-if(GMX_GPU)
- # now that we have detected the dependencies, do the second configure pass
- gmx_gpu_setup()
- if (GMX_CLANG_CUDA)
- list(APPEND GMX_EXTRA_LIBRARIES ${GMX_CUDA_CLANG_LINK_LIBS})
- link_directories("${GMX_CUDA_CLANG_LINK_DIRS}")
+string(TOUPPER "${GMX_GPU}" _gmx_gpu_uppercase)
+if(NOT ${_gmx_gpu_uppercase} STREQUAL "NONE")
+
+ if(${_gmx_gpu_uppercase} STREQUAL "CUDA")
+ include(gmxManageCuda)
+ elseif(${_gmx_gpu_uppercase} STREQUAL "OPENCL")
+ include(gmxManageOpenCL)
+ endif()
+ if(NOT GMX_OPENMP)
+ message(WARNING "To use GPU acceleration efficiently, mdrun requires OpenMP multi-threading, which is currently not enabled.")
endif()
+
endif()
+# Not ideal to set this without the GPU acceleration, but the source presently requires GMX_GPU
+# to be set to GMX_GPU_None for a non-GPU build to work.
+set(GMX_GPU_ACCELERATION_FRAMEWORK "GMX_GPU_${_gmx_gpu_uppercase}")
+
if(CYGWIN)
set(GMX_CYGWIN 1)
endif()
# TODO: Make GMXRC adapt if this is changed
set(GMX_INSTALL_PKGCONFIGDIR ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
-set(GMX_INSTALL_OCLDIR ${GMX_INSTALL_GMXDATADIR}/opencl)
list(APPEND INSTALLED_HEADER_INCLUDE_DIRS ${CMAKE_INSTALL_INCLUDEDIR})
gmx_cpack_write_config()
-# Issue a warning if NVIDIA GPUs were detected, but CUDA was not found.
-# Don't bother the user after the first configure pass.
-if ((CUDA_NOTFOUND_AUTO AND GMX_DETECT_GPU_AVAILABLE) AND NOT GMX_GPU_DETECTION_DONE)
- message(WARNING "${CUDA_NOTFOUND_MESSAGE}")
-endif()
-set(GMX_GPU_DETECTION_DONE TRUE CACHE INTERNAL "Whether GPU detection has already been done")
-
#######################
## uninstall target
#######################
CMAKE_MPI_OPTIONS: "-DGMX_THREAD_MPI=OFF"
CMAKE_PRECISION_OPTIONS: "-DGMX_DOUBLE=OFF"
CMAKE_BUILD_TYPE_OPTIONS: "-DCMAKE_BUILD_TYPE=Debug"
- CMAKE_GPU_OPTIONS: "-DGMX_GPU=OFF"
+ CMAKE_GPU_OPTIONS: "-DGMX_GPU=None"
CMAKE_GMXAPI_OPTIONS: "-DGMX_PYTHON_PACKAGE=ON"
script:
- if [[ ! -z $GROMACS_RELEASE && $GROMACS_RELEASE == "true" ]] ; then
CMAKE_MPI_OPTIONS: "-DGMX_THREAD_MPI=ON"
CMAKE_PRECISION_OPTIONS: "-DGMX_DOUBLE=OFF"
CMAKE_BUILD_TYPE_OPTIONS: "-DCMAKE_BUILD_TYPE=Debug"
- CMAKE_GPU_OPTIONS: "-DGMX_GPU=OFF"
+ CMAKE_GPU_OPTIONS: "-DGMX_GPU=None"
CMAKE_GMXAPI_OPTIONS: "-DGMX_PYTHON_PACKAGE=ON"
RELEASE_BUILD_DIR: release-doc-builds
RELEASE_SOURCE: release-source-from-tarball
.use-cuda:
variables:
CMAKE_PRECISION_OPTIONS: "-DGMX_DOUBLE=OFF"
- CMAKE_GPU_OPTIONS: -DGMX_GPU=ON -DGMX_USE_CUDA=ON
+ CMAKE_GPU_OPTIONS: -DGMX_GPU=CUDA
.use-mpi:
variables:
.use-opencl:
variables:
CMAKE_PRECISION_OPTIONS: "-DGMX_DOUBLE=OFF"
- CMAKE_GPU_OPTIONS: -DGMX_GPU=ON -DGMX_USE_OPENCL=ON
+ CMAKE_GPU_OPTIONS: -DGMX_GPU=OpenCL
# Base definition for using gcc.
.use-gcc:base:
CMAKE_MPI_OPTIONS: "-DGMX_THREAD_MPI=ON"
CMAKE_PRECISION_OPTIONS: "-DGMX_DOUBLE=OFF"
CMAKE_BUILD_TYPE_OPTIONS: "-DCMAKE_BUILD_TYPE=Debug"
- CMAKE_GPU_OPTIONS: "-DGMX_GPU=OFF"
+ CMAKE_GPU_OPTIONS: "-DGMX_GPU=None"
CMAKE_GMXAPI_OPTIONS: "-DGMX_PYTHON_PACKAGE=OFF"
COMPILER_MAJOR_VERSION: 9
BUILD_DIR: simple-build
CMAKE_MPI_OPTIONS: "-DGMX_THREAD_MPI=ON"
CMAKE_PRECISION_OPTIONS: "-DGMX_DOUBLE=OFF"
CMAKE_BUILD_TYPE_OPTIONS: "-DCMAKE_BUILD_TYPE=Debug"
- CMAKE_GPU_OPTIONS: "-DGMX_GPU=OFF"
+ CMAKE_GPU_OPTIONS: "-DGMX_GPU=None"
script:
- echo $CMAKE_COMPILER_SCRIPT
- echo $CMAKE_EXTRA_OPTIONS
CMAKE_MPI_OPTIONS: "-DGMX_THREAD_MPI=ON"
CMAKE_PRECISION_OPTIONS: "-DGMX_DOUBLE=OFF"
CMAKE_BUILD_TYPE_OPTIONS: "-DCMAKE_BUILD_TYPE=RelWithAssert"
- CMAKE_GPU_OPTIONS: "-DGMX_GPU=OFF"
+ CMAKE_GPU_OPTIONS: "-DGMX_GPU=None"
CMAKE_REGRESSIONTEST_OPTIONS: "-DREGRESSIONTEST_PATH=../\\$RELEASE_REGRESSIONTESTS"
RELEASE_BUILD_DIR: release-builds
RELEASE_SOURCE: release-source-from-tarball
+++ /dev/null
-#
-# This file is part of the GROMACS molecular simulation package.
-#
-# Copyright (c) 2012,2018, by the GROMACS development team, led by
-# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
-# and including many others, as listed in the AUTHORS file in the
-# top-level source directory and at http://www.gromacs.org.
-#
-# GROMACS is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public License
-# as published by the Free Software Foundation; either version 2.1
-# of the License, or (at your option) any later version.
-#
-# GROMACS is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with GROMACS; if not, see
-# http://www.gnu.org/licenses, or write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# If you want to redistribute modifications to GROMACS, please
-# consider that scientific software is very special. Version
-# control is crucial - bugs must be traceable. We will be happy to
-# consider code for inclusion in the official distribution, but
-# derived work must not be called official GROMACS. Details are found
-# in the README & COPYING files - if they are missing, get the
-# official version at http://www.gromacs.org.
-#
-# To help us fund GROMACS development, we humbly ask that you cite
-# the research papers on the package. Check out http://www.gromacs.org.
-
-# The gmx_detect_gpu() macro aims to detect GPUs available in the build machine
-# and provide the number, names, and compute-capabilities of these devices.
-#
-# The current version is limited to checking the availability of NVIDIA GPUs
-# without compute-capability information.
-#
-# The current detection relies on the following checks in the order of listing:
-# - output of nvidia-smi (if available);
-# - presence and content of of /proc/driver/nvidia/gpus/*/information (Linux)
-# - output of lspci (Linux)
-#
-# If any of the checks succeeds in finding devices, consecutive checks will not
-# be carried out. Additionally, when lspci is used and a device with unknown
-# PCI ID is encountered, lspci tries to check the online PCI ID database. If
-# this is not possible or the device is simply not recognized, no device names
-# will be available.
-#
-# The following advanced variables are defined:
-# - GMX_DETECT_GPU_AVAILABLE - TRUE if any GPUs were detected, otherwise FALSE
-# - GMX_DETECT_GPU_COUNT - # of GPUs detected
-# - GMX_DETECT_GPU_INFO - list of information strings of the detected GPUs
-#
-# NOTE: The proper solution is to detect hardware compatible with the native
-# GPU acceleration. However, this requires checking the compute capability
-# of the device which is not possible with the current checks and requires
-# interfacing with the CUDA driver API.
-#
-
-# check whether the number of GPUs machetes the number of elements in the GPU info list
-macro(check_num_gpu_info NGPU GPU_INFO)
- list(LENGTH ${GPU_INFO} _len)
- if (NOT NGPU EQUAL _len)
- list(APPEND ${GMX_DETECT_GPU_INFO} "NOTE: information about some GPU(s) missing!")
- endif()
-endmacro()
-
-macro(gmx_detect_gpu)
-
- if (NOT DEFINED GMX_DETECT_GPU_AVAILABLE OR
- NOT DEFINED GMX_DETECT_GPU_COUNT OR
- NOT DEFINED GMX_DETECT_GPU_INFO)
-
- set(GMX_DETECT_GPU_COUNT 0)
- set(GMX_DETECT_GPU_INFO "")
-
- message(STATUS "Looking for NVIDIA GPUs present in the system")
-
- # nvidia-smi-based detection.
- # Requires the nvidia-smi tool to be installed and available in the path
- # or in one of the default search locations
- if (NOT DEFINED GMX_DETECT_GPU_COUNT_NVIDIA_SMI)
- # try to find the nvidia-smi binary
- # TODO add location hints
- find_program(_nvidia_smi "nvidia-smi")
- if (_nvidia_smi)
- set(GMX_DETECT_GPU_COUNT_NVIDIA_SMI 0)
- # execute nvidia-smi -L to get a short list of GPUs available
- exec_program(${_nvidia_smi_path} ARGS -L
- OUTPUT_VARIABLE _nvidia_smi_out
- RETURN_VALUE _nvidia_smi_ret)
- # process the stdout of nvidia-smi
- if (_nvidia_smi_ret EQUAL 0)
- # convert string with newlines to list of strings
- string(REGEX REPLACE "\n" ";" _nvidia_smi_out "${_nvidia_smi_out}")
- foreach(_line ${_nvidia_smi_out})
- if (_line MATCHES "^GPU [0-9]+:")
- math(EXPR GMX_DETECT_GPU_COUNT_NVIDIA_SMI "${GMX_DETECT_GPU_COUNT_NVIDIA_SMI}+1")
- # the UUID is not very useful for the user, remove it
- string(REGEX REPLACE " \\(UUID:.*\\)" "" _gpu_info "${_line}")
- if (NOT _gpu_info STREQUAL "")
- list(APPEND GMX_DETECT_GPU_INFO "${_gpu_info}")
- endif()
- endif()
- endforeach()
-
- check_num_gpu_info(${GMX_DETECT_GPU_COUNT_NVIDIA_SMI} GMX_DETECT_GPU_INFO)
- set(GMX_DETECT_GPU_COUNT ${GMX_DETECT_GPU_COUNT_NVIDIA_SMI})
- endif()
- endif()
-
- unset(_nvidia_smi CACHE)
- unset(_nvidia_smi_ret)
- unset(_nvidia_smi_out)
- unset(_gpu_name)
- unset(_line)
- endif()
-
- if (UNIX AND NOT (APPLE OR CYGWIN))
- # /proc/driver/nvidia/gpus/*/information-based detection.
- # Requires the NVDIA closed source driver to be installed and loaded
- if (NOT DEFINED GMX_DETECT_GPU_COUNT_PROC AND GMX_DETECT_GPU_COUNT EQUAL 0)
- set(GMX_DETECT_GPU_COUNT_PROC 0)
- file(GLOB _proc_nv_gpu_info "/proc/driver/nvidia/gpus/*/information")
- foreach (_file ${_proc_nv_gpu_info})
- math(EXPR GMX_DETECT_GPU_COUNT_PROC "${GMX_DETECT_GPU_COUNT_PROC}+1")
- # assemble information strings similar to the nvidia-smi output
- # GPU ID = directory name on /proc/driver/nvidia/gpus/
- string(REGEX REPLACE "/proc/driver/nvidia/gpus.*([0-9]+).*information" "\\1" _gpu_id ${_file})
- # GPU name
- file(STRINGS ${_file} _gpu_name LIMIT_COUNT 1 REGEX "^Model:.*" NO_HEX_CONVERSION)
- string(REGEX REPLACE "^Model:[ \t]*(.*)" "\\1" _gpu_name "${_gpu_name}")
- if (NOT _gpu_id STREQUAL "" AND NOT _gpu_name STREQUAL "")
- list(APPEND GMX_DETECT_GPU_INFO "GPU ${_gpu_id}: ${_gpu_name}")
- endif()
- endforeach()
-
- check_num_gpu_info(${GMX_DETECT_GPU_COUNT_PROC} GMX_DETECT_GPU_INFO)
- set(GMX_DETECT_GPU_COUNT ${GMX_DETECT_GPU_COUNT_PROC})
-
- unset(_proc_nv_gpu_info)
- unset(_gpu_name)
- unset(_gpu_id)
- unset(_file)
- endif()
-
- # lspci-based detection (does not provide GPU information).
- # Requires lspci and for GPU names to be fetched from the central
- # PCI ID db if not available locally.
- if (NOT DEFINED GMX_DETECT_GPU_COUNT_LSPCI AND GMX_DETECT_GPU_COUNT EQUAL 0)
- set(GMX_DETECT_GPU_COUNT_LSPCI 0)
- exec_program(lspci ARGS -q
- OUTPUT_VARIABLE _lspci_out
- RETURN_VALUE _lspci_ret)
- # prehaps -q is not supported, try running without
- if (NOT RETURN_VALUE EQUAL 0)
- exec_program(lspci
- OUTPUT_VARIABLE _lspci_out
- RETURN_VALUE _lspci_ret)
- endif()
- if (_lspci_ret EQUAL 0)
- # convert string with newlines to list of strings
- STRING(REGEX REPLACE ";" "\\\\;" _lspci_out "${_lspci_out}")
- string(REGEX REPLACE "\n" ";" _lspci_out "${_lspci_out}")
- foreach(_line ${_lspci_out})
- string(TOUPPER "${_line}" _line_upper)
- if (_line_upper MATCHES ".*VGA.*NVIDIA.*" OR _line_upper MATCHES ".*3D.*NVIDIA.*")
- math(EXPR GMX_DETECT_GPU_COUNT_LSPCI "${GMX_DETECT_GPU_COUNT_LSPCI}+1")
- # Try to parse out the device name which should be
- # included in the lspci -q output between []-s
- string(REGEX REPLACE ".*\\[(.*)\\].*" "\\1" _gpu_name "${_line}")
- if (NOT _gpu_name EQUAL "")
- list(APPEND GMX_DETECT_GPU_INFO "${_gpu_name}")
- endif()
- endif()
- endforeach()
-
- check_num_gpu_info(${GMX_DETECT_GPU_COUNT_LSPCI} GMX_DETECT_GPU_INFO)
- set(GMX_DETECT_GPU_COUNT ${GMX_DETECT_GPU_COUNT_LSPCI})
- endif()
-
- unset(_lspci_ret)
- unset(_lspci_out)
- unset(_gpu_name)
- unset(_line)
- unset(_line_upper)
- endif()
- endif()
-
- if (GMX_DETECT_GPU_COUNT GREATER 0)
- set(GMX_DETECT_GPU_AVAILABLE YES)
- else()
- set(GMX_DETECT_GPU_AVAILABLE NO)
- endif()
- set(GMX_DETECT_GPU_AVAILABLE ${GMX_DETECT_GPU_AVAILABLE} CACHE BOOL "Whether any NVIDIA GPU was detected" FORCE)
-
- set(GMX_DETECT_GPU_COUNT ${GMX_DETECT_GPU_COUNT}
- CACHE STRING "Number of NVIDIA GPUs detected")
- set(GMX_DETECT_GPU_INFO ${GMX_DETECT_GPU_INFO}
- CACHE STRING "basic information on the detected NVIDIA GPUs")
-
- set(GMX_DETECT_GPU_COUNT_NVIDIA_SMI ${GMX_DETECT_GPU_COUNT_NVIDIA_SMI}
- CACHE INTERNAL "Number of NVIDIA GPUs detected using nvidia-smi")
- set(GMX_DETECT_GPU_COUNT_PROC ${GMX_DETECT_GPU_COUNT_PROC}
- CACHE INTERNAL "Number of NVIDIA GPUs detected in /proc/driver/nvidia/gpus")
- set(GMX_DETECT_GPU_COUNT_LSPCI ${GMX_DETECT_GPU_COUNT_LSPCI}
- CACHE INTERNAL "Number of NVIDIA GPUs detected using lspci")
-
- mark_as_advanced(GMX_DETECT_GPU_AVAILABLE
- GMX_DETECT_GPU_COUNT
- GMX_DETECT_GPU_INFO)
-
- if (GMX_DETECT_GPU_AVAILABLE)
- message(STATUS "Number of NVIDIA GPUs detected: ${GMX_DETECT_GPU_COUNT} ")
- else()
- message(STATUS "Could not detect NVIDIA GPUs")
- endif()
-
- endif()
-endmacro(gmx_detect_gpu)
--- /dev/null
+#
+# This file is part of the GROMACS molecular simulation package.
+#
+# Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
+# Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+# and including many others, as listed in the AUTHORS file in the
+# top-level source directory and at http://www.gromacs.org.
+#
+# GROMACS is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation; either version 2.1
+# of the License, or (at your option) any later version.
+#
+# GROMACS is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with GROMACS; if not, see
+# http://www.gnu.org/licenses, or write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# If you want to redistribute modifications to GROMACS, please
+# consider that scientific software is very special. Version
+# control is crucial - bugs must be traceable. We will be happy to
+# consider code for inclusion in the official distribution, but
+# derived work must not be called official GROMACS. Details are found
+# in the README & COPYING files - if they are missing, get the
+# official version at http://www.gromacs.org.
+#
+# To help us fund GROMACS development, we humbly ask that you cite
+# the research papers on the package. Check out http://www.gromacs.org.
+
+
+# The earliest version of the CUDA toolkit that supports c++14 is 9.0
+set(REQUIRED_CUDA_VERSION 9.0)
+set(REQUIRED_CUDA_COMPUTE_CAPABILITY 3.0)
+
+set(GMX_USE_CUDA ON)
+
+option(GMX_CLANG_CUDA "Use clang for CUDA" OFF)
+
+if(GMX_DOUBLE)
+ message(FATAL_ERROR "CUDA acceleration is not available in double precision")
+endif()
+
+find_package(CUDA ${REQUIRED_CUDA_VERSION} REQUIRED)
+
+# Try to execute ${CUDA_NVCC_EXECUTABLE} --version and set the output
+# (or an error string) in the argument variable.
+# Note that semicolon is used as separator for nvcc.
+#
+# Parameters:
+# COMPILER_INFO - [output variable] string with compiler path, ID and
+# some compiler-provided information
+# DEVICE_COMPILER_FLAGS - [output variable] device flags for the compiler
+# HOST_COMPILER_FLAGS - [output variable] host flags for the compiler, if propagated
+#
+macro(get_cuda_compiler_info COMPILER_INFO DEVICE_COMPILER_FLAGS HOST_COMPILER_FLAGS)
+ if(NOT GMX_CLANG_CUDA)
+ if(CUDA_NVCC_EXECUTABLE)
+
+ # Get the nvcc version string. This is multi-line, but since it is only 4 lines
+ # and might change in the future it is better to store than trying to parse out
+ # the version from the current format.
+ execute_process(COMMAND ${CUDA_NVCC_EXECUTABLE} --version
+ RESULT_VARIABLE _nvcc_version_res
+ OUTPUT_VARIABLE _nvcc_version_out
+ ERROR_VARIABLE _nvcc_version_err
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (${_nvcc_version_res} EQUAL 0)
+ # Fix multi-line mess: Replace newline with ";" so we can use it in a define
+ string(REPLACE "\n" ";" _nvcc_info_singleline ${_nvcc_version_out})
+ SET(${COMPILER_INFO} "${CUDA_NVCC_EXECUTABLE} ${_nvcc_info_singleline}")
+ string(TOUPPER ${CMAKE_BUILD_TYPE} _build_type)
+ SET(_compiler_flags "${CUDA_NVCC_FLAGS_${_build_type}}")
+ if(CUDA_PROPAGATE_HOST_FLAGS)
+ set(${HOST_COMPILER_FLAGS} BUILD_CXXFLAGS)
+ else()
+ set(${HOST_COMPILER_FLAGS} "")
+ endif()
+ SET(${DEVICE_COMPILER_FLAGS} "${CUDA_NVCC_FLAGS}${CUDA_NVCC_FLAGS_${_build_type}}")
+ else()
+ SET(${COMPILER_INFO} "N/A")
+ SET(${COMPILER_FLAGS} "N/A")
+ endif()
+ endif()
+ else()
+ # CXX compiler is the CUDA compiler
+ set(${COMPILER_INFO} "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
+ # there are some extra flags
+ set(${COMPILER_FLAGS} "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${_build_type}} ${GMX_CUDA_CLANG_FLAGS}")
+ endif()
+endmacro ()
+
+if(GMX_CLANG_CUDA)
+ include(gmxManageClangCudaConfig)
+ list(APPEND GMX_EXTRA_LIBRARIES ${GMX_CUDA_CLANG_LINK_LIBS})
+ link_directories("${GMX_CUDA_CLANG_LINK_DIRS}")
+else()
+ # Using NVIDIA compiler
+ if(NOT CUDA_NVCC_EXECUTABLE)
+ message(FATAL_ERROR "nvcc is required for a CUDA build, please set CUDA_TOOLKIT_ROOT_DIR appropriately")
+ endif()
+ # set up nvcc options
+ include(gmxManageNvccConfig)
+endif()
+
+option(GMX_CUDA_NB_SINGLE_COMPILATION_UNIT "Whether to compile the CUDA non-bonded module using a single compilation unit." OFF)
+mark_as_advanced(GMX_CUDA_NB_SINGLE_COMPILATION_UNIT)
+++ /dev/null
-#
-# This file is part of the GROMACS molecular simulation package.
-#
-# Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
-# Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
-# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
-# and including many others, as listed in the AUTHORS file in the
-# top-level source directory and at http://www.gromacs.org.
-#
-# GROMACS is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public License
-# as published by the Free Software Foundation; either version 2.1
-# of the License, or (at your option) any later version.
-#
-# GROMACS is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with GROMACS; if not, see
-# http://www.gnu.org/licenses, or write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# If you want to redistribute modifications to GROMACS, please
-# consider that scientific software is very special. Version
-# control is crucial - bugs must be traceable. We will be happy to
-# consider code for inclusion in the official distribution, but
-# derived work must not be called official GROMACS. Details are found
-# in the README & COPYING files - if they are missing, get the
-# official version at http://www.gromacs.org.
-#
-# To help us fund GROMACS development, we humbly ask that you cite
-# the research papers on the package. Check out http://www.gromacs.org.
-
-# If the user did not set GMX_GPU we'll consider this option to be
-# in "auto" mode meaning that we will:
-# - search for CUDA and set GMX_GPU=ON we find it
-# - check whether GPUs are present
-# - if CUDA is not found but GPUs were detected issue a warning
-if (NOT DEFINED GMX_GPU)
- set(GMX_GPU_AUTO TRUE CACHE INTERNAL "GPU acceleration will be selected automatically")
-else()
- set(GMX_GPU_AUTO FALSE CACHE INTERNAL "GPU acceleration will be selected automatically")
-endif()
-option(GMX_GPU "Enable GPU acceleration" OFF)
-
-option(GMX_CLANG_CUDA "Use clang for CUDA" OFF)
-
-if(GMX_GPU AND GMX_DOUBLE)
- message(FATAL_ERROR "GPU acceleration is not available in double precision!")
-endif()
-if(GMX_GPU_AUTO AND GMX_DOUBLE)
- message(WARNING "GPU acceleration is not available in double precision, disabled!")
- set_property(CACHE GMX_GPU PROPERTY VALUE OFF)
- set_property(CACHE GMX_GPU_AUTO PROPERTY VALUE OFF)
-endif()
-
-# detect GPUs in the build host machine
-if ((GMX_GPU OR GMX_GPU_AUTO) AND NOT GMX_GPU_DETECTION_DONE)
- include(gmxDetectGpu)
- gmx_detect_gpu()
-endif()
-
-# We need to call find_package even when we've already done the detection/setup
-if(GMX_GPU OR GMX_GPU_AUTO)
- if(NOT GMX_GPU AND NOT GMX_DETECT_GPU_AVAILABLE)
- # Stay quiet when detection has occured and found no GPU.
- # Noise is acceptable when there is a GPU or the user required one.
- set(FIND_CUDA_QUIETLY QUIET)
- endif()
-
- # Cmake tries to use the static cuda runtime by default,
- # but this leads to unusable GPU builds on OS X.
- if(APPLE)
- set(CUDA_USE_STATIC_CUDA_RUNTIME OFF CACHE STRING "Use the static version of the CUDA runtime library if available")
- endif()
-
- find_package(CUDA ${REQUIRED_CUDA_VERSION} ${FIND_CUDA_QUIETLY})
-endif()
-
-# Depending on the current vale of GMX_GPU and GMX_GPU_AUTO:
-# - OFF, FALSE: Will skip this detection/setup.
-# - OFF, TRUE : Will keep GMX_GPU=OFF if no CUDA is detected, but will assemble
-# a warning message which will be issued at the end of the
-# configuration if GPU(s) were found in the build system.
-# - ON , FALSE: The user requested GPU build and this requires CUDA, so we will
-# fail if it is not available.
-# - ON , TRUE : Can't happen (GMX_GPU=ON can only be user-set at this point)
-if((GMX_GPU OR GMX_GPU_AUTO) AND NOT GMX_GPU_DETECTION_DONE)
- # assemble warning/error message
- if (GMX_DETECT_GPU_AVAILABLE)
- set(_msg "${GMX_DETECT_GPU_COUNT} NVIDIA GPU(s) found in the system")
-
- # append GPU names
- if (NOT GMX_DETECT_GPU_INFO STREQUAL "")
- set(_msg "${_msg}:")
- foreach(gpu ${GMX_DETECT_GPU_INFO})
- set(_msg "${_msg}
-${gpu}")
- endforeach()
- endif()
-
- # TODO remove the second part of the message when we'll have compute
- # capability information from the detection.
- set(_msg "${_msg}
-Compute capability information not available, consult the NVIDIA website:
-https://developer.nvidia.com/cuda-gpus")
- endif()
-
- set(CUDA_NOTFOUND_MESSAGE "mdrun supports native GPU acceleration on NVIDIA hardware with compute capability >= ${REQUIRED_CUDA_COMPUTE_CAPABILITY} (Kepler or later). This requires the NVIDIA CUDA toolkit, which was not found. Its location can be hinted by setting the CUDA_TOOLKIT_ROOT_DIR CMake option (does not work as an environment variable). The typical location would be /usr/local/cuda[-version]. Note that CPU or GPU acceleration can be selected at runtime.
-
-${_msg}")
- unset(_msg)
-
- if (NOT CUDA_FOUND)
- if (GMX_GPU_AUTO)
- # Disable GPU acceleration in auto mode
- message(STATUS "No compatible CUDA toolkit found (v5.0+), disabling native GPU acceleration")
- set_property(CACHE GMX_GPU PROPERTY VALUE OFF)
- set(CUDA_NOTFOUND_AUTO ON)
- else()
- # the user requested CUDA, but it wasn't found
- message(FATAL_ERROR "${CUDA_NOTFOUND_MESSAGE}")
- endif()
- else()
- if (GMX_GPU_AUTO)
- message(STATUS "Enabling native GPU acceleration")
- set_property(CACHE GMX_GPU PROPERTY VALUE ON)
- endif()
- endif()
-endif()
-
-# Annoyingly enough, FindCUDA leaves a few variables behind as non-advanced.
-# We need to mark these advanced outside the conditional, otherwise, if the
-# user turns GMX_GPU=OFF after a failed cmake pass, these variables will be
-# left behind in the cache.
-mark_as_advanced(CUDA_SDK_ROOT_DIR
- CUDA_USE_STATIC_CUDA_RUNTIME
- CUDA_dl_LIBRARY CUDA_rt_LIBRARY
- )
-if(NOT GMX_GPU)
- mark_as_advanced(CUDA_TOOLKIT_ROOT_DIR)
- mark_as_advanced(CUDA_HOST_COMPILER)
-endif()
-
-# Try to execute ${CUDA_NVCC_EXECUTABLE} --version and set the output
-# (or an error string) in the argument variable.
-# Note that semicolon is used as separator for nvcc.
-#
-# Parameters:
-# COMPILER_INFO - [output variable] string with compiler path, ID and
-# some compiler-provided information
-# DEVICE_COMPILER_FLAGS - [output variable] device flags for the compiler
-# HOST_COMPILER_FLAGS - [output variable] host flags for the compiler, if propagated
-#
-macro(get_cuda_compiler_info COMPILER_INFO DEVICE_COMPILER_FLAGS HOST_COMPILER_FLAGS)
- if(NOT GMX_CLANG_CUDA)
- if(CUDA_NVCC_EXECUTABLE)
-
- # Get the nvcc version string. This is multi-line, but since it is only 4 lines
- # and might change in the future it is better to store than trying to parse out
- # the version from the current format.
- execute_process(COMMAND ${CUDA_NVCC_EXECUTABLE} --version
- RESULT_VARIABLE _nvcc_version_res
- OUTPUT_VARIABLE _nvcc_version_out
- ERROR_VARIABLE _nvcc_version_err
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (${_nvcc_version_res} EQUAL 0)
- # Fix multi-line mess: Replace newline with ";" so we can use it in a define
- string(REPLACE "\n" ";" _nvcc_info_singleline ${_nvcc_version_out})
- SET(${COMPILER_INFO} "${CUDA_NVCC_EXECUTABLE} ${_nvcc_info_singleline}")
- string(TOUPPER ${CMAKE_BUILD_TYPE} _build_type)
- SET(_compiler_flags "${CUDA_NVCC_FLAGS_${_build_type}}")
- if(CUDA_PROPAGATE_HOST_FLAGS)
- set(${HOST_COMPILER_FLAGS} BUILD_CXXFLAGS)
- else()
- set(${HOST_COMPILER_FLAGS} "")
- endif()
- SET(${DEVICE_COMPILER_FLAGS} "${CUDA_NVCC_FLAGS}${CUDA_NVCC_FLAGS_${_build_type}}")
- else()
- SET(${COMPILER_INFO} "N/A")
- SET(${COMPILER_FLAGS} "N/A")
- endif()
- endif()
- else()
- # CXX compiler is the CUDA compiler
- set(${COMPILER_INFO} "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
- # there are some extra flags
- set(${COMPILER_FLAGS} "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${_build_type}} ${GMX_CUDA_CLANG_FLAGS}")
- endif()
-endmacro ()
-
-macro(enable_multiple_cuda_compilation_units)
- message(STATUS "Enabling multiple compilation units for the CUDA non-bonded module.")
- set_property(CACHE GMX_CUDA_NB_SINGLE_COMPILATION_UNIT PROPERTY VALUE OFF)
-endmacro()
-
-include(CMakeDependentOption)
-include(gmxOptionUtilities)
-macro(gmx_gpu_setup)
- if(GMX_GPU)
- if(NOT GMX_CLANG_CUDA)
- if(NOT CUDA_NVCC_EXECUTABLE)
- message(FATAL_ERROR "nvcc is required for a CUDA build, please set CUDA_TOOLKIT_ROOT_DIR appropriately")
- endif()
- # set up nvcc options
- include(gmxManageNvccConfig)
- else()
- include(gmxManageClangCudaConfig)
- endif()
-
- # no OpenMP is no good!
- if(NOT GMX_OPENMP)
- message(WARNING "To use GPU acceleration efficiently, mdrun requires OpenMP multi-threading. Without OpenMP a single CPU core can be used with a GPU which is not optimal. Note that with MPI multiple processes can be forced to use a single GPU, but this is typically inefficient. You need to set both C and C++ compilers that support OpenMP (CC and CXX environment variables, respectively) when using GPUs.")
- endif()
- endif() # GMX_GPU
-
- option(GMX_CUDA_NB_SINGLE_COMPILATION_UNIT "Whether to compile the CUDA non-bonded module using a single compilation unit." OFF)
- mark_as_advanced(GMX_CUDA_NB_SINGLE_COMPILATION_UNIT)
-
-endmacro()
# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
+# OpenCL required version: 1.2 or newer
+set(REQUIRED_OPENCL_MIN_VERSION_MAJOR 1)
+set(REQUIRED_OPENCL_MIN_VERSION_MINOR 2)
+set(REQUIRED_OPENCL_MIN_VERSION ${REQUIRED_OPENCL_MIN_VERSION_MAJOR}.${REQUIRED_OPENCL_MIN_VERSION_MINOR})
+
+set(GMX_USE_OPENCL ON)
+
if(GMX_DOUBLE)
- message(FATAL_ERROR "OpenCL not available in double precision - Yet!")
+ message(FATAL_ERROR "OpenCL acceleration is not available in double precision")
endif()
# for some reason FindOpenCL checks CUDA_PATH but not CUDA_HOME
set(GMX_OPENCL_NB_CLUSTER_SIZE 8 CACHE STRING "Cluster size used by nonbonded OpenCL kernel. Set to 4 for Intel GPUs.")
mark_as_advanced(GMX_OPENCL_NB_CLUSTER_SIZE)
-macro(gmx_gpu_setup)
- # no OpenMP is no good!
- if(NOT GMX_OPENMP)
- message(WARNING "To use GPU acceleration efficiently, mdrun requires OpenMP multi-threading. Without OpenMP a single CPU core can be used with a GPU which is not optimal. Note that with MPI multiple processes can be forced to use a single GPU, but this is typically inefficient. You need to set both C and C++ compilers that support OpenMP (CC and CXX environment variables, respectively) when using GPUs.")
- endif()
-endmacro()
+set(GMX_INSTALL_OCLDIR ${GMX_INSTALL_GMXDATADIR}/opencl)
* ``-DCMAKE_C_COMPILER=xxx`` equal to the name of the C99 `Compiler`_ you wish to use (or the environment variable ``CC``)
* ``-DCMAKE_CXX_COMPILER=xxx`` equal to the name of the C++98 `compiler`_ you wish to use (or the environment variable ``CXX``)
* ``-DGMX_MPI=on`` to build using `MPI support`_ (generally good to combine with `building only mdrun`_)
-* ``-DGMX_GPU=on`` to build using nvcc to run using NVIDIA `CUDA GPU acceleration`_ or an OpenCL_ GPU
-* ``-DGMX_USE_OPENCL=on`` to build with OpenCL_ support enabled. ``GMX_GPU`` must also be set.
+* ``-DGMX_GPU=CUDA`` to build with NVIDIA CUDA support enabled.
+* ``-DGMX_GPU=OpenCL`` to build with OpenCL_ support enabled.
* ``-DGMX_SIMD=xxx`` to specify the level of `SIMD support`_ of the node on which |Gromacs| will run
* ``-DGMX_BUILD_MDRUN_ONLY=on`` for `building only mdrun`_, e.g. for compute cluster back-end nodes
* ``-DGMX_DOUBLE=on`` to build |Gromacs| in double precision (slower, and not normally useful)
::
- cmake .. -DGMX_GPU=ON -DGMX_MPI=ON -DCMAKE_INSTALL_PREFIX=/home/marydoe/programs
+ cmake .. -DGMX_GPU=CUDA -DGMX_MPI=ON -DCMAKE_INSTALL_PREFIX=/home/marydoe/programs
can be used to build with CUDA GPUs, MPI and install in a custom
location. You can even save that in a shell script to make it even
::
- cmake .. -DGMX_GPU=ON -DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda
+ cmake .. -DGMX_GPU=CUDA -DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda
(or whichever path has your installation). In some cases, you might
need to specify manually which of your C++ compilers should be used,
::
- cmake .. -DGMX_GPU=ON -DGMX_USE_OPENCL=ON
+ cmake .. -DGMX_GPU=OpenCL
To build with support for Intel integrated GPUs, it is required
to add ``-DGMX_OPENCL_NB_CLUSTER_SIZE=4`` to the cmake command line,
::
- cmake .. -DGMX_GPU=ON -DGMX_USE_OPENCL=ON -DclFFT_ROOT_DIR=/path/to/your/clFFT -DGMX_EXTERNAL_CLFFT=TRUE
+ cmake .. -DGMX_GPU=OpenCL -DclFFT_ROOT_DIR=/path/to/your/clFFT -DGMX_EXTERNAL_CLFFT=TRUE
Static linking
~~~~~~~~~~~~~~
cd ..
mkdir build-mdrun-only
cd build-mdrun-only
- cmake .. -DGMX_MPI=ON -DGMX_GPU=ON -DGMX_BUILD_MDRUN_ONLY=ON -DCMAKE_INSTALL_PREFIX=/your/installation/prefix/here
+ cmake .. -DGMX_MPI=ON -DGMX_GPU=CUDA -DGMX_BUILD_MDRUN_ONLY=ON -DCMAKE_INSTALL_PREFIX=/your/installation/prefix/here
make -j 4
make install
cd /to/your/unpacked/regressiontests
Also, please use the syntax :issue:`number` to reference issues on GitLab, without the
a space between the colon and number!
+Uniform and manual CMake GPU-support configuration
+""""""""""""""""""""""""""""""""""""""""""""""""""
+The GPU accelerations setup has been changed to be uniform for CUDA and OpenCL. Either
+option is now enabled by setting GMX_GPU to CUDA or OpenCL in the CMake configuration.
+To simplify the CMake code, we have also moved away from automated option selection
+based on the build host. In particular, this means that CUDA will not be enabled unless
+the GMX_GPU option is explicitly enabled, and CMake will no longer perform the extra
+steps of trying to detect hardware and propose to install CUDA if hardware is available.
+Apart from the simplification, this should also make it easier to handle multiple
+different accelerator APIs targeting e.g. NVIDIA hardware.
+
Configuration-time trivalue options changed from autodetection to boolean on/off
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
To simplify the CMake configuration and avoid having multiple settings that
change outside of the users direct control we have removed the support for
automatically setting booleans. GMX_BUILD_HELP and GMX_HWLOC are now
disabled by default, while GMX_LOAD_PLUGINS is enabled by default.
+
* Make sure your compiler supports OpenMP (some versions of Clang don't).
* If you have GPUs that support either CUDA or OpenCL, use them.
- * Configure with ``-DGMX_GPU=ON`` (add ``-DGMX_USE_OPENCL=ON`` for OpenCL).
+ * Configure with ``-DGMX_GPU=CUDA `` or ``-DGMX_GPU=OpenCL``.
* For CUDA, use the newest CUDA available for your GPU to take advantage of the
latest performance enhancements.
* Use a recent GPU driver.