Lift
Library of parallel computing primitives for GPUs and multi-core CPUs
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
compute_device_cuda.cu
Go to the documentation of this file.
1 /*
2  * Lift
3  *
4  * Copyright (c) 2014-2015, NVIDIA CORPORATION
5  * Copyright (c) 2015, Nuno Subtil <subtil@gmail.com>
6  * Copyright (c) 2015, Roche Molecular Systems, Inc.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  * * Neither the name of the copyright holders nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <lift/types.h>
34 
35 #include <string>
36 #include <vector>
37 
38 namespace lift {
39 
41 {
42  cudaDeviceProp prop;
43  cudaGetDeviceProperties(&prop, dev);
44 
45  // compose our device name
46  char str[1024];
47  snprintf(str, sizeof(str), "NVIDIA %s (%lu MB, CUDA device %d)",
48  prop.name, prop.totalGlobalMem / (1024 * 1024), dev);
49 
50  device = dev;
51  device_name = strdup(str);
52  total_memory = prop.totalGlobalMem;
53  compute_capability_major = prop.major;
54  compute_capability_minor = prop.minor;
55 }
56 
57 // enumerate the GPUs that match a set of minimum requirements
58 // returns false if an error occurs
59 bool cuda_device_config::enumerate_gpus(std::vector<cuda_device_config>& devices,
60  std::string& error,
61  const cuda_device_config& requirements)
62 {
63  cudaError_t err;
64  int gpu_count;
65 
66  err = cudaGetDeviceCount(&gpu_count);
67  if (err != cudaSuccess)
68  {
69  error = std::string(cudaGetErrorString(err));
70  return false;
71  }
72 
73  for(int dev = 0; dev < gpu_count; dev++)
74  {
75  cudaDeviceProp prop;
76  cudaGetDeviceProperties(&prop, dev);
77 
78  // match on the config requirements
79  if (requirements.device != -1 &&
80  dev != requirements.device)
81  {
82  continue;
83  }
84 
85  if (requirements.device_name != nullptr &&
86  strcmp(requirements.device_name, prop.name))
87  {
88  continue;
89  }
90 
91  // the following are considered a minimum requirement and not an exact match
92  if (requirements.total_memory != uint64(-1) &&
93  prop.totalGlobalMem < requirements.total_memory)
94  {
95  continue;
96  }
97 
98  if (requirements.compute_capability_major != -1)
99  {
100  if (prop.major < requirements.compute_capability_major)
101  {
102  continue;
103  }
104 
105  if (prop.major == requirements.compute_capability_major)
106  {
107  if (requirements.compute_capability_minor != -1 &&
108  prop.minor < requirements.compute_capability_minor)
109  {
110  continue;
111  }
112  }
113  }
114 
115  devices.push_back(cuda_device_config(dev));
116  }
117 
118  return true;
119 }
120 
122 {
123  cudaError_t err;
124  int runtime_version;
125 
126  // force explicit runtime initialization
127  err = cudaFree(0);
128  if (err != cudaSuccess)
129  {
130  ret = std::string(cudaGetErrorString(err));
131  return false;
132  }
133 
134  err = cudaRuntimeGetVersion(&runtime_version);
135  if (err != cudaSuccess)
136  {
137  ret = std::string(cudaGetErrorString(err));
138  return false;
139  }
140 
141  char buf[256];
142  snprintf(buf, sizeof(buf),
143  "NVIDIA CUDA %d.%d", runtime_version / 1000, runtime_version % 100 / 10);
144 
145  ret = std::string(buf);
146  return true;
147 }
148 
149 } // namespace lift
uint64_t uint64
Definition: types.h:45
static bool enumerate_gpus(std::vector< cuda_device_config > &devices, std::string &error, const cuda_device_config &requirements=cuda_device_config())
static bool runtime_initialize(std::string &ret)