ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
init_cuda.cu
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2022 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "init.hpp"
21#include "utils.cuh"
22
23#include <cuda.h>
24#include <cuda_runtime.h>
25
26#include <cstring>
27#include <memory>
28#include <string>
29
30#if defined(OMPI_MPI_H) || defined(_MPI_H)
31#error CU-file includes mpi.h! This should not happen!
32#endif
33
34#ifdef CUDA
35
36/** \name minimally required compute capability. */
37/**@{*/
38static const int computeCapabilityMinMajor = 3;
39static const int computeCapabilityMinMinor = 0;
40/**@}*/
41
42void cuda_init() { CUDA_CHECK(cudaStreamCreate(&stream[0])) }
43
45 int deviceCount;
46 CUDA_CHECK(cudaGetDeviceCount(&deviceCount))
47 return deviceCount;
48}
49
51 cudaDeviceProp deviceProp;
52 CUDA_CHECK(cudaGetDeviceProperties(&deviceProp, dev))
53 return (deviceProp.major < computeCapabilityMinMajor or
54 (deviceProp.major == computeCapabilityMinMajor and
55 deviceProp.minor < computeCapabilityMinMinor));
56}
57
58/**
59 * @brief Safely copy the device name and pad the string with null characters.
60 */
61static void cuda_copy_gpu_name(char *const name, cudaDeviceProp const &prop) {
62 char buffer[256] = {'\0'};
63 std::strncpy(buffer, prop.name, 256);
64 name[255] = '\0';
65 std::strncpy(name, buffer, 256);
66}
67
68void cuda_get_gpu_name(int dev, char *const name) {
69 cudaDeviceProp deviceProp;
70 CUDA_CHECK(cudaGetDeviceProperties(&deviceProp, dev))
71 cuda_copy_gpu_name(name, deviceProp);
72}
73
75 cudaDeviceProp deviceProp;
76 CUDA_CHECK(cudaGetDeviceProperties(&deviceProp, dev))
77 EspressoGpuDevice device{dev,
78 "",
79 "",
80 -1,
81 deviceProp.major,
82 deviceProp.minor,
83 deviceProp.totalGlobalMem,
84 deviceProp.multiProcessorCount};
85 cuda_copy_gpu_name(device.name, deviceProp);
86 return device;
87}
88
89void cuda_set_device(int dev) {
90 CUDA_CHECK(cudaSetDevice(dev))
91 CUDA_CHECK(cudaStreamDestroy(stream[0]))
92 CUDA_CHECK(cudaStreamCreate(&stream[0]))
93}
94
96 int dev;
97 CUDA_CHECK(cudaGetDevice(&dev))
98 return dev;
99}
100
102 auto const deleter = [](int *p) { cudaFree(reinterpret_cast<void *>(p)); };
103 int *ptr = nullptr;
104 int h = 42;
105 CUDA_CHECK(cudaMalloc(reinterpret_cast<void **>(&ptr), sizeof(int)));
106 std::unique_ptr<int, decltype(deleter)> d(ptr, deleter);
107 CUDA_CHECK(cudaMemcpy(d.get(), &h, sizeof(int), cudaMemcpyHostToDevice));
108 h = 0;
109 CUDA_CHECK(cudaMemcpy(&h, d.get(), sizeof(int), cudaMemcpyDeviceToHost));
110 return h != 42;
111}
112
114 if (cuda_get_n_gpus() == 0) {
115 throw cuda_runtime_error("No GPU was found.");
116 }
117 auto const devID = cuda_get_device();
118 auto const incompatible = cuda_check_gpu_compute_capability(devID);
119 auto const communication_failure = cuda_test_device_access();
120 if (incompatible or communication_failure) {
121 throw cuda_runtime_error("CUDA device " + std::to_string(devID) +
122 " is not capable of running ESPResSo.");
123 }
124}
125
126#endif /* defined(CUDA) */
Wrapper for CUDA runtime exceptions.
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
static const int computeCapabilityMinMajor
Definition init_cuda.cu:38
EspressoGpuDevice cuda_get_device_props(const int dev)
Get properties of a CUDA device.
Definition init_cuda.cu:74
void cuda_check_device()
Check that a device is available, that its compute capability is sufficient for ESPResSo,...
Definition init_cuda.cu:113
bool cuda_check_gpu_compute_capability(int dev)
Check that a given GPU has compute capability.
Definition init_cuda.cu:50
void cuda_get_gpu_name(int dev, char *const name)
Get the name of a CUDA device.
Definition init_cuda.cu:68
bool cuda_test_device_access()
Test if communication to the CUDA device works.
Definition init_cuda.cu:101
static const int computeCapabilityMinMinor
Definition init_cuda.cu:39
int cuda_get_device()
Get the current CUDA device.
Definition init_cuda.cu:95
static void cuda_copy_gpu_name(char *const name, cudaDeviceProp const &prop)
Safely copy the device name and pad the string with null characters.
Definition init_cuda.cu:61
void cuda_set_device(int dev)
Choose a device for future CUDA computations.
Definition init_cuda.cu:89
int cuda_get_n_gpus()
Get the number of CUDA devices.
Definition init_cuda.cu:44
void cuda_init()
Initializes the CUDA stream.
Definition init_cuda.cu:42
Struct to hold information relevant to ESPResSo about GPUs.
Definition init.hpp:35
#define CUDA_CHECK(statement)
Convert CUDA error codes into runtime errors.
Definition utils.cuh:46