Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

port to c++11 #89

Merged
merged 3 commits into from
May 14, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,6 @@ else ()
set (CMAKE_CXX_STANDARD 11)
endif ()

# Boost required for any and cstdint on MSVC < 2010
find_package(Boost COMPONENTS REQUIRED)
if(MSVC AND (MSVC_VERSION LESS 1600))
add_definitions(-DBOOST_STDINT)
endif(MSVC AND (MSVC_VERSION LESS 1600))

# openmp
set(USE_OPEN_MP TRUE CACHE BOOL "Set to FALSE to not use OpenMP")
if (USE_OPEN_MP)
Expand Down Expand Up @@ -143,7 +137,7 @@ else (USE_OPEN_CL)
endif (USE_OPEN_CL)

# include all libs so far
include_directories(${CMAKE_SOURCE_DIR} ${EIGEN_INCLUDE_DIR} ${Boost_INCLUDE_DIRS})
include_directories(${CMAKE_SOURCE_DIR} ${EIGEN_INCLUDE_DIR})

# main nabo lib
set(NABO_SRC
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ On the average, libnabo is 5% to 20% faster than [ANN].

libnabo depends on [Eigen], a modern C++ matrix and linear-algebra library.
libnabo works with either version 2 or 3 of Eigen.
libnabo also depends on [Boost], a C++ general library.
libnabo also optionally depends on [Boost], a C++ general library, for Python bindings.

libnabo was developed by [Stéphane Magnenat](http://stephane.magnenat.net) as part of his work at [ASL-ETH](http://www.asl.ethz.ch) and is now maintained by [Simon Lynen](https://github.com/simonlynen).

Expand All @@ -30,7 +30,7 @@ You will find a nice introductory tutorial in [this video](http://www.youtube.co
Prerequisites
-------------

If your operating system does not provide it, you must get [Eigen] and [Boost].
If your operating system does not provide it, you must get [Eigen], and [Boost] if you want to build the Python bindings.
[Eigen] only needs to be downloaded and extracted.
You also need `grep`, which is available in standard on Linux or Mac OS X, you can get the window version [here](http://gnuwin32.sourceforge.net/packages/grep.htm).

Expand Down
6 changes: 3 additions & 3 deletions debian/control
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Source: libnabo
Priority: extra
Maintainer: Stéphane Magnenat <stephane@nospam.magnenat.net>
Build-Depends: debhelper (>= 7.0.50~), cmake, doxygen, cdbs, libboost-dev, libboost-python-dev, libeigen3-dev, python-dev, python-numpy
Build-Depends: debhelper (>= 7.0.50~), cmake, doxygen, cdbs, libboost-python-dev, libeigen3-dev, python-dev, python-numpy
Standards-Version: 3.9.1
Section: libs
Homepage: https://github.com/ethz-asl/libnabo
Expand All @@ -11,7 +11,7 @@ Vcs-Browser: https://github.com/ethz-asl/libnabo
Package: libnabo-dev
Section: libdevel
Architecture: any
Depends: libnabo1 (= ${binary:Version}), libboost-dev, libeigen3-dev
Depends: libnabo1 (= ${binary:Version}), libeigen3-dev
Suggests: libnabo-doc
Description: Development headers of libnabo, a fast K Nearset Neighbor library.
libnabo is a fast K Nearest Neighbour library for low-dimensional spaces.
Expand Down Expand Up @@ -62,4 +62,4 @@ Description: Python bindings for libnabo, a fast K Nearset Neighbor library.
It provides a clean, legacy-free, scalar-type–agnostic API thanks to C++
templates. Its current CPU implementation is strongly inspired by ANN,
but with more compact data types. On the average, libnabo is 5% to 20%
faster than ANN.
faster than ANN.
4 changes: 2 additions & 2 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
include_directories(..)

add_executable(trivial trivial.cpp)
target_link_libraries(trivial ${LIB_NAME} ${EXTRA_LIBS} ${Boost_LIBRARIES})
target_link_libraries(trivial ${LIB_NAME} ${EXTRA_LIBS})

add_executable(usage usage.cpp)
target_link_libraries(usage ${LIB_NAME} ${EXTRA_LIBS} ${Boost_LIBRARIES})
target_link_libraries(usage ${LIB_NAME} ${EXTRA_LIBS})
2 changes: 0 additions & 2 deletions experimental/kdtree_cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <limits>
#include <queue>
#include <algorithm>
#include <boost/numeric/conversion/bounds.hpp>
#include <boost/limits.hpp>

namespace Nabo
{
Expand Down
13 changes: 6 additions & 7 deletions nabo/kdtree_cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <queue>
#include <algorithm>
#include <utility>
#include <boost/numeric/conversion/bounds.hpp>
#include <boost/limits.hpp>
#include <boost/format.hpp>
#ifdef HAVE_OPENMP
#include <omp.h>
#endif
Expand Down Expand Up @@ -96,8 +93,8 @@ namespace Nabo
template<typename T, typename Heap, typename CloudType>
pair<T,T> KDTreeUnbalancedPtInLeavesImplicitBoundsStackOpt<T, Heap, CloudType>::getBounds(const BuildPointsIt first, const BuildPointsIt last, const unsigned dim)
{
T minVal(boost::numeric::bounds<T>::highest());
T maxVal(boost::numeric::bounds<T>::lowest());
T minVal(std::numeric_limits<T>::max());
T maxVal(std::numeric_limits<T>::lowest());

for (BuildPointsCstIt it(first); it != last; ++it)
{
Expand Down Expand Up @@ -235,7 +232,7 @@ namespace Nabo
dimMask((1<<dimBitCount)-1)
{
if (bucketSize < 2)
throw runtime_error((boost::format("Requested bucket size %1%, but must be larger than 2") % bucketSize).str());
throw runtime_error("Requested bucket size " + std::to_string(bucketSize) + ", but must be larger than 2");
if (cloud.cols() <= bucketSize)
{
// make a single-bucket tree
Expand All @@ -249,7 +246,8 @@ namespace Nabo
const uint64_t estimatedNodeCount(cloud.cols() / (bucketSize / 2));
if (estimatedNodeCount > maxNodeCount)
{
throw runtime_error((boost::format("Cloud has a risk to have more nodes (%1%) than the kd-tree allows (%2%). The kd-tree has %3% bits for dimensions and %4% bits for node indices") % estimatedNodeCount % maxNodeCount % dimBitCount % (32-dimBitCount)).str());
throw runtime_error("Cloud has a risk to have more nodes (" + std::to_string(estimatedNodeCount) + ") than the kd-tree allows (" + std::to_string(maxNodeCount) + "). "
"The kd-tree has " + std::to_string(dimBitCount) + " bits for dimensions and " + std::to_string((32-dimBitCount)) + " bits for node indices");
}

// build point vector and compute bounds
Expand Down Expand Up @@ -465,3 +463,4 @@ namespace Nabo

//@}
}
/* vim: set ts=8 sw=8 tw=0 noexpandtab cindent softtabstop=8 :*/
15 changes: 6 additions & 9 deletions nabo/kdtree_opencl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <queue>
#include <algorithm>
// #include <map>
#include <boost/numeric/conversion/bounds.hpp>
#include <boost/limits.hpp>
#include <boost/format.hpp>
#include <boost/thread.hpp>


/*! \file kdtree_opencl.cpp
Expand Down Expand Up @@ -203,7 +199,7 @@ namespace Nabo
//! Create a new contexc for a given type of device
cl::Context& createContext(const cl_device_type deviceType)
{
boost::mutex::scoped_lock lock(mutex);
std::lock_guard lock(mutex);
Devices::iterator it(devices.find(deviceType));
if (it == devices.end())
{
Expand All @@ -216,7 +212,7 @@ namespace Nabo
//! Return the cache for a given type of device
SourceCacher* getSourceCacher(const cl_device_type deviceType)
{
boost::mutex::scoped_lock lock(mutex);
std::lock_guard lock(mutex);
Devices::iterator it(devices.find(deviceType));
if (it == devices.end())
throw runtime_error("Attempt to get source cacher before creating a context");
Expand All @@ -225,7 +221,7 @@ namespace Nabo

protected:
Devices devices; //!< devices with caches
boost::mutex mutex; //!< mutex to protect concurrent accesses to devices
std::mutex mutex; //!< mutex to protect concurrent accesses to devices
};

//! Static instance of context manager
Expand Down Expand Up @@ -545,7 +541,7 @@ namespace Nabo
const unsigned maxStackDepth(getTreeDepth(nodes.size()) + 1);

// init openCL
initOpenCL("knn_kdtree_pt_in_leaves.cl", "knnKDTree", (boost::format("#define MAX_STACK_DEPTH %1%\n") % maxStackDepth).str());
initOpenCL("knn_kdtree_pt_in_leaves.cl", "knnKDTree", "#define MAX_STACK_DEPTH " + std::to_string(maxStackDepth) + "\n");

// map nodes, for info about alignment, see sect 6.1.5
const size_t nodesCLSize(nodes.size() * sizeof(Node));
Expand Down Expand Up @@ -672,7 +668,7 @@ namespace Nabo
const unsigned maxStackDepth(getTreeDepth(nodes.size()) + 1);

// init openCL
initOpenCL("knn_kdtree_pt_in_nodes.cl", "knnKDTree", (boost::format("#define MAX_STACK_DEPTH %1%\n") % maxStackDepth).str());
initOpenCL("knn_kdtree_pt_in_nodes.cl", "knnKDTree", "#define MAX_STACK_DEPTH " + std::to_string(maxStackDepth) + "\n");

// map nodes, for info about alignment, see sect 6.1.5
const size_t nodesCLSize(nodes.size() * sizeof(Node));
Expand All @@ -694,3 +690,4 @@ namespace Nabo
}

#endif // HAVE_OPENCL
/* vim: set ts=8 sw=8 tw=0 noexpandtab cindent softtabstop=8 :*/
4 changes: 1 addition & 3 deletions nabo/nabo.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ On the average, libnabo is 5% to 20% faster than \ref ANN.

libnabo depends on \ref Eigen, a modern C++ matrix and linear-algebra library.
libnabo works with either version 2 or 3 of Eigen.
libnabo also depends on \ref Boost, a C++ general library.

\section Compilation

Expand Down Expand Up @@ -192,14 +191,13 @@ libnabo differs from \ref ANN on the following points:

* performances
- about 5% to 20% faster than ANN (both -O3 -NDEBUG), probably due to the smaller memory footprint
- clearly memory-bound, neither OpenMP nor boost::thread improve performances
- clearly memory-bound, neither OpenMP nor std::thread improve performances

\section References

\li \anchor Eigen Eigen: http://eigen.tuxfamily.org
\li \anchor ANN ANN: http://www.cs.umd.edu/~mount/ANN
\li \anchor CMake CMake: http://www.cmake.org
\li \anchor Boost Boost: http://www.boost.org

*/

Expand Down
8 changes: 2 additions & 6 deletions nabo/nabo_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "nabo.h"

#ifdef BOOST_STDINT
#include <boost/cstdint.hpp>
using boost::uint32_t;
#else // BOOST_STDINT
#include <stdint.h>
#endif // BOOST_STDINT
#include <cstdint>
using std::uint32_t;

// OpenCL
#ifdef HAVE_OPENCL
Expand Down
17 changes: 6 additions & 11 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ include (CheckSymbolExists)
include_directories(..)

add_executable(knnvalidate knnvalidate.cpp)
target_link_libraries(knnvalidate ${LIB_NAME} ${EXTRA_LIBS} ${Boost_LIBRARIES})
# disable as experimental is broken target_link_libraries(knnvalidate naboexperimental nabo ${EXTRA_LIBS} ${Boost_LIBRARIES})
target_link_libraries(knnvalidate ${LIB_NAME} ${EXTRA_LIBS})
# disable as experimental is broken target_link_libraries(knnvalidate naboexperimental nabo ${EXTRA_LIBS})

add_test(validation-2D-exhaustive ${EXECUTABLE_OUTPUT_PATH}/knnvalidate ${CMAKE_CURRENT_SOURCE_DIR}/data/scan.2d.txt 10 2 -1)
add_test(validation-2D-random ${EXECUTABLE_OUTPUT_PATH}/knnvalidate ${CMAKE_CURRENT_SOURCE_DIR}/data/scan.2d.txt 10 2 10000)
Expand Down Expand Up @@ -51,16 +51,11 @@ else (FLANN_INCLUDE_DIR AND FLANN_LIBRARY)
message("FLANN not found, disabling it in benchmarks")
endif (FLANN_INCLUDE_DIR AND FLANN_LIBRARY)

check_symbol_exists(_POSIX_TIMERS "unistd.h;time.h" POSIX_TIMERS)
if (POSIX_TIMERS AND NOT APPLE)
set(EXTRA_LIBS ${EXTRA_LIBS} rt)
endif (POSIX_TIMERS AND NOT APPLE)

include_directories(..)

add_executable(knnbench knnbench.cpp)
target_link_libraries(knnbench ${LIB_NAME} ${EXTRA_LIBS} ${Boost_LIBRARIES})
# disable as experimental is broken target_link_libraries(knnbench naboexperimental nabo ${EXTRA_LIBS} ${Boost_LIBRARIES})
target_link_libraries(knnbench ${LIB_NAME} ${EXTRA_LIBS})
# disable as experimental is broken target_link_libraries(knnbench naboexperimental nabo ${EXTRA_LIBS})

add_test(bench-3D-large-exhaustive-10000-K1 ${EXECUTABLE_OUTPUT_PATH}/knnbench ${CMAKE_CURRENT_SOURCE_DIR}/data/scan.3d.large.txt 1 -10000 3 5)
add_test(bench-3D-large-exhaustive-1000-K1 ${EXECUTABLE_OUTPUT_PATH}/knnbench ${CMAKE_CURRENT_SOURCE_DIR}/data/scan.3d.large.txt 1 -1000 3 5)
Expand All @@ -76,10 +71,10 @@ add_test(bench-3D-large-exhaustive-100-K30 ${EXECUTABLE_OUTPUT_PATH}/knnbench ${
add_test(bench-3D-large-random-K30 ${EXECUTABLE_OUTPUT_PATH}/knnbench ${CMAKE_CURRENT_SOURCE_DIR}/data/scan.3d.large.txt 30 40000 3 5)

add_executable(knnepsilon knnepsilon.cpp)
target_link_libraries(knnepsilon ${LIB_NAME} ${EXTRA_LIBS} ${Boost_LIBRARIES})
target_link_libraries(knnepsilon ${LIB_NAME} ${EXTRA_LIBS})

add_executable(knnbucketsize knnbucketsize.cpp)
target_link_libraries(knnbucketsize ${LIB_NAME} ${EXTRA_LIBS} ${Boost_LIBRARIES})
target_link_libraries(knnbucketsize ${LIB_NAME} ${EXTRA_LIBS})

# Ensure that users cannot instantiate a tree with wrong matrix types.
macro(try_compile_cloud_types MAT_TYPE TREE_TYPE EXPECT)
Expand Down
69 changes: 15 additions & 54 deletions tests/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <iostream>
#include <fstream>

#ifdef BOOST_STDINT
#include <boost/cstdint.hpp>
using boost::uint64_t;
#else // BOOST_STDINT
#include <stdint.h>
#endif // BOOST_STDINT
#include <cstdint>
using std::uint64_t;

using namespace std;
using namespace Nabo;
Expand Down Expand Up @@ -129,55 +125,20 @@ typename NearestNeighbourSearch<T>::Matrix createQuery(const typename NearestNei
return q;
}

#ifdef __MACH__
#include <mach/clock.h>
#include <mach/mach.h>
#else
#include <time.h>
#endif

#ifdef _POSIX_TIMERS
namespace boost
#include <chrono>
using std::chrono::high_resolution_clock;
using std::chrono::duration_cast;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather use explicit scoping or function level using below.

struct timer
{
/*
High-precision timer class, using gettimeofday().
The interface is a subset of the one boost::timer provides,
but the implementation is much more precise
on systems where clock() has low precision, such as glibc.
*/
struct timer
{
typedef uint64_t Time;

timer():_start_time(curTime()){ }
void restart() { _start_time = curTime(); }
double elapsed() const // return elapsed time in seconds
{ return double(curTime() - _start_time) / double(1000000000); }

private:
Time curTime() const {
#ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time
clock_serv_t cclock;
mach_timespec_t ts;
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
clock_get_time(cclock, &ts);
mach_port_deallocate(mach_task_self(), cclock);
#else
struct timespec ts;
#ifdef CLOCK_PROCESS_CPUTIME_ID
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
#else // BSD and old Linux
clock_gettime(CLOCK_PROF, &ts);
#endif
#endif
return Time(ts.tv_sec) * Time(1000000000) + Time(ts.tv_nsec);
}
Time _start_time;
};
}
#else // _POSIX_TIMERS
#include <boost/timer.hpp>
#endif // _POSIX_TIMERS
timer():_start_time(high_resolution_clock::now()){ }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd make high_resolution_clock::now() a private static function, e.g. curTime like before to deduplicate the three occurrences.

void restart() { _start_time = high_resolution_clock::now(); }
double elapsed() const // return elapsed time in seconds
{ return duration_cast<chrono::nanoseconds>(high_resolution_clock::now() - _start_time).count() / double(1000000000); }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be possible to write this more concise as

return duration_cast<duration<double>>(high_resolution_clock::now() - _start_time).count();


private:
high_resolution_clock::time_point _start_time;
};

#endif // __NABE_TEST_HELPERS_H

/* vim: set ts=8 sw=8 tw=0 noexpandtab cindent softtabstop=8 :*/
Loading