SCM Repository
Annotation of /branches/cuda/src/lib/include/diderot/gpu-select.cuh
Parent Directory
|
Revision Log
Revision 5641 - (view) (download)
1 : | adrianlehm | 5634 | #ifndef _DIDEROT_GPU_SELECT_ |
2 : | #define _DIDEROT_GPU_SELECT_ | ||
3 : | |||
4 : | adrianlehm | 5641 | #include "base.h" |
5 : | adrianlehm | 5634 | #include "options.h" |
6 : | #include <cmath> | ||
7 : | |||
8 : | namespace diderot { | ||
9 : | class gpu_selector { | ||
10 : | private: | ||
11 : | bool interactive = false; | ||
12 : | int32_t gpuIdx = -1; | ||
13 : | |||
14 : | bool isValidGpu(cudaDeviceProp &deviceProperties) { | ||
15 : | return deviceProperties.major >= 6 && deviceProperties.totalGlobalMem >= 1000 * 1000 * 1000 /*1GB*/; | ||
16 : | } | ||
17 : | |||
18 : | public: | ||
19 : | void registerOptions(diderot::options *options) { | ||
20 : | options->addFlag("ig,interactive-gpu", "Interactively select CUDA GPU when launching", &interactive); | ||
21 : | options->add("gpu", "Specify id of CUDA GPU to select", &gpuIdx, true); | ||
22 : | } | ||
23 : | |||
24 : | void selectGpu() { | ||
25 : | if (gpuIdx < -1) { | ||
26 : | std::cerr << "Warning: GPU id cannot be negative - ignoring" << std::endl; | ||
27 : | } | ||
28 : | bool validGpuId = gpuIdx >= 0; | ||
29 : | if (interactive && validGpuId) { | ||
30 : | std::cerr << "Warning: GPU specified, ignoring interactive GPU selection flag" << std::endl; | ||
31 : | } | ||
32 : | int devicesCount; | ||
33 : | cudaGetDeviceCount(&devicesCount); | ||
34 : | adrianlehm | 5635 | if (devicesCount == 0) { |
35 : | adrianlehm | 5634 | std::cerr << "Error: No CUDA GPUs found." << std::endl; |
36 : | exit(1); | ||
37 : | } | ||
38 : | adrianlehm | 5635 | int defaultGpuIdx; |
39 : | cudaGetDevice(&defaultGpuIdx); | ||
40 : | adrianlehm | 5634 | if (!validGpuId && interactive) { |
41 : | std::cout << "Available GPUs:" << std::endl; | ||
42 : | std::cout << "| id | name | memory | max grid | max threads per block |\n"; | ||
43 : | for (int i = 0; i < devicesCount; i++) { | ||
44 : | cudaDeviceProp deviceProperties{}; | ||
45 : | cudaGetDeviceProperties(&deviceProperties, i); | ||
46 : | if (!isValidGpu(deviceProperties)) { | ||
47 : | continue; | ||
48 : | } | ||
49 : | int maxGridSize = std::min(deviceProperties.maxGridSize[0], | ||
50 : | std::min(deviceProperties.maxGridSize[1], deviceProperties.maxGridSize[2])); | ||
51 : | printf("| %d | %s | %zu | %d | %d |\n", i, deviceProperties.name, deviceProperties.totalGlobalMem, | ||
52 : | maxGridSize, deviceProperties.maxThreadsPerBlock); | ||
53 : | } | ||
54 : | std::cout << std::endl; | ||
55 : | do { | ||
56 : | std::cout << "Enter GPU id:" << std::endl; | ||
57 : | std::string input; | ||
58 : | getline(std::cin, input); | ||
59 : | try { | ||
60 : | gpuIdx = std::stoi(input); | ||
61 : | } catch (std::invalid_argument) { | ||
62 : | } | ||
63 : | adrianlehm | 5641 | } while (gpuIdx < 0 || gpuIdx >= devicesCount); |
64 : | adrianlehm | 5634 | } |
65 : | validGpuId = gpuIdx >= 0 && gpuIdx <= devicesCount; | ||
66 : | adrianlehm | 5635 | cudaError_t gpuSelectionErr = cudaSuccess; |
67 : | adrianlehm | 5634 | if (validGpuId) { |
68 : | cudaDeviceProp deviceProperties{}; | ||
69 : | cudaGetDeviceProperties(&deviceProperties, gpuIdx); | ||
70 : | if (!isValidGpu(deviceProperties)) { | ||
71 : | std::cerr | ||
72 : | << "Warning: selected invalid GPU. Falling back to default GPU. Please use interactive GPU selection if unsure"; | ||
73 : | return; | ||
74 : | } | ||
75 : | std::cout << "Set GPU to: " << deviceProperties.name << " (id:" << gpuIdx << ")" << std::endl; | ||
76 : | adrianlehm | 5635 | gpuSelectionErr = cudaSetDevice(gpuIdx); |
77 : | if (gpuSelectionErr == cudaErrorDeviceAlreadyInUse) { | ||
78 : | std::cerr << "Warning: GPU already in use - falling back to default" << std::endl; | ||
79 : | } else if (gpuSelectionErr == cudaErrorInvalidDevice) { // Should technically not happen | ||
80 : | std::cerr << "Warning: GPU invalid - falling back to default" << std::endl; | ||
81 : | } | ||
82 : | } | ||
83 : | if ((!validGpuId || gpuSelectionErr != cudaSuccess) && | ||
84 : | devicesCount > 1) { // No need to display selection when single GPU | ||
85 : | adrianlehm | 5634 | cudaDeviceProp deviceProperties{}; |
86 : | adrianlehm | 5635 | cudaGetDeviceProperties(&deviceProperties, defaultGpuIdx); |
87 : | std::cout << "Using default GPU: " << deviceProperties.name << " (id:" << defaultGpuIdx << ")" << std::endl; | ||
88 : | gpuSelectionErr = cudaSetDevice(defaultGpuIdx); | ||
89 : | if (gpuSelectionErr == cudaErrorDeviceAlreadyInUse) { | ||
90 : | std::cerr << "Error: Default/Fallback GPU already in use" << std::endl; | ||
91 : | exit(1); | ||
92 : | } else if (gpuSelectionErr == cudaErrorInvalidDevice) { // Should technically not happen | ||
93 : | std::cerr << "Warning: Default/Fallback GPU invalid" << std::endl; | ||
94 : | exit(1); | ||
95 : | } | ||
96 : | adrianlehm | 5634 | } |
97 : | } | ||
98 : | }; | ||
99 : | } | ||
100 : | #endif //_DIDEROT_GPU_SELECT_ |
root@smlnj-gforge.cs.uchicago.edu | ViewVC Help |
Powered by ViewVC 1.0.0 |