set(REQUIRED_OPENCL_MIN_VERSION 1.1)
if(NOT GMX_USE_OPENCL)
- # CUDA detection is done only if GMX_USE_OPENCL is OFF
+ # 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
+ #Now the OpenCL path (for both AMD and NVIDIA)
if(GMX_GPU)
include(gmxManageOpenCL)
- else(GMX_GPU)
+ 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(GMX_GPU)
+ endif()
endif()
include(gmxDetectSimd)
option(GMX_LOAD_PLUGINS "Compile with plugin support, needed to read VMD supported file formats" ON)
mark_as_advanced(GMX_LOAD_PLUGINS)
-option(GMX_GPU "Enable GPU acceleration" ON)
option(GMX_OPENMP "Enable OpenMP-based multithreading" ON)
option(GMX_USE_TNG "Use the TNG library for trajectory I/O" ON)
if (GMX_COMPILER_WARNINGS)
GMX_TEST_CFLAG(CFLAGS_WARN "-Wall -Wno-unused -Wunused-value -Wunused-parameter" GMXC_CFLAGS)
GMX_TEST_CFLAG(CFLAGS_WARN_EXTRA "-Wextra -Wno-missing-field-initializers -Wno-sign-compare -Wpointer-arith" GMXC_CFLAGS)
- if(NOT GMX_GPU) #TODO: Fix that CUDA code has warnings
+ if(NOT GMX_USE_CUDA) #TODO: Fix that CUDA code has warnings
GMX_TEST_CFLAG(CFLAGS_WARN_UNDEF "-Wundef" GMXC_CFLAGS)
endif()
# Since 4.8 on by default. For previous version disabling is a no-op. Only disabling for Release because with assert
# Problematic with CUDA
# GMX_TEST_CXXFLAG(CXXFLAGS_WARN_EFFCXX "-Wnon-virtual-dtor" GMXC_CXXFLAGS)
GMX_TEST_CXXFLAG(CXXFLAGS_WARN_EXTRA "-Wextra -Wno-missing-field-initializers -Wpointer-arith" GMXC_CXXFLAGS)
- if(NOT GMX_GPU)
+ if(NOT GMX_USE_CUDA)
GMX_TEST_CXXFLAG(CXXFLAGS_WARN_UNDEF "-Wundef" GMXC_CXXFLAGS)
endif()
GMX_TEST_CFLAG(CXXFLAGS_WARN_REL "-Wno-array-bounds" GMXC_CXXFLAGS_RELEASE_ONLY)
include(GetCompilerInfo.cmake)
get_compiler_info(C BUILD_C_COMPILER BUILD_CFLAGS)
get_compiler_info(CXX BUILD_CXX_COMPILER BUILD_CXXFLAGS)
-if(GMX_GPU AND NOT GMX_USE_OPENCL)
+if(GMX_USE_CUDA)
GMX_SET_CUDA_NVCC_FLAGS()
get_cuda_compiler_info(CUDA_NVCC_COMPILER_INFO CUDA_NVCC_COMPILER_FLAGS)
endif()
/* Enable x86 gcc inline assembly */
#cmakedefine GMX_X86_GCC_INLINE_ASM
-/* Use GPU native acceleration */
-#cmakedefine GMX_GPU
+/* Define constants useful for handling GPU support */
+#define GMX_GPU_NONE 0
+#define GMX_GPU_CUDA 1
+#define GMX_GPU_OPENCL 2
+/* Which kind of GPU support is configured */
+#define GMX_GPU @GMX_GPU_ACCELERATION_FRAMEWORK@
/* CUDA runtime API version (identical to CUDART_VERSION from cuda_runtime_api.h) */
#cmakedefine GMX_CUDA_VERSION @GMX_CUDA_VERSION@
REMOTE_HASH SOURCE_FILE)
list(APPEND LIBGROMACS_SOURCES ${GENERATED_VERSION_FILE})
-if (GMX_GPU AND NOT GMX_USE_OPENCL)
+if (GMX_USE_CUDA)
cuda_add_library(libgromacs ${LIBGROMACS_SOURCES})
else()
add_library(libgromacs ${LIBGROMACS_SOURCES})
include(InstallLibInfo.cmake)
endif()
+# Technically, the user could want to do this for an OpenCL build
+# using the CUDA runtime, but currently there's no reason to want to
+# do that.
if (INSTALL_CUDART_LIB) #can be set manual by user
- if (GMX_GPU AND NOT GMX_USE_OPENCL)
+ if (GMX_USE_CUDA)
foreach(CUDA_LIB ${CUDA_LIBRARIES})
string(REGEX MATCH "cudart" IS_CUDART ${CUDA_LIB})
if(IS_CUDART) #libcuda should not be installed
endif()
endforeach()
else()
- message(WARNING "INSTALL_CUDART_LIB only makes sense with GMX_GPU")
+ message(WARNING "INSTALL_CUDART_LIB only makes sense when configuring for CUDA support")
endif()
endif()
-if(GMX_GPU AND GMX_USE_OPENCL)
+if(GMX_USE_OPENCL)
set(OPENCL_KERNELS ${MDLIB_OPENCL_KERNELS})
install(FILES ${OPENCL_KERNELS} DESTINATION
#else
fprintf(fp, "OpenMP support: disabled\n");
#endif
-#ifdef GMX_GPU
- fprintf(fp, "GPU support: enabled\n");
-#else
- fprintf(fp, "GPU support: disabled\n");
-#endif
-#if defined(GMX_GPU) && defined(GMX_USE_OPENCL)
- fprintf(fp, "OpenCL support: enabled\n");
-#else
- fprintf(fp, "OpenCL support: disabled\n");
-#endif
+ fprintf(fp, "GPU support: %s\n", getGpuImplementationString());
/* A preprocessor trick to avoid duplicating logic from vec.h */
#define gmx_stringify2(x) #x
#define gmx_stringify(x) gmx_stringify2(x)
fprintf(fp, "Linked with Intel MKL version %d.%d.%d.\n",
__INTEL_MKL__, __INTEL_MKL_MINOR__, __INTEL_MKL_UPDATE__);
#endif
-#if defined(GMX_GPU)
-#ifdef GMX_USE_OPENCL
+#if GMX_GPU == GMX_GPU_OPENCL
fprintf(fp, "OpenCL include dir: %s\n", OPENCL_INCLUDE_DIR);
fprintf(fp, "OpenCL library: %s\n", OPENCL_LIBRARY);
fprintf(fp, "OpenCL version: %s\n", OPENCL_VERSION_STRING);
-#else
- gmx_print_version_info_cuda_gpu(fp);
#endif
+#if GMX_GPU == GMX_GPU_CUDA
+ gmx_print_version_info_cuda_gpu(fp);
#endif
}
# conditionally built, so we cannot use a GLOB_RECURSE here.
file(GLOB GMXLIB_SOURCES *.cpp)
-# gpu utils + cuda tools module
-if(GMX_GPU)
- if(NOT GMX_USE_OPENCL)
- add_subdirectory(cuda_tools)
- else()
- add_subdirectory(ocl_tools)
- endif()
-endif()
+add_subdirectory(cuda_tools)
+add_subdirectory(ocl_tools)
add_subdirectory(gpu_utils)
set(GMXLIB_SOURCES ${GMXLIB_SOURCES} ${NONBONDED_SOURCES} PARENT_SCOPE)
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2012,2014, by the GROMACS development team, led by
+# Copyright (c) 2012,2014,2015, 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.
# 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(GMX_GPU)
+if(GMX_USE_CUDA)
file(GLOB CUDA_TOOLS_SOURCES *.cu)
set(GMXLIB_SOURCES ${GMXLIB_SOURCES} ${CUDA_TOOLS_SOURCES} PARENT_SCOPE)
endif()
#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/basenetwork.h"
+#include "gromacs/utility/baseversion.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/stringutil.h"
#include "gromacs/utility/sysinfo.h"
+static const bool bGPUBinary = GMX_GPU != GMX_GPU_NONE;
-#ifdef GMX_GPU
+/* Note that some of the following arrays must match the "GPU support
+ * enumeration" in src/config.h.cmakein, so that GMX_GPU looks up an
+ * array entry. */
-static const bool bGPUBinary = TRUE;
+/* CUDA supports everything. Our current OpenCL implementation only
+ * supports using exactly one GPU per PP rank, so sharing is
+ * impossible */
+static const bool gpuSharingSupport[] = { false, true, false };
+static const bool bGpuSharingSupported = gpuSharingSupport[GMX_GPU];
-# ifdef GMX_USE_OPENCL
-
-static const char *gpu_implementation = "OpenCL";
-/* Our current OpenCL implementation only supports using exactly one
- * GPU per PP rank, so sharing is impossible */
-static const bool bGpuSharingSupported = false;
-/* Our current OpenCL implementation seems to handle concurrency
- * correctly with thread-MPI. The AMD OpenCL runtime does not seem to
- * support creating a context from more than one real MPI rank on the
- * same node (it segfaults when you try).
+/* CUDA supports everything. Our current OpenCL implementation seems
+ * to handle concurrency correctly with thread-MPI. The AMD OpenCL
+ * runtime does not seem to support creating a context from more than
+ * one real MPI rank on the same node (it segfaults when you try).
*/
-# ifdef GMX_THREAD_MPI
-static const bool bMultiGpuPerNodeSupported = true;
-# else /* GMX_THREAD_MPI */
-/* Real MPI and no MPI */
-static const bool bMultiGpuPerNodeSupported = false;
-# endif
-
-# else /* GMX_USE_OPENCL */
-
-// Our CUDA implementation supports everything
-static const char *gpu_implementation = "CUDA";
-static const bool bGpuSharingSupported = true;
-static const bool bMultiGpuPerNodeSupported = true;
-
-# endif /* GMX_USE_OPENCL */
-
-#else /* GMX_GPU */
-
-// Not compiled with GPU support
-static const bool bGPUBinary = false;
-static const char *gpu_implementation = "non-GPU";
-static const bool bGpuSharingSupported = false;
-static const bool bMultiGpuPerNodeSupported = false;
-
-#endif /* GMX_GPU */
+static const bool multiGpuSupport[] = {
+ false, true,
+#ifdef GMX_THREAD_MPI
+ true,
+#else
+ false, /* Real MPI and no MPI */
+#endif
+};
+static const bool bMultiGpuPerNodeSupported = multiGpuSupport[GMX_GPU];
/* Names of the GPU detection/check results (see e_gpu_detect_res_t in hw_info.h). */
const char * const gpu_detect_res_str[egpuNR] =
!gmx_multiple_gpu_per_node_supported())
{
reasonForLimit = "can be used by ";
- reasonForLimit += gpu_implementation;
+ reasonForLimit += getGpuImplementationString();
reasonForLimit += " in GROMACS";
}
else
&gpu_opt->dev_use);
if (!gmx_multiple_gpu_per_node_supported() && 1 < gpu_opt->n_dev_use)
{
- gmx_fatal(FARGS, "The %s implementation only supports using exactly one PP rank per node", gpu_implementation);
+ gmx_fatal(FARGS, "The %s implementation only supports using exactly one PP rank per node", getGpuImplementationString());
}
if (!gmx_gpu_sharing_supported() && anyGpuIdIsRepeated(gpu_opt))
{
- gmx_fatal(FARGS, "The %s implementation only supports using exactly one PP rank per GPU", gpu_implementation);
+ gmx_fatal(FARGS, "The %s implementation only supports using exactly one PP rank per GPU", getGpuImplementationString());
}
if (gpu_opt->n_dev_use == 0)
{
# 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(GMX_GPU)
- if (GMX_USE_OPENCL)
- file(GLOB GPU_UTILS_SOURCES *ocl*.cpp)
- else()
- file(GLOB GPU_UTILS_SOURCES *.cu)
- endif()
-else()
- file(GLOB OCL_UTILS_SOURCES *ocl*.cpp)
- file(GLOB GPU_UTILS_SOURCES *.cpp)
- list(REMOVE_ITEM GPU_UTILS_SOURCES ${OCL_UTILS_SOURCES})
+file(GLOB GPU_UTILS_SOURCES gpu_utils.cpp)
+if(GMX_USE_OPENCL)
+ file(GLOB GPU_UTILS_SOURCES *ocl*.cpp)
endif()
+if(GMX_USE_CUDA)
+ file(GLOB GPU_UTILS_SOURCES *.cu)
+endif()
+
set(GMXLIB_SOURCES ${GMXLIB_SOURCES} ${GPU_UTILS_SOURCES} PARENT_SCOPE)
#define OPENCL_FUNC_TERM REAL_FUNC_TERM
#define OPENCL_FUNC_TERM_WITH_RETURN(arg) REAL_FUNC_TERM_WITH_RETURN(arg)
-#elif defined GMX_GPU
+#elif GMX_GPU != GMX_GPU_NONE
/* GPU support is enabled, so these functions will have real code
* defined somewhere */
#define GPU_FUNC_TERM REAL_FUNC_TERM
#define GPU_FUNC_TERM_WITH_RETURN(arg) REAL_FUNC_TERM_WITH_RETURN(arg)
-# if defined GMX_USE_OPENCL
+# if GMX_GPU == GMX_GPU_OPENCL
/* OpenCL support is enabled, so CUDA-specific functions need empty
* implementations, while OpenCL-specific functions will have real
#define OPENCL_FUNC_TERM REAL_FUNC_TERM
#define OPENCL_FUNC_TERM_WITH_RETURN(arg) REAL_FUNC_TERM_WITH_RETURN(arg)
-# else /* !(defined GMX_USE_OPENCL) */
+# endif
+# if GMX_GPU == GMX_GPU_CUDA
/* CUDA support is enabled, so OpenCL-specific functions need empty
* implementations, while CUDA-specific functions will have real
# endif
-#else /* !(defined DOXYGEN) && !(defined GMX_GPU) */
+#elif GMX_GPU == GMX_GPU_NONE
/* No GPU support is configured, so none of these functions will have
* real definitions. */
# 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(GMX_GPU AND GMX_USE_OPENCL)
+if(GMX_USE_OPENCL)
file(GLOB GMXLIB_OPENCL_SOURCES *.cpp)
set(GMXLIB_SOURCES ${GMXLIB_SOURCES} ${GMXLIB_OPENCL_SOURCES} PARENT_SCOPE)
endif()
file(GLOB MDLIB_SOURCES nbnxn_kernels/simd_4xn/*.cpp nbnxn_kernels/simd_2xnn/*.cpp nbnxn_kernels/*.cpp *.cpp)
-if(GMX_GPU AND NOT GMX_USE_OPENCL)
+if(GMX_USE_CUDA)
add_subdirectory(nbnxn_cuda)
-elseif(GMX_GPU AND GMX_USE_OPENCL)
+endif()
+if(GMX_USE_OPENCL)
add_subdirectory(nbnxn_ocl)
set(MDLIB_OPENCL_KERNELS ${MDLIB_OPENCL_KERNELS} PARENT_SCOPE)
endif()
# 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(GMX_GPU AND NOT GMX_USE_OPENCL)
+if(GMX_USE_CUDA)
file(GLOB CUDA_NB_SOURCES *.cu)
set(MDLIB_SOURCES ${MDLIB_SOURCES} ${CUDA_NB_SOURCES} PARENT_SCOPE)
endif()
extern "C" {
#endif
-#ifdef GMX_GPU
-
-# if defined GMX_USE_OPENCL
-
+#if GMX_GPU == GMX_GPU_OPENCL
struct gmx_nbnxn_ocl_t;
typedef struct gmx_nbnxn_ocl_t gmx_nbnxn_gpu_t;
+#endif
-# else
-
+#if GMX_GPU == GMX_GPU_CUDA
struct gmx_nbnxn_cuda_t;
typedef struct gmx_nbnxn_cuda_t gmx_nbnxn_gpu_t;
+#endif
-# endif
-
-#else
-
+#if GMX_GPU == GMX_GPU_NONE
typedef int gmx_nbnxn_gpu_t;
-
#endif
#ifdef __cplusplus
# 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(GMX_GPU AND GMX_USE_OPENCL)
+if(GMX_USE_OPENCL)
file(GLOB OPENCL_NB_SOURCES *.cpp)
set(MDLIB_SOURCES ${MDLIB_SOURCES} ${OPENCL_NB_SOURCES} PARENT_SCOPE)
file(GLOB MDLIB_OPENCL_KERNELS *.cl *.clh)
#include "nbnxn_gpu.h"
-#if defined(GMX_GPU)
-#if defined(GMX_USE_OPENCL)
-// Have OpenCL support
-static const bool useCuda = false;
-static const bool useOpenCL = true;
-#else
-// Have CUDA support
-static const bool useCuda = true;
-static const bool useOpenCL = false;
-#endif
-#else
-// No GPU support
-static const bool useCuda = false;
-static const bool useOpenCL = false;
-#endif
+static const bool useCuda = GMX_GPU == GMX_GPU_CUDA;
+static const bool useOpenCL = GMX_GPU == GMX_GPU_OPENCL;
void print_time(FILE *out,
gmx_walltime_accounting_t walltime_accounting,
#include "baseversion.h"
+#include "config.h"
+
#include "baseversion-gen.h"
const char *gmx_version()
{
}
#endif
+
+/* Note that this array (and some which follow) must match the "GPU
+ * support enumeration" in src/config.h.cmakein */
+static const char * const gpuImplementationStrings[] = { "disabled", "CUDA", "OpenCL" };
+
+const char *getGpuImplementationString()
+{
+ return gpuImplementationStrings[GMX_GPU];
+}
*/
const char *gmx_version_git_central_base_hash(void);
-extern "C" {
-
/*! \brief
* Defined if ``libgromacs`` has been compiled in double precision.
*
*
* \ingroup module_utility
*/
+
void gmx_is_single_precision();
-}
+/*! \brief Return a string describing what kind of GPU suport was configured in the build. */
+const char *getGpuImplementationString();
#endif
}
#ifdef GMX_MPI
-# ifdef GMX_GPU
+# if GMX_GPU != GMX_GPU_NONE
# ifdef GMX_THREAD_MPI
int numGpusNeeded = g_numThreads;
# else /* Must be real MPI */