Skip to content

Commit

Permalink
Merge pull request #81 from andrew-hardin/feature/remove-boost-from-core
Browse files Browse the repository at this point in the history
Remove boost from core popsift library
  • Loading branch information
simogasp authored Apr 20, 2020
2 parents bf3556f + 249bbca commit 149de05
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 49 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,5 @@ oxford
# Temporary files
.DS_Store

# Downloaded archives for tests.
*.tgz
18 changes: 3 additions & 15 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,10 @@ option(PopSift_USE_POSITION_INDEPENDENT_CODE "Generate position independent code
option(PopSift_USE_GRID_FILTER "Switch off grid filtering to massively reduce compile time while debugging other things." ON)
option(PopSift_USE_NORMF "The __normf function computes Euclidian distance on large arrays. Fast but stability is uncertain." OFF)
option(PopSift_USE_TEST_CMD "Add testing step for functional verification" OFF)
option(PopSift_BOOST_USE_STATIC_LIBS "Link with static Boost libraries" OFF)
option(PopSift_NVCC_WARNINGS "Switch on several additional warning for CUDA nvcc" OFF)
option(BUILD_SHARED_LIBS "Build shared libraries" ON)


if(PopSift_BOOST_USE_STATIC_LIBS)
set(Boost_USE_STATIC_LIBS ON)
endif()

if(PopSift_USE_POSITION_INDEPENDENT_CODE)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
endif()
Expand Down Expand Up @@ -52,16 +47,6 @@ set(CMAKE_CUDA_STANDARD_REQUIRED ON)
include(GNUInstallDirs)


#################
# BOOST
#################
find_package(Boost 1.53.0 REQUIRED COMPONENTS system thread)
if(WIN32)
add_definitions("-DBOOST_ALL_NO_LIB")
link_directories(Boost_LIBRARRY_DIR_DEBUG)
link_directories(Boost_LIBRARRY_DIR_RELEASE)
endif(WIN32)

if(BUILD_SHARED_LIBS)
message(STATUS "BUILD_SHARED_LIBS ON")
# Need to declare CUDA_USE_STATIC_CUDA_RUNTIME as an option to ensure that it is not overwritten in FindCUDA.
Expand All @@ -77,6 +62,9 @@ else()
set(CUDA_USE_STATIC_CUDA_RUNTIME ON)
endif()

# Require threads because of std::thread.
find_package(Threads REQUIRED)

###################
# CUDA
###################
Expand Down
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

# PopSift
# PopSift

[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/3728/badge)](https://bestpractices.coreinfrastructure.org/projects/3728) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/8b0f7a68bc0d4df2ac89c6e732917caa)](https://app.codacy.com/manual/alicevision/popsift?utm_source=github.com&utm_medium=referral&utm_content=alicevision/popsift&utm_campaign=Badge_Grade_Settings)

Expand All @@ -15,12 +15,12 @@ PopSift compiles and works with NVidia cards of compute capability >= 3.0 (inclu

PopSift depends on:

* Boost >= 1.55 (required components {atomic, chrono, date-time, system, thread}-dev)

* CUDA >= 7.0

Optionally, for the provided applications:

* Boost >= 1.55 (required components {atomic, chrono, date-time, system, thread}-dev)

* DevIL (libdevil-dev) can be used to load a broader range of image formats, otherwise only pgm is supported.

## Build
Expand All @@ -41,7 +41,7 @@ Some build options are available:
* `BUILD_SHARED_LIBS` (default: `ON`) controls the type of library to build (`ON` for shared libraries, `OFF` for static)


### Continuous integration:
### Continuous integration:
- [![Build Status](https://travis-ci.org/alicevision/popsift.svg?branch=master)](https://travis-ci.org/alicevision/popsift) master branch.
- [![Build Status](https://travis-ci.org/alicevision/popsift.svg?branch=develop)](https://travis-ci.org/alicevision/popsift) develop branch.
- [![Build status](https://ci.appveyor.com/api/projects/status/rsm5269hs288c2ji/branch/develop?svg=true)](https://ci.appveyor.com/project/AliceVision/popsift/branch/develop)
Expand All @@ -57,12 +57,12 @@ Calling `popsift-demo` without parameters shows the options.

### Using PopSift as third party

To integrate PopSift into other software, link with `libpopsift`.
If your are using CMake for building your project you can easily add PopSift to your project.
To integrate PopSift into other software, link with `libpopsift`.
If your are using CMake for building your project you can easily add PopSift to your project.
Once you have built and installed PopSift in a directory (say, `<prefix>`), in your `CMakeLists.txt` file just add the dependency

```cmake
# Find the package from the PopSiftConfig.cmake
# Find the package from the PopSiftConfig.cmake
# in <prefix>/lib/cmake/PopSift/. Under the namespace PopSift::
# it exposes the target popsift that allows you to compile
# and link with the library
Expand All @@ -86,23 +86,23 @@ cmake .. -DPopSift_DIR=<prefix>/lib/cmake/PopSift/

The caller must create a `popart::Config` struct (documented in `src/sift/sift_conf.h`) to control the behaviour of the PopSift, and instantiate an object of class `PopSift` (found in `src/sift/popsift.h`).

After this, images can be enqueued for SIFT extraction using (`enqueue()`).
After this, images can be enqueued for SIFT extraction using (`enqueue()`).
A valid input is a single plane of grayscale values located in host memory.
They can passed as a pointer to unsigned char, with a value range from 0 to 255, or as a pointer to float, with a value range from 0.0f to 1.0f.

Only host memory limits the number of images that can be enqueued.
Only host memory limits the number of images that can be enqueued.
The `enqueue` function returns a pointer to a `SiftJob` immediately and performs the feature extraction asynchronously.
The memory of the image passed to enqueue remains the caller's responsibility. Calling `SiftJob::get` on the returned job blocks until features are extracted, and returns them.

Features offer iterators that iterate over objects of type `Feature`.
Both classes are documented in `sift_extremum.h`.
Features offer iterators that iterate over objects of type `Feature`.
Both classes are documented in `sift_extremum.h`.
Each feature represents a feature point in the coordinate system of the input image, providing X and Y coordinates and scale (sigma), as well as several alternative descriptors for the feature point (according to Lowe, 15% of the feature points should be expected to have 2 or more descriptors).

In an alternate, deprecated, blocking API, `init()` must be called to pass image width and height to PopSift, followed by a call to `executed()` that takes image data and returns the extracted features. `execute()` is synchronous and blocking.

As far as we know, no implementation that is faster than PopSift at the time of PopSift's release comes under a license that allows commercial use and sticks close to the original paper at the same time as well.
PopSift can be configured at runtime to use constants that affect it behaviours.
In particular, users can choose to generate results very similar to VLFeat or results that are closer (but not as close) to the SIFT implementation of the OpenCV extras.
As far as we know, no implementation that is faster than PopSift at the time of PopSift's release comes under a license that allows commercial use and sticks close to the original paper at the same time as well.
PopSift can be configured at runtime to use constants that affect it behaviours.
In particular, users can choose to generate results very similar to VLFeat or results that are closer (but not as close) to the SIFT implementation of the OpenCV extras.
We acknowledge that there is at least one SIFT implementation that is vastly faster, but it makes considerable sacrifices in terms of accuracy and compatibility.


Expand Down Expand Up @@ -131,7 +131,7 @@ If you use PopSift for your publication, please cite us as:
acmid = {3208136},
publisher = {ACM},
address = {New York, NY, USA},
}
}
```


Expand Down
4 changes: 3 additions & 1 deletion cmake/Config.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@
#
################################################################################


@PACKAGE_INIT@

include(CMakeFindDependencyMacro)
find_dependency(Threads REQUIRED)

include("${CMAKE_CURRENT_LIST_DIR}/@popsift_targets_export_name@.cmake")
check_required_components("@PROJECT_NAME@")
6 changes: 3 additions & 3 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,12 @@ set(popsift_generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated")

# BUILD_INTERFACE allows to include the directory with source only when target is
# built in the building tree (ie, not from an install location)
target_include_directories(popsift
target_include_directories(popsift
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>
$<BUILD_INTERFACE:${popsift_generated_dir}>
$<BUILD_INTERFACE:${popsift_generated_dir}/popsift>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/>
${Boost_INCLUDE_DIRS}
${CUDA_INCLUDE_DIRS})


Expand All @@ -60,7 +59,8 @@ set_target_properties(popsift PROPERTIES DEBUG_POSTFIX "d")

# cannot use PRIVATE here as there is a bug in FindCUDA and CUDA_ADD_LIBRARY
# https://gitlab.kitware.com/cmake/cmake/issues/16097
target_link_libraries(popsift ${Boost_LIBRARIES} ${CUDA_CUDADEVRT_LIBRARY} ${CUDA_CUBLAS_LIBRARIES})
target_link_libraries(popsift ${CUDA_CUDADEVRT_LIBRARY} ${CUDA_CUBLAS_LIBRARIES} Threads::Threads)



# EXPORTING THE LIBRARY
Expand Down
12 changes: 9 additions & 3 deletions src/application/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
cmake_minimum_required(VERSION 3.12)
project(PopsiftDemo LANGUAGES CXX)

OPTION(PopSift_BOOST_USE_STATIC_LIBS "Link examples with static Boost libraries" OFF)

if(TARGET popsift)
# when compiled in the repository the target is already defined
add_library(PopSift::popsift ALIAS popsift)
Expand All @@ -15,9 +17,13 @@ endif()

find_package(DevIL COMPONENTS IL ILU) # yields IL_FOUND, IL_LIBRARIES, IL_INCLUDE_DIR

set(Boost_INCLUDE_DIRS "")
set(Boost_LIBRARIES "")
find_package(Boost 1.53.0 REQUIRED COMPONENTS filesystem program_options)
if(PopSift_BOOST_USE_STATIC_LIBS)
set(Boost_USE_STATIC_LIBS ON)
endif()
find_package(Boost 1.53.0 REQUIRED COMPONENTS filesystem program_options system)
if(WIN32)
add_definitions("-DBOOST_ALL_NO_LIB")
endif(WIN32)

set(PD_INCLUDE_DIRS ${Boost_INCLUDE_DIRS})
set(PD_LINK_LIBS ${Boost_LIBRARIES} ${CUDA_CUDADEVRT_LIBRARY})
Expand Down
56 changes: 56 additions & 0 deletions src/popsift/common/sync_queue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#pragma once

#include <condition_variable>
#include <mutex>
#include <queue>

namespace popsift {

/**
* @brief A thread safe wrapper around std::queue (replaces boost::sync_queue).
* @tparam T the value type that's stored in the queue.
*/
template<typename T>
class SyncQueue {
public:
SyncQueue() = default;

/**
* @brief Push an item onto the queue and signal it's available.
* @param[in] value the item to add to the queue.
*/
void push(const T& value) {
std::unique_lock<std::mutex> lock(mtx_);
items_.push(value);
lock.unlock();
signal_.notify_one();
}

/**
* @brief Check if the queue is empty - thread safety via mutex.
* @return True if the queue is empty.
*/
bool empty() {
std::unique_lock<std::mutex> lock(mtx_);
return items_.empty();
}

/**
* @brief Pull an item off the queue, or, wait until one arrives. Blocking.
* @return The front item that was popped off the queue.
*/
T pull() {
std::unique_lock<std::mutex> lock(mtx_);
signal_.wait(lock, [this] { return !items_.empty(); });
auto ans = items_.front();
items_.pop();
return ans;
}

private:
std::mutex mtx_;
std::queue<T> items_;
std::condition_variable signal_;
};

} // namespace popsift
12 changes: 7 additions & 5 deletions src/popsift/popsift.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <cmath>
#include <cstring>
#include <fstream>

#include "popsift.h"
Expand All @@ -30,11 +32,11 @@ PopSift::PopSift( const popsift::Config& config, popsift::Config::ProcessingMode

configure( config, true );

_pipe._thread_stage1.reset( new boost::thread( &PopSift::uploadImages, this ));
_pipe._thread_stage1.reset( new std::thread( &PopSift::uploadImages, this ));
if( mode == popsift::Config::ExtractingMode )
_pipe._thread_stage2.reset( new boost::thread( &PopSift::extractDownloadLoop, this ));
_pipe._thread_stage2.reset( new std::thread( &PopSift::extractDownloadLoop, this ));
else
_pipe._thread_stage2.reset( new boost::thread( &PopSift::matchPrepareLoop, this ));
_pipe._thread_stage2.reset( new std::thread( &PopSift::matchPrepareLoop, this ));
}

PopSift::PopSift( ImageMode imode )
Expand All @@ -51,8 +53,8 @@ PopSift::PopSift( ImageMode imode )
_pipe._unused.push( new popsift::ImageFloat );
}

_pipe._thread_stage1.reset( new boost::thread( &PopSift::uploadImages, this ));
_pipe._thread_stage2.reset( new boost::thread( &PopSift::extractDownloadLoop, this ));
_pipe._thread_stage1.reset( new std::thread( &PopSift::uploadImages, this ));
_pipe._thread_stage2.reset( new std::thread( &PopSift::extractDownloadLoop, this ));
}

PopSift::~PopSift()
Expand Down
14 changes: 7 additions & 7 deletions src/popsift/popsift.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
#include <stack>
#include <queue>
#include <future>
#include <boost/thread/thread.hpp>
#include <boost/thread/sync_queue.hpp>
#include <thread>

#include "common/sync_queue.h"
#include "sift_conf.h"
#include "sift_extremum.h"
#include "sift_config.h"
Expand Down Expand Up @@ -75,11 +75,11 @@ class PopSift
{
struct Pipe
{
std::unique_ptr<boost::thread> _thread_stage1;
std::unique_ptr<boost::thread> _thread_stage2;
boost::sync_queue<SiftJob*> _queue_stage1;
boost::sync_queue<SiftJob*> _queue_stage2;
boost::sync_queue<popsift::ImageBase*> _unused;
std::unique_ptr<std::thread> _thread_stage1;
std::unique_ptr<std::thread> _thread_stage2;
popsift::SyncQueue<SiftJob*> _queue_stage1;
popsift::SyncQueue<SiftJob*> _queue_stage2;
popsift::SyncQueue<popsift::ImageBase*> _unused;

popsift::Pyramid* _pyramid{nullptr};

Expand Down

0 comments on commit 149de05

Please sign in to comment.