OpenDroneMap-ODM/opendm/gpu.py

92 wiersze
3.2 KiB
Python
Czysty Zwykły widok Historia

2021-03-23 19:15:47 +00:00
import os
2021-11-24 16:26:03 +00:00
import sys
2021-12-16 19:36:17 +00:00
import shutil
import ctypes
2021-02-09 17:14:05 +00:00
from opendm import log
from repoze.lru import lru_cache
2022-05-30 19:52:13 +00:00
def gpu_disabled_by_user_env():
2021-11-12 15:41:41 +00:00
return bool(os.environ.get('ODM_NO_GPU'))
2021-02-09 17:14:05 +00:00
@lru_cache(maxsize=None)
def has_popsift_and_can_handle_texsize(width, height):
# We first check that we have the required compute capabilities
# As we do not support compute capabilities less than 3.5
try:
compute_major, compute_minor = get_cuda_compute_version(0)
if compute_major < 3 or (compute_major == 3 and compute_minor < 5):
# Not supported
2023-03-20 16:59:33 +00:00
log.ODM_INFO("CUDA compute platform is not supported (detected: %s.%s but we need at least 3.5)" % (compute_major, compute_minor))
return False
except Exception as e:
2023-03-20 16:59:33 +00:00
log.ODM_INFO("Using CPU for feature extraction: %s" % str(e))
2022-03-09 16:53:02 +00:00
return False
try:
2021-12-16 19:36:17 +00:00
from opensfm import pypopsift
2023-03-20 16:59:33 +00:00
return pypopsift.fits_texture(int(width * 1.02), int(height * 1.02))
2021-12-17 17:12:41 +00:00
except (ModuleNotFoundError, ImportError):
return False
except Exception as e:
log.ODM_WARNING(str(e))
return False
2021-02-09 17:14:05 +00:00
@lru_cache(maxsize=None)
def get_cuda_compute_version(device_id = 0):
cuda_lib = "libcuda.so"
if sys.platform == 'win32':
2022-06-19 21:00:49 +00:00
cuda_lib = os.path.join(os.environ.get('SYSTEMROOT'), 'system32', 'nvcuda.dll')
if not os.path.isfile(cuda_lib):
cuda_lib = "nvcuda.dll"
nvcuda = ctypes.cdll.LoadLibrary(cuda_lib)
nvcuda.cuInit.argtypes = (ctypes.c_uint32, )
nvcuda.cuInit.restypes = (ctypes.c_int32)
if nvcuda.cuInit(0) != 0:
raise Exception("Cannot initialize CUDA")
nvcuda.cuDeviceGetCount.argtypes = (ctypes.POINTER(ctypes.c_int32), )
nvcuda.cuDeviceGetCount.restypes = (ctypes.c_int32)
device_count = ctypes.c_int32()
if nvcuda.cuDeviceGetCount(ctypes.byref(device_count)) != 0:
raise Exception("Cannot get device count")
if device_count.value == 0:
raise Exception("No devices")
nvcuda.cuDeviceComputeCapability.argtypes = (ctypes.POINTER(ctypes.c_int32), ctypes.POINTER(ctypes.c_int32), ctypes.c_int32)
nvcuda.cuDeviceComputeCapability.restypes = (ctypes.c_int32)
compute_major = ctypes.c_int32()
compute_minor = ctypes.c_int32()
if nvcuda.cuDeviceComputeCapability(ctypes.byref(compute_major), ctypes.byref(compute_minor), device_id) != 0:
raise Exception("Cannot get CUDA compute version")
return (compute_major.value, compute_minor.value)
2022-05-30 19:52:13 +00:00
def has_gpu(args):
if gpu_disabled_by_user_env():
2021-12-16 19:36:17 +00:00
log.ODM_INFO("Disabling GPU features (ODM_NO_GPU is set)")
2021-02-09 17:14:05 +00:00
return False
2022-05-30 19:52:13 +00:00
if args.no_gpu:
log.ODM_INFO("Disabling GPU features (--no-gpu is set)")
return False
if sys.platform == 'win32':
nvcuda_path = os.path.join(os.environ.get('SYSTEMROOT'), 'system32', 'nvcuda.dll')
if os.path.isfile(nvcuda_path):
2022-02-03 14:13:25 +00:00
log.ODM_INFO("CUDA drivers detected")
2021-12-16 19:36:17 +00:00
return True
else:
log.ODM_INFO("No CUDA drivers detected, using CPU")
2021-12-16 19:36:17 +00:00
return False
else:
2021-12-16 19:36:17 +00:00
if shutil.which('nvidia-smi') is not None:
2022-02-03 14:13:25 +00:00
log.ODM_INFO("nvidia-smi detected")
2021-12-16 19:36:17 +00:00
return True
else:
return False