Viskores  1.0
ChooseCudaDevice.h
Go to the documentation of this file.
1 //============================================================================
2 // The contents of this file are covered by the Viskores license. See
3 // LICENSE.txt for details.
4 //
5 // By contributing to this file, all contributors agree to the Developer
6 // Certificate of Origin Version 1.1 (DCO 1.1) as stated in DCO.txt.
7 //============================================================================
8 
9 //============================================================================
10 // Copyright (c) Kitware, Inc.
11 // All rights reserved.
12 // See LICENSE.txt for details.
13 //
14 // This software is distributed WITHOUT ANY WARRANTY; without even
15 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 // PURPOSE. See the above copyright notice for more information.
17 //============================================================================
18 #ifndef viskores_cont_cuda_ChooseCudaDevice_h
19 #define viskores_cont_cuda_ChooseCudaDevice_h
20 
22 
27 
28 #include <algorithm>
29 #include <set>
30 #include <vector>
31 
33 #include <cuda.h>
35 
36 namespace viskores
37 {
38 namespace cont
39 {
40 namespace cuda
41 {
42 
43 namespace
44 {
45 struct compute_info
46 {
47  compute_info(cudaDeviceProp prop, int index)
48  {
49  this->Index = index;
50  this->Major = prop.major;
51 
52  this->MemorySize = prop.totalGlobalMem;
53  this->Performance =
54  prop.multiProcessorCount * prop.maxThreadsPerMultiProcessor * (prop.clockRate / 100000.0);
55 
56  //9999 is equal to emulation make sure it is a super bad device
57  if (this->Major >= 9999)
58  {
59  this->Major = -1;
60  this->Performance = -1;
61  }
62  }
63 
64  //sort from fastest to slowest
65  bool operator<(const compute_info other) const
66  {
67  //if we are both SM3 or greater check performance
68  //if we both the same SM level check performance
69  if ((this->Major >= 3 && other.Major >= 3) || (this->Major == other.Major))
70  {
71  return betterPerformance(other);
72  }
73  //prefer the greater SM otherwise
74  return this->Major > other.Major;
75  }
76 
77  bool betterPerformance(const compute_info other) const
78  {
79  if (this->Performance == other.Performance)
80  {
81  if (this->MemorySize == other.MemorySize)
82  {
83  //prefer first device over second device
84  //this will be subjective I bet
85  return this->Index < other.Index;
86  }
87  return this->MemorySize > other.MemorySize;
88  }
89  return this->Performance > other.Performance;
90  }
91 
92  int GetIndex() const { return Index; }
93 
94 private:
95  int Index;
96  int Major;
97  size_t MemorySize;
98  double Performance;
99 };
100 }
101 
104 static int FindFastestDeviceId()
105 {
106  auto cudaDeviceConfig = dynamic_cast<
107  viskores::cont::internal::RuntimeDeviceConfiguration<viskores::cont::DeviceAdapterTagCuda>&>(
110  viskores::Id numDevices;
111  cudaDeviceConfig.GetMaxDevices(numDevices);
112 
113  // multiset stores elements in sorted order (allows duplicate values)
114  std::multiset<compute_info> devices;
115  std::vector<cudaDeviceProp> cudaProp;
116  cudaDeviceConfig.GetCudaDeviceProp(cudaProp);
117  for (int i = 0; i < numDevices; ++i)
118  {
119  if (cudaProp[i].computeMode != cudaComputeModeProhibited)
120  {
121  devices.emplace(cudaProp[i], i);
122  }
123  }
124 
125  return devices.size() > 0 ? devices.begin()->GetIndex() : 0;
126 }
127 
129 static void SetFastestDeviceId()
130 {
131  auto deviceId = FindFastestDeviceId();
134  .SetDeviceInstance(deviceId);
135 }
136 
137 }
138 }
139 } //namespace
140 
141 #endif
viskores::cont::RuntimeDeviceInformation
A class that can be used to determine if a given device adapter is supported on the current machine a...
Definition: RuntimeDeviceInformation.h:37
VISKORES_THIRDPARTY_POST_INCLUDE
#define VISKORES_THIRDPARTY_POST_INCLUDE
Definition: Configure.h:200
viskores::cont::DeviceAdapterTagCuda
Tag for a device adapter that uses a CUDA capable GPU device.
Definition: DeviceAdapterTagCuda.h:41
RuntimeDeviceConfigurationCuda.h
DeviceAdapterTagCuda.h
viskores::Id
viskores::Int64 Id
Base type to use to index arrays.
Definition: Types.h:235
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
Index
int Index
Definition: ChooseCudaDevice.h:95
ErrorExecution.h
Major
int Major
Definition: ChooseCudaDevice.h:96
MemorySize
size_t MemorySize
Definition: ChooseCudaDevice.h:97
RuntimeDeviceInformation.h
ErrorCuda.h
Performance
double Performance
Definition: ChooseCudaDevice.h:98
VISKORES_THIRDPARTY_PRE_INCLUDE
#define VISKORES_THIRDPARTY_PRE_INCLUDE
Definition: Configure.h:199
viskores::cont::RuntimeDeviceInformation::GetRuntimeConfiguration
viskores::cont::internal::RuntimeDeviceConfigurationBase & GetRuntimeConfiguration(DeviceAdapterId id, const viskores::cont::internal::RuntimeDeviceConfigurationOptions &configOptions, int &argc, char *argv[]=nullptr) const
Returns a reference to a RuntimeDeviceConfiguration that will work with the given device.