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 <cuda.h>
21
22#include "init.hpp"
23#include "utils.cuh"
24
25#include <utils/constants.hpp>
26
27#include <cstring>
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 if (deviceProp.major < computeCapabilityMinMajor ||
54 (deviceProp.major == computeCapabilityMinMajor &&
55 deviceProp.minor < computeCapabilityMinMinor)) {
56 return ES_ERROR;
57 }
58 return ES_OK;
59}
60
61/**
62 * @brief Safely copy the device name and pad the string with null characters.
63 */
64static void cuda_copy_gpu_name(char *const name, cudaDeviceProp const &prop) {
65 char buffer[256] = {'\0'};
66 std::strncpy(buffer, prop.name, 256);
67 name[255] = '\0';
68 std::strncpy(name, buffer, 256);
69}
70
71void cuda_get_gpu_name(int dev, char *const name) {
72 cudaDeviceProp deviceProp;
73 CUDA_CHECK(cudaGetDeviceProperties(&deviceProp, dev))
74 cuda_copy_gpu_name(name, deviceProp);
75}
76
78 cudaDeviceProp deviceProp;
79 CUDA_CHECK(cudaGetDeviceProperties(&deviceProp, dev))
80 EspressoGpuDevice device{dev,
81 "",
82 "",
83 -1,
84 deviceProp.major,
85 deviceProp.minor,
86 deviceProp.totalGlobalMem,
87 deviceProp.multiProcessorCount};
88 cuda_copy_gpu_name(device.name, deviceProp);
89 return device;
90}
91
92void cuda_set_device(int dev) {
94 CUDA_CHECK(cudaStreamDestroy(stream[0]))
95 CUDA_CHECK(cudaStreamCreate(&stream[0]))
96}
97
99 int dev;
100 CUDA_CHECK(cudaGetDevice(&dev))
101 return dev;
102}
103
105 int *d = nullptr;
106 int h = 42;
107 cudaError_t err;
108
109 err = cudaMalloc((void **)&d, sizeof(int));
110 if (err != cudaSuccess) {
111 throw cuda_runtime_error_cuda(err);
112 }
113 err = cudaMemcpy(d, &h, sizeof(int), cudaMemcpyHostToDevice);
114 if (err != cudaSuccess) {
115 cudaFree(d);
116 throw cuda_runtime_error_cuda(err);
117 }
118 h = 0;
119 err = cudaMemcpy(&h, d, sizeof(int), cudaMemcpyDeviceToHost);
120 cudaFree(d);
121 if (err != cudaSuccess) {
122 throw cuda_runtime_error_cuda(err);
123 }
124 if (h != 42) {
125 return ES_ERROR;
126 }
127 return ES_OK;
128}
129
131 if (cuda_get_n_gpus() == 0) {
132 throw cuda_runtime_error("No GPU was found.");
133 }
134 auto const devID = cuda_get_device();
135 auto const compute_capability = cuda_check_gpu_compute_capability(devID);
136 auto const communication_test = cuda_test_device_access();
137 if (compute_capability != ES_OK or communication_test != ES_OK) {
138 throw cuda_runtime_error("CUDA device " + std::to_string(devID) +
139 " is not capable of running ESPResSo.");
140 }
141}
142
143#endif /* defined(CUDA) */
float h[3]
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
#define ES_OK
error code if no error occurred
Definition constants.hpp:78
#define ES_ERROR
error code if an error occurred
Definition constants.hpp:80
int cuda_test_device_access()
Test if actual CUDA device works.
Definition init_cuda.cu:104
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:77
void cuda_check_device()
Check that a device is available, that its compute capability is sufficient for ESPResSo,...
Definition init_cuda.cu:130
void cuda_get_gpu_name(int dev, char *const name)
Get the name of a CUDA device.
Definition init_cuda.cu:71
static const int computeCapabilityMinMinor
Definition init_cuda.cu:39
int cuda_check_gpu_compute_capability(int dev)
Check that a given GPU has compute capability.
Definition init_cuda.cu:50
int cuda_get_device()
Get the current CUDA device.
Definition init_cuda.cu:98
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:64
void cuda_set_device(int dev)
Choose a device for future CUDA computations.
Definition init_cuda.cu:92
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
static constexpr int deviceCount
#define cudaSetDevice(d)
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:45