diff --git a/.gitignore b/.gitignore index 9c06b143..d3828c78 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,5 @@ vcpkg/ venv/ python38/ dist/ -innosetup/ \ No newline at end of file +innosetup/ +.DS_Store diff --git a/README.md b/README.md index 836ef4a4..e0b08031 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ run C:\Users\youruser\datasets\project [--additional --parameters --here] ODM has support for doing SIFT feature extraction on a GPU, which is about 2x faster than the CPU on a typical consumer laptop. To use this feature, you need to use the `opendronemap/odm:gpu` docker image instead of `opendronemap/odm` and you need to pass the `--gpus all` flag: ``` -docker run -ti --rm -v c:/Users/youruser/datasets:/datasets --gpus all opendronemap/odm:gpu --project-path /datasets project +docker run -ti --rm -v c:/Users/youruser/datasets:/datasets --gpus all opendronemap/odm:gpu --project-path /datasets project --feature-type sift ``` When you run ODM, if the GPU is recognized, in the first few lines of output you should see: diff --git a/gpu.Dockerfile b/gpu.Dockerfile index e6e1c47b..c2afc558 100644 --- a/gpu.Dockerfile +++ b/gpu.Dockerfile @@ -1,8 +1,8 @@ -FROM nvidia/cuda:11.2.2-devel-ubuntu20.04 AS builder +FROM nvidia/cuda:11.8.0-devel-ubuntu20.04 AS builder # Env variables ENV DEBIAN_FRONTEND=noninteractive \ - PYTHONPATH="$PYTHONPATH:/code/SuperBuild/install/lib/python3.9/dist-packages:/code/SuperBuild/install/lib/python3.8/dist-packages:/code/SuperBuild/install/bin/opensfm" \ + PYTHONPATH="/code/SuperBuild/install/lib/python3.9/dist-packages:/code/SuperBuild/install/lib/python3.8/dist-packages:/code/SuperBuild/install/bin/opensfm" \ LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/code/SuperBuild/install/lib" # Prepare directories @@ -21,12 +21,11 @@ RUN bash configure.sh clean ### Use a second image for the final asset to reduce the number and # size of the layers. -FROM nvidia/cuda:11.2.2-runtime-ubuntu20.04 -#FROM nvidia/cuda:11.2.0-devel-ubuntu20.04 +FROM nvidia/cuda:11.8.0-runtime-ubuntu20.04 # Env variables ENV DEBIAN_FRONTEND=noninteractive \ - PYTHONPATH="$PYTHONPATH:/code/SuperBuild/install/lib/python3.9/dist-packages:/code/SuperBuild/install/lib/python3.8/dist-packages:/code/SuperBuild/install/bin/opensfm" \ + PYTHONPATH="/code/SuperBuild/install/lib/python3.9/dist-packages:/code/SuperBuild/install/lib/python3.8/dist-packages:/code/SuperBuild/install/bin/opensfm" \ LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/code/SuperBuild/install/lib" \ PDAL_DRIVER_PATH="/code/SuperBuild/install/bin" @@ -38,7 +37,7 @@ COPY --from=builder /code /code # Copy the Python libraries installed via pip from the builder COPY --from=builder /usr/local /usr/local #COPY --from=builder /usr/lib/x86_64-linux-gnu/libavcodec.so.58 /usr/lib/x86_64-linux-gnu/libavcodec.so.58 -RUN dpkg --remove cuda-compat-11-2 + RUN apt-get update -y \ && apt-get install -y ffmpeg libtbb2 # Install shared libraries that we depend on via APT, but *not* diff --git a/opendm/gpu.py b/opendm/gpu.py index 2b423614..a75a44a7 100644 --- a/opendm/gpu.py +++ b/opendm/gpu.py @@ -19,14 +19,17 @@ def has_popsift_and_can_handle_texsize(width, height): 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: - log.ODM_INFO("Using CPU for feature extraction: %s" % str(e)) + log.ODM_WARNING(str(e)) return False try: from opensfm import pypopsift - return pypopsift.fits_texture(int(width * 1.02), int(height * 1.02)) - except (ModuleNotFoundError, ImportError): - return False + if pypopsift.fits_texture(int(width * 1.02), int(height * 1.02)): + log.ODM_INFO("popsift can handle texture size %dx%d" % (width, height)) + return True + else: + log.ODM_INFO("popsift cannot handle texture size %dx%d" % (width, height)) + return False except Exception as e: log.ODM_WARNING(str(e)) return False @@ -81,11 +84,12 @@ def has_gpu(args): log.ODM_INFO("CUDA drivers detected") return True else: - log.ODM_INFO("No CUDA drivers detected, using CPU") + log.ODM_INFO("No CUDA drivers detected") return False else: if shutil.which('nvidia-smi') is not None: log.ODM_INFO("nvidia-smi detected") return True else: + log.ODM_INFO("No nvidia-smi detected") return False diff --git a/opendm/osfm.py b/opendm/osfm.py index 0d49e1e4..5db25706 100644 --- a/opendm/osfm.py +++ b/opendm/osfm.py @@ -296,19 +296,23 @@ class OSFMContext: config.append("matcher_type: %s" % osfm_matchers[matcher_type]) # GPU acceleration? - if has_gpu(args) and max_dims is not None: - w, h = max_dims - if w > h: - h = int((h / w) * feature_process_size) - w = int(feature_process_size) - else: - w = int((w / h) * feature_process_size) - h = int(feature_process_size) - - if has_popsift_and_can_handle_texsize(w, h) and feature_type == "SIFT": - log.ODM_INFO("Using GPU for extracting SIFT features") - feature_type = "SIFT_GPU" - self.gpu_sift_feature_extraction = True + if feature_type == "SIFT": + log.ODM_INFO("Checking for GPU as using SIFT for extracting features") + if has_gpu(args) and max_dims is not None: + w, h = max_dims + if w > h: + h = int((h / w) * feature_process_size) + w = int(feature_process_size) + else: + w = int((w / h) * feature_process_size) + h = int(feature_process_size) + + if has_popsift_and_can_handle_texsize(w, h): + log.ODM_INFO("Using GPU for extracting SIFT features") + feature_type = "SIFT_GPU" + self.gpu_sift_feature_extraction = True + else: + log.ODM_INFO("Using CPU for extracting SIFT features as texture size is too large or GPU SIFT is not available") config.append("feature_type: %s" % feature_type)