Skip to content

Commit 8bc314e

Browse files
add gpu to global positioning and bundle adjustment
1 parent 18a70ee commit 8bc314e

File tree

7 files changed

+194
-2
lines changed

7 files changed

+194
-2
lines changed

cmake/FindDependencies.cmake

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ FetchContent_Declare(PoseLib
2828
SYSTEM
2929
)
3030
message(STATUS "Configuring PoseLib...")
31-
if (FETCH_POSELIB)
31+
if (FETCH_POSELIB)
3232
FetchContent_MakeAvailable(PoseLib)
3333
else()
3434
find_package(PoseLib REQUIRED)
@@ -42,9 +42,73 @@ FetchContent_Declare(COLMAP
4242
)
4343
message(STATUS "Configuring COLMAP...")
4444
set(UNINSTALL_ENABLED OFF CACHE INTERNAL "")
45-
if (FETCH_COLMAP)
45+
if (FETCH_COLMAP)
4646
FetchContent_MakeAvailable(COLMAP)
4747
else()
4848
find_package(COLMAP REQUIRED)
4949
endif()
5050
message(STATUS "Configuring COLMAP... done")
51+
52+
set(CUDA_MIN_VERSION "7.0")
53+
if(CUDA_ENABLED)
54+
if(CMAKE_VERSION VERSION_LESS 3.17)
55+
find_package(CUDA QUIET)
56+
if(CUDA_FOUND)
57+
message(STATUS "Found CUDA version ${CUDA_VERSION} installed in "
58+
"${CUDA_TOOLKIT_ROOT_DIR} via legacy CMake (<3.17) module. "
59+
"Using the legacy CMake module means that any installation of "
60+
"COLMAP will require that the CUDA libraries are "
61+
"available under LD_LIBRARY_PATH.")
62+
message(STATUS "Found CUDA ")
63+
message(STATUS " Includes : ${CUDA_INCLUDE_DIRS}")
64+
message(STATUS " Libraries : ${CUDA_LIBRARIES}")
65+
66+
enable_language(CUDA)
67+
68+
macro(declare_imported_cuda_target module)
69+
add_library(CUDA::${module} INTERFACE IMPORTED)
70+
target_include_directories(
71+
CUDA::${module} INTERFACE ${CUDA_INCLUDE_DIRS})
72+
target_link_libraries(
73+
CUDA::${module} INTERFACE ${CUDA_${module}_LIBRARY} ${ARGN})
74+
endmacro()
75+
76+
declare_imported_cuda_target(cudart ${CUDA_LIBRARIES})
77+
declare_imported_cuda_target(curand ${CUDA_LIBRARIES})
78+
79+
set(CUDAToolkit_VERSION "${CUDA_VERSION_STRING}")
80+
set(CUDAToolkit_BIN_DIR "${CUDA_TOOLKIT_ROOT_DIR}/bin")
81+
else()
82+
message(STATUS "CUDA not found")
83+
endif()
84+
else()
85+
find_package(CUDAToolkit QUIET)
86+
if(CUDAToolkit_FOUND)
87+
set(CUDA_FOUND ON)
88+
enable_language(CUDA)
89+
else()
90+
message(STATUS "CUDA not found")
91+
endif()
92+
endif()
93+
endif()
94+
95+
if(CUDA_ENABLED AND CUDA_FOUND)
96+
if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
97+
set(CMAKE_CUDA_ARCHITECTURES "native")
98+
endif()
99+
100+
add_definitions("-DGLOMAP_CUDA_ENABLED")
101+
102+
# Do not show warnings if the architectures are deprecated.
103+
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Wno-deprecated-gpu-targets")
104+
# Explicitly set PIC flags for CUDA targets.
105+
if(NOT IS_MSVC)
106+
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --compiler-options -fPIC")
107+
endif()
108+
109+
message(STATUS "Enabling CUDA support (version: ${CUDAToolkit_VERSION}, "
110+
"archs: ${CMAKE_CUDA_ARCHITECTURES})")
111+
else()
112+
set(CUDA_ENABLED OFF)
113+
message(STATUS "Disabling CUDA support")
114+
endif()

glomap/controllers/option_manager.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ void OptionManager::AddGlobalPositionerOptions() {
180180
return;
181181
}
182182
added_global_positioning_options_ = true;
183+
AddAndRegisterDefaultOption("GlobalPositioning.use_gpu",
184+
&mapper->opt_gp.use_gpu);
183185
AddAndRegisterDefaultOption("GlobalPositioning.optimize_positions",
184186
&mapper->opt_gp.optimize_positions);
185187
AddAndRegisterDefaultOption("GlobalPositioning.optimize_points",
@@ -199,6 +201,10 @@ void OptionManager::AddBundleAdjusterOptions() {
199201
return;
200202
}
201203
added_bundle_adjustment_options_ = true;
204+
AddAndRegisterDefaultOption("BundleAdjustment.use_gpu",
205+
&mapper->opt_ba.use_gpu);
206+
AddAndRegisterDefaultOption("BundleAdjustment.gpu_index",
207+
&mapper->opt_ba.gpu_index);
202208
AddAndRegisterDefaultOption("BundleAdjustment.optimize_rotations",
203209
&mapper->opt_ba.optimize_rotations);
204210
AddAndRegisterDefaultOption("BundleAdjustment.optimize_translation",

glomap/estimators/bundle_adjustment.cc

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include <colmap/estimators/cost_functions.h>
44
#include <colmap/estimators/manifold.h>
55
#include <colmap/sensor/models.h>
6+
#include <colmap/util/cuda.h>
7+
#include <colmap/util/misc.h>
68

79
namespace glomap {
810

@@ -36,6 +38,57 @@ bool BundleAdjuster::Solve(const ViewGraph& view_graph,
3638
// Set the solver options.
3739
ceres::Solver::Summary summary;
3840

41+
int num_images = images.size();
42+
#ifdef GLOMAP_CUDA_ENABLED
43+
bool cuda_solver_enabled = false;
44+
45+
#if (CERES_VERSION_MAJOR >= 3 || \
46+
(CERES_VERSION_MAJOR == 2 && CERES_VERSION_MINOR >= 2)) && \
47+
!defined(CERES_NO_CUDA)
48+
if (options_.use_gpu && num_images >= options_.min_num_images_gpu_solver) {
49+
cuda_solver_enabled = true;
50+
options_.solver_options.dense_linear_algebra_library_type = ceres::CUDA;
51+
}
52+
#else
53+
if (options_.use_gpu) {
54+
LOG_FIRST_N(WARNING, 1)
55+
<< "Requested to use GPU for bundle adjustment, but Ceres was "
56+
"compiled without CUDA support. Falling back to CPU-based dense "
57+
"solvers.";
58+
}
59+
#endif
60+
61+
#if (CERES_VERSION_MAJOR >= 3 || \
62+
(CERES_VERSION_MAJOR == 2 && CERES_VERSION_MINOR >= 3)) && \
63+
!defined(CERES_NO_CUDSS)
64+
if (options_.use_gpu && num_images >= options_.min_num_images_gpu_solver) {
65+
cuda_solver_enabled = true;
66+
options_.solver_options.sparse_linear_algebra_library_type =
67+
ceres::CUDA_SPARSE;
68+
}
69+
#else
70+
if (options_.use_gpu) {
71+
LOG_FIRST_N(WARNING, 1)
72+
<< "Requested to use GPU for bundle adjustment, but Ceres was "
73+
"compiled without cuDSS support. Falling back to CPU-based sparse "
74+
"solvers.";
75+
}
76+
#endif
77+
78+
if (cuda_solver_enabled) {
79+
const std::vector<int> gpu_indices = colmap::CSVToVector<int>(options_.gpu_index);
80+
THROW_CHECK_GT(gpu_indices.size(), 0);
81+
colmap::SetBestCudaDevice(gpu_indices[0]);
82+
}
83+
#else
84+
if (options_.use_gpu) {
85+
LOG_FIRST_N(WARNING, 1)
86+
<< "Requested to use GPU for bundle adjustment, but COLMAP was "
87+
"compiled without CUDA support. Falling back to CPU-based "
88+
"solvers.";
89+
}
90+
#endif // GLOMAP_CUDA_ENABLED
91+
3992
// Do not use the iterative solver, as it does not seem to be helpful
4093
options_.solver_options.linear_solver_type = ceres::SPARSE_SCHUR;
4194
options_.solver_options.preconditioner_type = ceres::CLUSTER_TRIDIAGONAL;

glomap/estimators/bundle_adjustment.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ struct BundleAdjusterOptions : public OptimizationBaseOptions {
1616
bool optimize_intrinsics = true;
1717
bool optimize_points = true;
1818

19+
bool use_gpu = true;
20+
std::string gpu_index = "-1";
21+
int min_num_images_gpu_solver = 300;
22+
1923
// Constrain the minimum number of views per track
2024
int min_num_view_per_track = 3;
2125

glomap/estimators/global_positioning.cc

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "glomap/estimators/global_positioning.h"
22

33
#include "glomap/estimators/cost_function.h"
4+
#include <colmap/util/cuda.h>
5+
#include <colmap/util/misc.h>
46

57
namespace glomap {
68
namespace {
@@ -361,6 +363,57 @@ void GlobalPositioner::ParameterizeVariables(
361363
}
362364
}
363365

366+
int num_images = images.size();
367+
#ifdef GLOMAP_CUDA_ENABLED
368+
bool cuda_solver_enabled = false;
369+
370+
#if (CERES_VERSION_MAJOR >= 3 || \
371+
(CERES_VERSION_MAJOR == 2 && CERES_VERSION_MINOR >= 2)) && \
372+
!defined(CERES_NO_CUDA)
373+
if (options_.use_gpu && num_images >= options_.min_num_images_gpu_solver) {
374+
cuda_solver_enabled = true;
375+
options_.solver_options.dense_linear_algebra_library_type = ceres::CUDA;
376+
}
377+
#else
378+
if (options_.use_gpu) {
379+
LOG_FIRST_N(WARNING, 1)
380+
<< "Requested to use GPU for bundle adjustment, but Ceres was "
381+
"compiled without CUDA support. Falling back to CPU-based dense "
382+
"solvers.";
383+
}
384+
#endif
385+
386+
#if (CERES_VERSION_MAJOR >= 3 || \
387+
(CERES_VERSION_MAJOR == 2 && CERES_VERSION_MINOR >= 3)) && \
388+
!defined(CERES_NO_CUDSS)
389+
if (options_.use_gpu && num_images >= options_.min_num_images_gpu_solver) {
390+
cuda_solver_enabled = true;
391+
options_.solver_options.sparse_linear_algebra_library_type =
392+
ceres::CUDA_SPARSE;
393+
}
394+
#else
395+
if (options_.use_gpu) {
396+
LOG_FIRST_N(WARNING, 1)
397+
<< "Requested to use GPU for bundle adjustment, but Ceres was "
398+
"compiled without cuDSS support. Falling back to CPU-based sparse "
399+
"solvers.";
400+
}
401+
#endif
402+
403+
if (cuda_solver_enabled) {
404+
const std::vector<int> gpu_indices = colmap::CSVToVector<int>(options_.gpu_index);
405+
THROW_CHECK_GT(gpu_indices.size(), 0);
406+
colmap::SetBestCudaDevice(gpu_indices[0]);
407+
}
408+
#else
409+
if (options_.use_gpu) {
410+
LOG_FIRST_N(WARNING, 1)
411+
<< "Requested to use GPU for bundle adjustment, but COLMAP was "
412+
"compiled without CUDA support. Falling back to CPU-based "
413+
"solvers.";
414+
}
415+
#endif // GLOMAP_CUDA_ENABLED
416+
364417
// Set up the options for the solver
365418
// Do not use iterative solvers, for its suboptimal performance.
366419
if (tracks.size() > 0) {

glomap/estimators/global_positioning.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ struct GlobalPositionerOptions : public OptimizationBaseOptions {
2929
bool optimize_points = true;
3030
bool optimize_scales = true;
3131

32+
bool use_gpu = true;
33+
std::string gpu_index = "-1";
34+
int min_num_images_gpu_solver = 1000;
35+
3236
// Constrain the minimum number of views per track
3337
int min_num_view_per_track = 3;
3438

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ int ShowHelp(
1212
std::cout << "GLOMAP -- Global Structure-from-Motion" << std::endl
1313
<< std::endl;
1414

15+
#ifdef GLOMAP_CUDA_ENABLED
16+
std::cout << "This version was compiled with CUDA!" << std::endl
17+
<< std::endl;
18+
#else
19+
std::cout << "This version was NOT compiled CUDA!" << std::endl
20+
<< std::endl;
21+
#endif
22+
1523
std::cout << "Usage:" << std::endl;
1624
std::cout << " glomap mapper --database_path DATABASE --output_path MODEL"
1725
<< std::endl;

0 commit comments

Comments
 (0)