From adebdfc5809fb4be2ca31d9c48924f9d6fcd5eed Mon Sep 17 00:00:00 2001 From: Craig Warren Date: Tue, 1 Jun 2021 11:30:18 +0100 Subject: [PATCH] Beginning host/GPU detection for OpenCL --- gprMax/config.py | 4 +- gprMax/utilities/host_info.py | 78 +++++++++++++++++++++++------------ 2 files changed, 53 insertions(+), 29 deletions(-) diff --git a/gprMax/config.py b/gprMax/config.py index 12505f61..c6a0fd62 100644 --- a/gprMax/config.py +++ b/gprMax/config.py @@ -28,7 +28,7 @@ from scipy.constants import c from scipy.constants import epsilon_0 as e0 from scipy.constants import mu_0 as m0 -from .utilities.host_info import detect_gpus, get_host_info +from .utilities.host_info import detect_cuda_gpus, get_host_info from .utilities.utilities import get_terminal_width logger = logging.getLogger(__name__) @@ -236,7 +236,7 @@ class SimulationConfig: if sys.platform == 'win32': self.cuda['nvcc_opts'] = ['-w'] # List of GPU objects of available GPUs - self.cuda['gpus'] = detect_gpus() + self.cuda['gpus'] = detect_cuda_gpus() # Subgrid parameter may not exist if user enters via CLI try: diff --git a/gprMax/utilities/host_info.py b/gprMax/utilities/host_info.py index b2034651..70a7d5d7 100644 --- a/gprMax/utilities/host_info.py +++ b/gprMax/utilities/host_info.py @@ -302,32 +302,30 @@ def mem_check_all(grids): class GPU: """GPU information.""" - def __init__(self, deviceID): - """ - Args: - deviceID (int): Device ID for GPU. - """ + def __init__(self): - self.deviceID = deviceID + self.deviceID = None self.name = None self.pcibusID = None self.constmem = None self.totalmem = None - def get_gpu_info(self, drv): + def get_cuda_gpu_info(self, drv, deviceID): """Set information about GPU. Args: - drv (object): PyCuda driver. + drv (object): pycuda driver. + deviceID (int): Device ID for GPU. """ + self.deviceID = deviceID self.name = drv.Device(self.deviceID).name() self.pcibusID = drv.Device(self.deviceID).pci_bus_id() self.constmem = drv.Device(self.deviceID).total_constant_memory self.totalmem = drv.Device(self.deviceID).total_memory() -def detect_gpus(): +def detect_cuda_gpus(): """Get information about Nvidia GPU(s). Returns: @@ -336,26 +334,52 @@ def detect_gpus(): try: import pycuda.driver as drv + has_pycuda = True except ImportError: - logger.exception('To use gprMax in GPU mode the pycuda package must be installed, and you must have a NVIDIA CUDA-Enabled GPU (https://developer.nvidia.com/cuda-gpus).') - raise - drv.init() + logger.warning('pycuda not detected - to use gprMax in GPU mode the pycuda package must be installed, and you must have a NVIDIA CUDA-Enabled GPU (https://developer.nvidia.com/cuda-gpus).') + has_pycuda = False + + if has_pycuda: + drv.init() + + # Check and list any CUDA-Enabled GPUs + if drv.Device.count() == 0: + logger.exception('No NVIDIA CUDA-Enabled GPUs detected (https://developer.nvidia.com/cuda-gpus)') + raise ValueError + elif 'CUDA_VISIBLE_DEVICES' in os.environ: + deviceIDsavail = os.environ.get('CUDA_VISIBLE_DEVICES') + deviceIDsavail = [int(s) for s in deviceIDsavail.split(',')] + else: + deviceIDsavail = range(drv.Device.count()) + + # Gather information about detected GPUs + gpus = [] + for ID in deviceIDsavail: + gpu = GPU() + gpu.get_cuda_gpu_info(drv, ID) + gpus.append(gpu) - # Check and list any CUDA-Enabled GPUs - if drv.Device.count() == 0: - logger.exception('No NVIDIA CUDA-Enabled GPUs detected (https://developer.nvidia.com/cuda-gpus)') - raise ValueError - elif 'CUDA_VISIBLE_DEVICES' in os.environ: - deviceIDsavail = os.environ.get('CUDA_VISIBLE_DEVICES') - deviceIDsavail = [int(s) for s in deviceIDsavail.split(',')] else: - deviceIDsavail = range(drv.Device.count()) - - # Gather information about detected GPUs - gpus = [] - for ID in deviceIDsavail: - gpu = GPU(deviceID=ID) - gpu.get_gpu_info(drv) - gpus.append(gpu) + gpus = None return gpus + + +def detect_opencl(): + """Get information about OpenCL platforms and devices. + + Returns: + gpus (list): Detected GPU(s) object(s). + """ + + try: + import pyopencl as cl + has_pyopencl = True + except ImportError: + logger.warning('pyopencl not detected - to use gprMax with OpenCL, the pyopencl package must be installed, and you must have at least one OpenCL capable platform.') + has_pyopencl = False + + if has_pyopencl: + platforms = cl.get_platforms() + platform_names = [p.name for p in platforms] + logger.info(platform_names)