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 <string>
28
29#if defined(OMPI_MPI_H) || defined(_MPI_H)
30#error CU-file includes mpi.h! This should not happen!
31#endif
32
33#ifdef CUDA
34
35/** \name minimally required compute capability. */
36/**@{*/
37static const int computeCapabilityMinMajor = 3;
38static const int computeCapabilityMinMinor = 0;
39/**@}*/
40
41void cuda_init() { CUDA_CHECK(cudaStreamCreate(&stream[0])) }
42
44 int deviceCount;
45 CUDA_CHECK(cudaGetDeviceCount(&deviceCount))
46 return deviceCount;
47}
48
50 cudaDeviceProp deviceProp;
51 CUDA_CHECK(cudaGetDeviceProperties(&deviceProp, dev))
52 return (deviceProp.major < computeCapabilityMinMajor or
53 (deviceProp.major == computeCapabilityMinMajor and
54 deviceProp.minor < computeCapabilityMinMinor));
55}
56
57/**
58 * @brief Safely copy the device name and pad the string with null characters.
59 */
60static void cuda_copy_gpu_name(char *const name, cudaDeviceProp const &prop) {
61 char buffer[256] = {'\0'};
62 std::strncpy(buffer, prop.name, 256);
63 name[255] = '\0';
64 std::strncpy(name, buffer, 256);
65}
66
67void cuda_get_gpu_name(int dev, char *const name) {
68 cudaDeviceProp deviceProp;
69 CUDA_CHECK(cudaGetDeviceProperties(&deviceProp, dev))
70 cuda_copy_gpu_name(name, deviceProp);
71}
72
74 cudaDeviceProp deviceProp;
75 CUDA_CHECK(cudaGetDeviceProperties(&deviceProp, dev))
76 EspressoGpuDevice device{dev,
77 "",
78 "",
79 -1,
80 deviceProp.major,
81 deviceProp.minor,
82 deviceProp.totalGlobalMem,
83 deviceProp.multiProcessorCount};
84 cuda_copy_gpu_name(device.name, deviceProp);
85 return device;
86}
87
88void cuda_set_device(int dev) {
89 CUDA_CHECK(cudaSetDevice(dev))
90 CUDA_CHECK(cudaStreamDestroy(stream[0]))
91 CUDA_CHECK(cudaStreamCreate(&stream[0]))
92}
93
95 int dev;
96 CUDA_CHECK(cudaGetDevice(&dev))
97 return dev;
98}
99
101 int *d = nullptr;
102 int h = 42;
103 cudaError_t err;
104
105 err = cudaMalloc((void **)&d, sizeof(int));
106 if (err != cudaSuccess) {
107 throw cuda_runtime_error_cuda(err);
108 }
109 err = cudaMemcpy(d, &h, sizeof(int), cudaMemcpyHostToDevice);
110 if (err != cudaSuccess) {
111 cudaFree(d);
112 throw cuda_runtime_error_cuda(err);
113 }
114 h = 0;
115 err = cudaMemcpy(&h, d, sizeof(int), cudaMemcpyDeviceToHost);
116 cudaFree(d);
117 if (err != cudaSuccess) {
118 throw cuda_runtime_error_cuda(err);
119 }
120 return h != 42;
121}
122
124 if (cuda_get_n_gpus() == 0) {
125 throw cuda_runtime_error("No GPU was found.");
126 }
127 auto const devID = cuda_get_device();
128 auto const incompatible = cuda_check_gpu_compute_capability(devID);
129 auto const communication_failure = cuda_test_device_access();
130 if (incompatible or communication_failure) {
131 throw cuda_runtime_error("CUDA device " + std::to_string(devID) +
132 " is not capable of running ESPResSo.");
133 }
134}
135
136#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:37
EspressoGpuDevice cuda_get_device_props(const int dev)
Get properties of a CUDA device.
Definition init_cuda.cu:73
void cuda_check_device()
Check that a device is available, that its compute capability is sufficient for ESPResSo,...
Definition init_cuda.cu:123
bool cuda_check_gpu_compute_capability(int dev)
Check that a given GPU has compute capability.
Definition init_cuda.cu:49
void cuda_get_gpu_name(int dev, char *const name)
Get the name of a CUDA device.
Definition init_cuda.cu:67
bool cuda_test_device_access()
Test if communication to the CUDA device works.
Definition init_cuda.cu:100
static const int computeCapabilityMinMinor
Definition init_cuda.cu:38
int cuda_get_device()
Get the current CUDA device.
Definition init_cuda.cu:94
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:60
void cuda_set_device(int dev)
Choose a device for future CUDA computations.
Definition init_cuda.cu:88
int cuda_get_n_gpus()
Get the number of CUDA devices.
Definition init_cuda.cu:43
void cuda_init()
Initializes the CUDA stream.
Definition init_cuda.cu:41
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