| 197 | |
| 198 | |
| 199 | bool gpu_isGpuAvailable() { |
| 200 | #if COMPILE_CUDA |
| 201 | |
| 202 | int numDevices = gpu_getNumberOfLocalGpus(); |
| 203 | if (numDevices == 0) |
| 204 | return false; |
| 205 | |
| 206 | // check if any reported device is a valid GPU |
| 207 | for (int deviceInd=0; deviceInd < numDevices; deviceInd++) { |
| 208 | |
| 209 | // by checking the properties of each device |
| 210 | struct cudaDeviceProp props; |
| 211 | auto status = cudaGetDeviceProperties(&props, deviceInd); |
| 212 | |
| 213 | // if the query failed, device is anyway unusable; we do not |
| 214 | // clear the error with clearPossibleCudaError() since this |
| 215 | // can trigger an internal error when QuEST is GPU-compiled |
| 216 | // but no valid GPU exists (hence no valid driver), like |
| 217 | // occurs on cluster submission nodes |
| 218 | if (status != cudaSuccess) |
| 219 | continue; |
| 220 | |
| 221 | // if the device is a real GPU, it's 'major' compute capability is != 9999 (meaning emulation) |
| 222 | if (props.major != 9999) |
| 223 | return true; |
| 224 | } |
| 225 | |
| 226 | // no non-emulation devices were found |
| 227 | return false; |
| 228 | |
| 229 | #else |
| 230 | error_gpuQueriedButGpuNotCompiled(); |
| 231 | return false; |
| 232 | #endif |
| 233 | } |
| 234 | |
| 235 | |
| 236 | bool gpu_isDirectGpuCommPossible() { |
no test coverage detected