| 1261 | } |
| 1262 | |
| 1263 | static std::unique_ptr<FeatureMatcher> Create( |
| 1264 | const FeatureMatchingOptions& options) { |
| 1265 | // SiftGPU uses many global static state variables and the initialization |
| 1266 | // must be thread-safe in order to work correctly. This is enforced here. |
| 1267 | static std::mutex mutex; |
| 1268 | std::lock_guard<std::mutex> lock(mutex); |
| 1269 | |
| 1270 | const std::vector<int> gpu_indices = CSVToVector<int>(options.gpu_index); |
| 1271 | THROW_CHECK_EQ(gpu_indices.size(), 1) << "SiftGPU can only run on one GPU"; |
| 1272 | |
| 1273 | SiftGPU sift_gpu; |
| 1274 | sift_gpu.SetVerbose(0); |
| 1275 | |
| 1276 | auto matcher = std::make_unique<SiftGPUFeatureMatcher>(options); |
| 1277 | |
| 1278 | // Note that the SiftMatchGPU object is not movable (for whatever reason). |
| 1279 | // If we instead create the object here and move it to the constructor, the |
| 1280 | // program segfaults inside SiftMatchGPU. |
| 1281 | |
| 1282 | matcher->sift_match_gpu_ = SiftMatchGPU(options.max_num_matches); |
| 1283 | |
| 1284 | #if defined(COLMAP_CUDA_ENABLED) |
| 1285 | if (gpu_indices[0] >= 0) { |
| 1286 | matcher->sift_match_gpu_.SetLanguage( |
| 1287 | SiftMatchGPU::SIFTMATCH_CUDA_DEVICE0 + gpu_indices[0]); |
| 1288 | } else { |
| 1289 | matcher->sift_match_gpu_.SetLanguage(SiftMatchGPU::SIFTMATCH_CUDA); |
| 1290 | } |
| 1291 | matcher->backend_ = SiftBackend::CUDA; |
| 1292 | #else // COLMAP_CUDA_ENABLED |
| 1293 | matcher->sift_match_gpu_.SetLanguage(SiftMatchGPU::SIFTMATCH_GLSL); |
| 1294 | matcher->backend_ = SiftBackend::GLSL; |
| 1295 | #endif // COLMAP_CUDA_ENABLED |
| 1296 | |
| 1297 | if (matcher->sift_match_gpu_.VerifyContextGL() == 0) { |
| 1298 | return nullptr; |
| 1299 | } |
| 1300 | |
| 1301 | if (!matcher->sift_match_gpu_.Allocate(options.max_num_matches, |
| 1302 | options.sift->cross_check)) { |
| 1303 | LOG(ERROR) << StringPrintf( |
| 1304 | "Not enough GPU memory to match %d features. " |
| 1305 | "Reduce the maximum number of matches.", |
| 1306 | options.max_num_matches); |
| 1307 | return nullptr; |
| 1308 | } |
| 1309 | |
| 1310 | #if !defined(COLMAP_CUDA_ENABLED) |
| 1311 | if (matcher->sift_match_gpu_.GetMaxSift() < options.max_num_matches) { |
| 1312 | LOG(WARNING) << StringPrintf( |
| 1313 | "OpenGL version of SiftGPU only supports a " |
| 1314 | "maximum of %d matches - consider changing to CUDA-based " |
| 1315 | "feature matching to avoid this limitation.", |
| 1316 | matcher->sift_match_gpu_.GetMaxSift()); |
| 1317 | } |
| 1318 | #endif // COLMAP_CUDA_ENABLED |
| 1319 | |
| 1320 | matcher->sift_match_gpu_.gpu_index = gpu_indices[0]; |
nothing calls this directly
no test coverage detected