diff --git a/doc/manual.tex b/doc/manual.tex index 371f06459e39f3f2b4fd5b020d9f4eca22821fd4..1d225225dfd2167f001dad0a02074af229e71160 100644 --- a/doc/manual.tex +++ b/doc/manual.tex @@ -746,7 +746,7 @@ flann::Matrix indices_gpu(gpu_pointer_indices,n_points, knn, stride); flann::Matrix dists_gpu(gpu_pointer_dists,n_points, knn, stride); flann::SearchParams params; -params["matrices_in_gpu_ram"]=true; +params.matrices_in_gpu_ram = true; flannindex.knnSearch( queries_gpu ,indices_gpu,dists_gpu,knn, params); \end{Verbatim} diff --git a/examples/queries.h b/examples/queries.h deleted file mode 100644 index e91d53830c64307ee1f6defe32662e82b68ef715..0000000000000000000000000000000000000000 --- a/examples/queries.h +++ /dev/null @@ -1,119 +0,0 @@ -/*********************************************************************** - * Software License Agreement (BSD License) - * - * Copyright 2008-2010 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. - * Copyright 2008-2010 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *************************************************************************/ - - -#ifndef QUERIES_H_ -#define QUERIES_H_ - -#include -#include -#include - - -namespace boost { -namespace serialization { - -template -void serialize(Archive & ar, flann::Matrix & matrix, const unsigned int version) -{ - ar & matrix.rows & matrix.cols & matrix.stride; - if (Archive::is_loading::value) { - matrix.data = new T[matrix.rows*matrix.cols]; - } - ar & boost::serialization::make_array(matrix.data, matrix.rows*matrix.cols); -} - -} -} - -namespace flann -{ - -template -struct Request -{ - flann::Matrix queries; - int nn; - int checks; - - template - void serialize(Archive& ar, const unsigned int version) - { - ar & queries & nn & checks; - } -}; - -template -struct Response -{ - flann::Matrix indices; - flann::Matrix dists; - - template - void serialize(Archive& ar, const unsigned int version) - { - ar & indices & dists; - } -}; - - -using boost::asio::ip::tcp; - -template -void read_object(tcp::socket& sock, T& val) -{ - uint32_t size; - boost::asio::read(sock, boost::asio::buffer(&size, sizeof(size))); - size = ntohl(size); - - boost::asio::streambuf archive_stream; - boost::asio::read(sock, archive_stream, boost::asio::transfer_at_least(size)); - - boost::archive::binary_iarchive archive(archive_stream); - archive >> val; -} - -template -void write_object(tcp::socket& sock, const T& val) -{ - boost::asio::streambuf archive_stream; - boost::archive::binary_oarchive archive(archive_stream); - archive << val; - - uint32_t size = archive_stream.size(); - size = htonl(size); - boost::asio::write(sock, boost::asio::buffer(&size, sizeof(size))); - boost::asio::write(sock, archive_stream); - -} - -} - - - -#endif /* QUERIES_H_ */ diff --git a/src/cpp/flann/algorithms/autotuned_index.h b/src/cpp/flann/algorithms/autotuned_index.h index 2760a4c7db797c4b87014db4bdce6a73b6d5eea7..39196363066a1edbf39c49b7c2bcb5f85c92d80c 100644 --- a/src/cpp/flann/algorithms/autotuned_index.h +++ b/src/cpp/flann/algorithms/autotuned_index.h @@ -123,7 +123,7 @@ public: { save_value(stream, (int)bestIndex_->getType()); bestIndex_->saveIndex(stream); - save_value(stream, get_param(bestSearchParams_, "checks")); + save_value(stream, bestSearchParams_.checks); } /** @@ -138,9 +138,7 @@ public: params["algorithm"] = (flann_algorithm_t)index_type; bestIndex_ = create_index_by_type(dataset_, params, distance_); bestIndex_->loadIndex(stream); - int checks; - load_value(stream, checks); - bestSearchParams_["checks"] = checks; + load_value(stream, bestSearchParams_.checks); } /** @@ -148,8 +146,7 @@ public: */ virtual void findNeighbors(ResultSet& result, const ElementType* vec, const SearchParams& searchParams) { - int checks = get_param(searchParams,"checks",(int)FLANN_CHECKS_AUTOTUNED); - if (checks == FLANN_CHECKS_AUTOTUNED) { + if (searchParams.checks == FLANN_CHECKS_AUTOTUNED) { bestIndex_->findNeighbors(result, vec, bestSearchParams_); } else { @@ -540,7 +537,7 @@ private: } Logger::info("Required number of checks: %d \n", checks); - searchParams["checks"] = checks; + searchParams.checks = checks; speedup = linear / searchTime; diff --git a/src/cpp/flann/algorithms/hierarchical_clustering_index.h b/src/cpp/flann/algorithms/hierarchical_clustering_index.h index 8011da5ac33aec36c9e60c20ea8b742a64c657f1..fe65223847149d54a0083136f5a14fe55f56aabe 100644 --- a/src/cpp/flann/algorithms/hierarchical_clustering_index.h +++ b/src/cpp/flann/algorithms/hierarchical_clustering_index.h @@ -416,7 +416,7 @@ public: void findNeighbors(ResultSet& result, const ElementType* vec, const SearchParams& searchParams) { - int maxChecks = get_param(searchParams,"checks",32); + int maxChecks = searchParams.checks; // Priority queue storing intermediate branches in the best-bin-first search Heap* heap = new Heap(size_); diff --git a/src/cpp/flann/algorithms/kdtree_cuda_3d_index.cu b/src/cpp/flann/algorithms/kdtree_cuda_3d_index.cu index 7f6999fa2bc64500b926b5309e7a05583d369501..c1aad72701c54513e85e4a0228e5d78593e2088e 100644 --- a/src/cpp/flann/algorithms/kdtree_cuda_3d_index.cu +++ b/src/cpp/flann/algorithms/kdtree_cuda_3d_index.cu @@ -280,14 +280,14 @@ void KDTreeCuda3dIndex::knnSearchGpu(const Matrix& querie assert(int(indices.cols) >= knn); assert( dists.cols == indices.cols && dists.stride==indices.stride ); - bool matrices_on_gpu = get_param(params, "matrices_in_gpu_ram", false); + bool matrices_on_gpu = params.matrices_in_gpu_ram; int threadsPerBlock = 128; int blocksPerGrid=(queries.rows+threadsPerBlock-1)/threadsPerBlock; - float epsError = 1+get_param(params,"eps",0.0f); - bool sorted = get_param(params,"sorted",true); - bool use_heap = get_param(params,"use_heap",false); + float epsError = 1+params.eps; + bool sorted = params.sorted; + bool use_heap = params.use_heap; typename GpuDistance::type distance; // std::cout<<" search: "<::radiusSearchGpu(const Matrix& que // assert(indices.roasdfws >= queries.rows); // assert(dists.rows >= queries.rows); - int max_neighbors = get_param(params, "max_neighbors", -1); - bool sorted = get_param(params, "sorted", true); - bool use_heap = get_param(params, "use_heap", false); + int max_neighbors = params.max_neighbors; + bool sorted = params.sorted; + bool use_heap = params.use_heap; if (indices.size() < queries.rows ) indices.resize(queries.rows); if (dists.size() < queries.rows ) dists.resize(queries.rows); @@ -506,7 +506,7 @@ int KDTreeCuda3dIndex::radiusSearchGpu(const Matrix& que 1, thrust::raw_pointer_cast(&indicesDev[0]), thrust::raw_pointer_cast(&distsDev[0]), - queries.rows, flann::cuda::RadiusResultSet(radius,thrust::raw_pointer_cast(&countsDev[0]),get_param(params, "sorted", true)), distance); + queries.rows, flann::cuda::RadiusResultSet(radius,thrust::raw_pointer_cast(&countsDev[0]),params.sorted), distance); } else { if( use_heap ) { @@ -521,7 +521,7 @@ int KDTreeCuda3dIndex::radiusSearchGpu(const Matrix& que 1, thrust::raw_pointer_cast(&indicesDev[0]), thrust::raw_pointer_cast(&distsDev[0]), - queries.rows, flann::cuda::RadiusKnnResultSet(radius,max_neighbors, thrust::raw_pointer_cast(&countsDev[0]),get_param(params, "sorted", true)), distance); + queries.rows, flann::cuda::RadiusKnnResultSet(radius,max_neighbors, thrust::raw_pointer_cast(&countsDev[0]),params.sorted), distance); } else { KdTreeCudaPrivate::nearestKernel<<>> (thrust::raw_pointer_cast(&((*gpu_helper_->gpu_splits_)[0])), @@ -535,7 +535,7 @@ int KDTreeCuda3dIndex::radiusSearchGpu(const Matrix& que 1, thrust::raw_pointer_cast(&indicesDev[0]), thrust::raw_pointer_cast(&distsDev[0]), - queries.rows, flann::cuda::RadiusKnnResultSet(radius,max_neighbors, thrust::raw_pointer_cast(&countsDev[0]),get_param(params, "sorted", true)), distance); + queries.rows, flann::cuda::RadiusKnnResultSet(radius,max_neighbors, thrust::raw_pointer_cast(&countsDev[0]),params.sorted), distance); } } thrust::transform(indicesDev.begin(), indicesDev.end(), indicesDev.begin(), map_indices(thrust::raw_pointer_cast( &((*gpu_helper_->gpu_vind_))[0]) )); @@ -566,17 +566,17 @@ struct isNotMinusOne template< typename Distance> int KDTreeCuda3dIndex< Distance >::radiusSearchGpu(const Matrix& queries, Matrix& indices, Matrix& dists, float radius, const SearchParams& params) { - int max_neighbors = get_param(params, "max_neighbors", -1); + int max_neighbors = params.max_neighbors; assert(indices.rows >= queries.rows); assert(dists.rows >= queries.rows || max_neighbors==0 ); assert(indices.stride==dists.stride || max_neighbors==0 ); assert( indices.cols==indices.stride ); assert(dists.rows >= queries.rows || max_neighbors==0 ); - bool sorted = get_param(params, "sorted", true); - bool matrices_on_gpu = get_param(params, "matrices_in_gpu_ram", false); - float epsError = 1+get_param(params,"eps",0.0f); - bool use_heap = get_param(params,"use_heap",false); + bool sorted = params.sorted; + bool matrices_on_gpu = params.matrices_in_gpu_ram; + float epsError = 1+params.eps; + bool use_heap = params.use_heap; if( max_neighbors<0 ) max_neighbors=indices.cols; @@ -610,7 +610,6 @@ int KDTreeCuda3dIndex< Distance >::radiusSearchGpu(const Matrix& qu thrust::device_vector distsDev(queries.rows* max_neighbors); thrust::device_vector indicesDev(queries.rows* max_neighbors); - // bool sorted = get_param(params,"sorted",true); if( use_heap ) { KdTreeCudaPrivate::nearestKernel<<>> (thrust::raw_pointer_cast(&((*gpu_helper_->gpu_splits_)[0])), @@ -675,7 +674,6 @@ int KDTreeCuda3dIndex< Distance >::radiusSearchGpu(const Matrix& qu thrust::copy( indicesDev.begin(), indicesDev.end(), indices.ptr() ); return thrust::reduce(indicesDev.begin(), indicesDev.end() ); } - // bool sorted = get_param(params,"sorted",true); if( use_heap ) { KdTreeCudaPrivate::nearestKernel<<>> (thrust::raw_pointer_cast(&((*gpu_helper_->gpu_splits_)[0])), diff --git a/src/cpp/flann/algorithms/kdtree_cuda_3d_index.h b/src/cpp/flann/algorithms/kdtree_cuda_3d_index.h index f846a1879beacd343d372d3768a6ed4b3df33f58..413be4d4e32d16f7eba68d1a538010c3f4db0332 100644 --- a/src/cpp/flann/algorithms/kdtree_cuda_3d_index.h +++ b/src/cpp/flann/algorithms/kdtree_cuda_3d_index.h @@ -199,13 +199,7 @@ public: */ virtual int knnSearch(const Matrix& queries, Matrix& indices, Matrix& dists, size_t knn, const SearchParams& params) { - if( get_param(params,"use_cpu",false) ) { - throw FLANNException( "CPU search not supported!" ); - // return NNIndex::knnSearch(queries,indices, dists, knn, params); - } - else { - knnSearchGpu(queries,indices, dists, knn, params); - } + knnSearchGpu(queries,indices, dists, knn, params); return knn*queries.rows; // hack... } @@ -223,13 +217,7 @@ public: size_t knn, const SearchParams& params) { - if( get_param(params,"use_cpu",false) ) { - throw FLANNException( "CPU search not supported!" ); - // return NNIndex::knnSearch(queries,indices, dists, knn, params); - } - else { - knnSearchGpu(queries,indices, dists, knn, params); - } + knnSearchGpu(queries,indices, dists, knn, params); return knn*queries.rows; // hack... } @@ -268,25 +256,13 @@ public: virtual int radiusSearch(const Matrix& queries, Matrix& indices, Matrix& dists, float radius, const SearchParams& params) { - if( get_param(params,"use_cpu",false) ) { - throw FLANNException( "CPU search not supported!" ); - // return NNIndex::radiusSearch(queries,indices, dists, radius, params); - } - else { - return radiusSearchGpu(queries,indices, dists, radius, params); - } + return radiusSearchGpu(queries,indices, dists, radius, params); } virtual int radiusSearch(const Matrix& queries, std::vector< std::vector >& indices, std::vector >& dists, float radius, const SearchParams& params) { - if( get_param(params,"use_cpu",false) ) { - throw FLANNException( "CPU search not supported!" ); - return NNIndex::radiusSearch(queries,indices, dists, radius, params); - } - else { - return radiusSearchGpu(queries,indices, dists, radius, params); - } + return radiusSearchGpu(queries,indices, dists, radius, params); } int radiusSearchGpu(const Matrix& queries, Matrix& indices, Matrix& dists, diff --git a/src/cpp/flann/algorithms/kdtree_index.h b/src/cpp/flann/algorithms/kdtree_index.h index 84e059959ead9e78fc2a164ada244c88c52e85fa..be621388f6e6e8141cc3608fc3da34e348c1c5d6 100644 --- a/src/cpp/flann/algorithms/kdtree_index.h +++ b/src/cpp/flann/algorithms/kdtree_index.h @@ -199,8 +199,8 @@ public: */ void findNeighbors(ResultSet& result, const ElementType* vec, const SearchParams& searchParams) { - int maxChecks = get_param(searchParams,"checks", 32); - float epsError = 1+get_param(searchParams,"eps",0.0f); + int maxChecks = searchParams.checks; + float epsError = 1+searchParams.eps; if (maxChecks==FLANN_CHECKS_UNLIMITED) { getExactNeighbors(result, vec, epsError); diff --git a/src/cpp/flann/algorithms/kdtree_single_index.h b/src/cpp/flann/algorithms/kdtree_single_index.h index e6a137a2af058771ed02fd576834d002c007310e..561bd14896dddc17e0cbe37337c0d60063061428 100644 --- a/src/cpp/flann/algorithms/kdtree_single_index.h +++ b/src/cpp/flann/algorithms/kdtree_single_index.h @@ -213,7 +213,7 @@ public: */ void findNeighbors(ResultSet& result, const ElementType* vec, const SearchParams& searchParams) { - float epsError = 1+get_param(searchParams,"eps",0.0f); + float epsError = 1+searchParams.eps; std::vector dists(dim_,0); DistanceType distsq = computeInitialDistances(vec, dists); @@ -517,14 +517,13 @@ private: { /* If this is a leaf node, then do check and return. */ if ((node->child1 == NULL)&&(node->child2 == NULL)) { -// DistanceType worst_dist = result_set.worstDist(); + DistanceType worst_dist = result_set.worstDist(); for (int i=node->left; iright; ++i) { int index = reorder_ ? i : vind_[i]; - DistanceType dist = distance_(vec, data_[index], dim_); -// DistanceType dist = distance_(vec, data_[index], dim_, worst_dist); -// if (dist& result, const ElementType* vec, const SearchParams& searchParams) { - int maxChecks = get_param(searchParams,"checks",32); + int maxChecks = searchParams.checks; if (maxChecks==FLANN_CHECKS_UNLIMITED) { findExactNN(root_, result, vec); diff --git a/src/cpp/flann/algorithms/lsh_index.h b/src/cpp/flann/algorithms/lsh_index.h index 8b4142c89bf105e90aeba76b6768ae19a0ad1b5c..b875181fdf4e07cb717ab22d31d3218b7277699e 100644 --- a/src/cpp/flann/algorithms/lsh_index.h +++ b/src/cpp/flann/algorithms/lsh_index.h @@ -196,16 +196,14 @@ public: assert(dists.rows >= queries.rows); assert(indices.cols >= knn); assert(dists.cols >= knn); - bool sorted = get_param(params,"sorted",true); - bool use_heap = get_param(params,"use_heap",false); int count = 0; - if (use_heap) { + if (params.use_heap==True) { KNNUniqueResultSet resultSet(knn); for (size_t i = 0; i < queries.rows; i++) { resultSet.clear(); findNeighbors(resultSet, queries[i], params); - resultSet.copy(indices[i], dists[i], knn, sorted); + resultSet.copy(indices[i], dists[i], knn, params.sorted); count += resultSet.size(); } } @@ -214,7 +212,7 @@ public: for (size_t i = 0; i < queries.rows; i++) { resultSet.clear(); findNeighbors(resultSet, queries[i], params); - resultSet.copy(indices[i], dists[i], knn, sorted); + resultSet.copy(indices[i], dists[i], knn, params.sorted); count += resultSet.size(); } } @@ -237,13 +235,11 @@ public: const SearchParams& params) { assert(queries.cols == veclen()); - bool sorted = get_param(params,"sorted",true); - bool use_heap = get_param(params,"use_heap",false); if (indices.size() < queries.rows ) indices.resize(queries.rows); if (dists.size() < queries.rows ) dists.resize(queries.rows); int count = 0; - if (use_heap) { + if (params.use_heap==True) { KNNUniqueResultSet resultSet(knn); for (size_t i = 0; i < queries.rows; i++) { resultSet.clear(); @@ -251,7 +247,7 @@ public: size_t n = std::min(resultSet.size(), knn); indices[i].resize(n); dists[i].resize(n); - resultSet.copy(&indices[i][0], &dists[i][0], n, sorted); + resultSet.copy(&indices[i][0], &dists[i][0], n, params.sorted); count += n; } } @@ -263,7 +259,7 @@ public: size_t n = std::min(resultSet.size(), knn); indices[i].resize(n); dists[i].resize(n); - resultSet.copy(&indices[i][0], &dists[i][0], n, sorted); + resultSet.copy(&indices[i][0], &dists[i][0], n, params.sorted); count += n; } } diff --git a/src/cpp/flann/algorithms/nn_index.h b/src/cpp/flann/algorithms/nn_index.h index 28963267766c1b6378e833dcf99020fa1627f339..bf0333e7717656d86cd65f2c0d1c5012f60a036c 100644 --- a/src/cpp/flann/algorithms/nn_index.h +++ b/src/cpp/flann/algorithms/nn_index.h @@ -87,21 +87,19 @@ public: assert(dists.rows >= queries.rows); assert(indices.cols >= knn); assert(dists.cols >= knn); - bool sorted = get_param(params,"sorted",true); bool use_heap; - if (!has_param(params,"use_heap")) { + + if (params.use_heap==Undefined) { use_heap = (knn>KNN_HEAP_THRESHOLD)?true:false; } else { - use_heap = get_param(params,"use_heap",false); + use_heap = (params.use_heap==True)?true:false; } int count = 0; #ifdef TBB - int cores = get_param(params,"cores",1); - assert(cores >= 1 || cores == -1); // Check if we need to do multicore search or stick with single core FLANN (less overhead) - if(cores == 1) + if(params.cores == 1) { #endif if (use_heap) { @@ -109,7 +107,7 @@ public: for (size_t i = 0; i < queries.rows; i++) { resultSet.clear(); findNeighbors(resultSet, queries[i], params); - resultSet.copy(indices[i], dists[i], knn, sorted); + resultSet.copy(indices[i], dists[i], knn, params.sorted); count += resultSet.size(); } } @@ -118,7 +116,7 @@ public: for (size_t i = 0; i < queries.rows; i++) { resultSet.clear(); findNeighbors(resultSet, queries[i], params); - resultSet.copy(indices[i], dists[i], knn, sorted); + resultSet.copy(indices[i], dists[i], knn, params.sorted); count += resultSet.size(); } } @@ -127,7 +125,7 @@ public: else { // Initialise the task scheduler for the use of Intel TBB parallel constructs - tbb::task_scheduler_init task_sched(cores); + tbb::task_scheduler_init task_sched(params.cores); // Make an atomic integer count, such that we can keep track of amount of neighbors found tbb::atomic atomic_count; @@ -162,13 +160,12 @@ public: const SearchParams& params) { assert(queries.cols == veclen()); - bool sorted = get_param(params,"sorted",true); bool use_heap; - if (!has_param(params,"use_heap")) { + if (params.use_heap==Undefined) { use_heap = (knn>KNN_HEAP_THRESHOLD)?true:false; } else { - use_heap = get_param(params,"use_heap",false); + use_heap = (params.use_heap==True)?true:false; } if (indices.size() < queries.rows ) indices.resize(queries.rows); @@ -176,10 +173,8 @@ public: int count = 0; #ifdef TBB - int cores = get_param(params,"cores",1); - assert(cores >= 1 || cores == -1); // Check if we need to do multicore search or stick with single core FLANN (less overhead) - if(cores == 1) + if(params.cores == 1) { #endif if (use_heap) { @@ -190,7 +185,7 @@ public: size_t n = std::min(resultSet.size(), knn); indices[i].resize(n); dists[i].resize(n); - resultSet.copy(&indices[i][0], &dists[i][0], n, sorted); + resultSet.copy(&indices[i][0], &dists[i][0], n, params.sorted); count += n; } } @@ -202,7 +197,7 @@ public: size_t n = std::min(resultSet.size(), knn); indices[i].resize(n); dists[i].resize(n); - resultSet.copy(&indices[i][0], &dists[i][0], n, sorted); + resultSet.copy(&indices[i][0], &dists[i][0], n, params.sorted); count += n; } } @@ -211,7 +206,7 @@ public: else { // Initialise the task scheduler for the use of Intel TBB parallel constructs - tbb::task_scheduler_init task_sched(cores); + tbb::task_scheduler_init task_sched(params.cores); // Make an atomic integer count, such that we can keep track of amount of neighbors found tbb::atomic atomic_count; @@ -245,13 +240,15 @@ public: assert(queries.cols == veclen()); int count = 0; #ifdef TBB - int cores = get_param(params,"cores",1); - assert(cores >= 1 || cores == -1); // Check if we need to do multicore search or stick with single core FLANN (less overhead) - if(cores == 1) + if(params.cores == 1) { #endif - int max_neighbors = get_param(params, "max_neighbors", -1); + size_t num_neighbors = std::min(indices.cols, dists.cols); + int max_neighbors = params.max_neighbors; + if (max_neighbors<0) max_neighbors = num_neighbors; + else max_neighbors = std::min(max_neighbors,(int)num_neighbors); + if (max_neighbors==0) { CountRadiusResultSet resultSet(radius); for (size_t i = 0; i < queries.rows; i++) { @@ -261,13 +258,10 @@ public: } } else { - size_t num_neighbors = std::min(indices.cols, dists.cols); - bool sorted = get_param(params, "sorted", true); - bool has_max_neighbors = has_param(params,"max_neighbors"); // explicitly indicated to use unbounded radius result set // or we know there'll be enough room for resulting indices and dists - if (max_neighbors<0 && (has_max_neighbors || num_neighbors>=size())) { + if (params.max_neighbors<0 && (num_neighbors>=size())) { RadiusResultSet resultSet(radius); for (size_t i = 0; i < queries.rows; i++) { resultSet.clear(); @@ -275,7 +269,7 @@ public: size_t n = resultSet.size(); count += n; if (n>num_neighbors) n = num_neighbors; - resultSet.copy(indices[i], dists[i], n, sorted); + resultSet.copy(indices[i], dists[i], n, params.sorted); // mark the next element in the output buffers as unused if (n resultSet(radius, max_neighbors); for (size_t i = 0; i < queries.rows; i++) { @@ -293,7 +285,7 @@ public: size_t n = resultSet.size(); count += n; if ((int)n>max_neighbors) n = max_neighbors; - resultSet.copy(indices[i], dists[i], n, sorted); + resultSet.copy(indices[i], dists[i], n, params.sorted); // mark the next element in the output buffers as unused if (n atomic_count; @@ -330,15 +322,12 @@ public: assert(queries.cols == veclen()); int count = 0; #ifdef TBB - int cores = get_param(params,"cores",1); - assert(cores >= 1 || cores == -1); // Check if we need to do multicore search or stick with single core FLANN (less overhead) - if(cores == 1) + if(params.cores == 1) { #endif - int max_neighbors = get_param(params, "max_neighbors", -1); // just count neighbors - if (max_neighbors==0) { + if (params.max_neighbors==0) { CountRadiusResultSet resultSet(radius); for (size_t i = 0; i < queries.rows; i++) { resultSet.clear(); @@ -347,11 +336,10 @@ public: } } else { - bool sorted = get_param(params, "sorted", true); if (indices.size() < queries.rows ) indices.resize(queries.rows); if (dists.size() < queries.rows ) dists.resize(queries.rows); - if (max_neighbors<0) { + if (params.max_neighbors<0) { // search for all neighbors RadiusResultSet resultSet(radius); for (size_t i = 0; i < queries.rows; i++) { @@ -361,21 +349,21 @@ public: count += n; indices[i].resize(n); dists[i].resize(n); - resultSet.copy(&indices[i][0], &dists[i][0], n, sorted); + resultSet.copy(&indices[i][0], &dists[i][0], n, params.sorted); } } else { // number of neighbors limited to max_neighbors - KNNRadiusResultSet resultSet(radius, max_neighbors); + KNNRadiusResultSet resultSet(radius, params.max_neighbors); for (size_t i = 0; i < queries.rows; i++) { resultSet.clear(); findNeighbors(resultSet, queries[i], params); size_t n = resultSet.size(); count += n; - if ((int)n>max_neighbors) n = max_neighbors; + if ((int)n>params.max_neighbors) n = params.max_neighbors; indices[i].resize(n); dists[i].resize(n); - resultSet.copy(&indices[i][0], &dists[i][0], n, sorted); + resultSet.copy(&indices[i][0], &dists[i][0], n, params.sorted); } } } @@ -384,7 +372,7 @@ public: else { // Initialise the task scheduler for the use of Intel TBB parallel constructs - tbb::task_scheduler_init task_sched(cores); + tbb::task_scheduler_init task_sched(params.cores); // Reset atomic count before passing it on to the threads, such that we can keep track of amount of neighbors found tbb::atomic atomic_count; diff --git a/src/cpp/flann/flann.cpp b/src/cpp/flann/flann.cpp index 1618428569282abf85a253076adf0b3a3488f416..b2ba2f8d23f3b2d8ad7c8500b4cf648c7cf66544 100644 --- a/src/cpp/flann/flann.cpp +++ b/src/cpp/flann/flann.cpp @@ -149,7 +149,7 @@ flann_index_t __flann_build_index(typename Distance::ElementType* dataset, int r if (index->getType()==FLANN_INDEX_AUTOTUNED) { AutotunedIndex* autotuned_index = (AutotunedIndex*)index->getIndex(); // FIXME - flann_params->checks = get_param(autotuned_index->getSearchParameters(),"checks"); + flann_params->checks = autotuned_index->getSearchParameters().checks; *speedup = autotuned_index->getSpeedup(); } diff --git a/src/cpp/flann/flann.hpp b/src/cpp/flann/flann.hpp index ae8c41d25a21ba9d5e80dc22e548d824c162b541..b3297778d6db75426a8c3075094f589f2a0ff116 100644 --- a/src/cpp/flann/flann.hpp +++ b/src/cpp/flann/flann.hpp @@ -64,7 +64,7 @@ struct SavedIndexParams : public IndexParams { SavedIndexParams(std::string filename) { - (* this)["algorithm"] = FLANN_INDEX_SAVED; + (*this)["algorithm"] = FLANN_INDEX_SAVED; (*this)["filename"] = filename; } }; @@ -98,7 +98,7 @@ NNIndex* load_saved_index(const Matrix template -class Index : public NNIndex +class Index { public: typedef typename Distance::ElementType ElementType; @@ -277,14 +277,6 @@ public: return nnIndex_->radiusSearch(queries, indices, dists, radius, params); } - /** - * \brief Method that searches for nearest-neighbours - */ - void findNeighbors(ResultSet& result, const ElementType* vec, const SearchParams& searchParams) - { - nnIndex_->findNeighbors(result, vec, searchParams); - } - /** * \brief Returns actual index */ diff --git a/src/cpp/flann/mpi/client.h b/src/cpp/flann/mpi/client.h index de4c41af6c04a5f90add9d85a2e9ce50889f9971..0c8d5fe431d67838f2e3677fb342ae7d5bef6fc1 100644 --- a/src/cpp/flann/mpi/client.h +++ b/src/cpp/flann/mpi/client.h @@ -59,7 +59,7 @@ public: Request req; req.nn = knn; req.queries = queries; - req.checks = get_param(params,"checks"); + req.checks = params.checks; // send request write_object(sock,req); diff --git a/src/cpp/flann/tbb/bodies.hpp b/src/cpp/flann/tbb/bodies.hpp index 7f3083619bdac14975fdbc094625cc12a2dc6d03..992aae91fbc854b72a9b31461a6e192fe9681267 100644 --- a/src/cpp/flann/tbb/bodies.hpp +++ b/src/cpp/flann/tbb/bodies.hpp @@ -79,17 +79,14 @@ public: */ void operator()( const tbb::blocked_range& r ) const { - bool sorted = get_param(params_,"sorted",true); - bool use_heap = get_param(params_,"use_heap",false); - - if (use_heap) + if (params_.use_heap==True) { KNNResultSet2 resultSet(knn_); for (size_t i=r.begin(); i!=r.end(); ++i) { resultSet.clear(); nnIndex_->findNeighbors(resultSet, queries_[i], params_); - resultSet.copy(indices_[i], distances_[i], knn_, sorted); + resultSet.copy(indices_[i], distances_[i], knn_, params_.sorted); count_ += resultSet.size(); } } @@ -100,7 +97,7 @@ public: { resultSet.clear(); nnIndex_->findNeighbors(resultSet, queries_[i], params_); - resultSet.copy(indices_[i], distances_[i], knn_, sorted); + resultSet.copy(indices_[i], distances_[i], knn_, params_.sorted); count_ += resultSet.size(); } } @@ -172,10 +169,7 @@ public: */ void operator()( const tbb::blocked_range& r ) const { - bool sorted = get_param(params_,"sorted",true); - bool use_heap = get_param(params_,"use_heap",false); - - if (use_heap) { + if (params_.use_heap==True) { KNNResultSet2 resultSet(knn_); for (size_t i=r.begin(); i!=r.end(); ++i) { @@ -184,7 +178,7 @@ public: size_t n = std::min(resultSet.size(), knn_); indices_[i].resize(n); distances_[i].resize(n); - resultSet.copy(&indices_[i][0], &distances_[i][0], n, sorted); + resultSet.copy(&indices_[i][0], &distances_[i][0], n, params_.sorted); count_ += n; } } @@ -197,7 +191,7 @@ public: size_t n = std::min(resultSet.size(), knn_); indices_[i].resize(n); distances_[i].resize(n); - resultSet.copy(&indices_[i][0], &distances_[i][0], n, sorted); + resultSet.copy(&indices_[i][0], &distances_[i][0], n, params_.sorted); count_ += n; } } @@ -269,7 +263,10 @@ public: void operator()( const tbb::blocked_range& r ) const { - int max_neighbors = get_param(params_, "max_neighbors", -1); + size_t num_neighbors = std::min(indices_.cols, distances_.cols); + int max_neighbors = params_.max_neighbors; + if (max_neighbors<0) max_neighbors = num_neighbors; + else max_neighbors = std::min(max_neighbors,(int)num_neighbors); if (max_neighbors==0) { CountRadiusResultSet resultSet(radius_); @@ -281,13 +278,10 @@ public: } } else { - size_t num_neighbors = std::min(indices_.cols, distances_.cols); - bool sorted = get_param(params_, "sorted", true); - bool has_max_neighbors = has_param(params_,"max_neighbors"); // explicitly indicated to use unbounded radius result set // or we know there'll be enough room for resulting indices and dists - if (max_neighbors<0 && (has_max_neighbors || num_neighbors>=nnIndex_->size())) { + if (params_.max_neighbors<0 && (num_neighbors>=nnIndex_->size())) { RadiusResultSet resultSet(radius_); for (size_t i=r.begin(); i!=r.end(); ++i) { @@ -296,7 +290,7 @@ public: size_t n = resultSet.size(); count_ += n; if (n>num_neighbors) n = num_neighbors; - resultSet.copy(indices_[i], distances_[i], n, sorted); + resultSet.copy(indices_[i], distances_[i], n, params_.sorted); // mark the next element in the output buffers as unused if (n resultSet(radius_, max_neighbors); for (size_t i=r.begin(); i!=r.end(); ++i) @@ -315,7 +307,7 @@ public: size_t n = resultSet.size(); count_ += n ; if ((int)n>max_neighbors) n = max_neighbors; - resultSet.copy(indices_[i], distances_[i], n, sorted); + resultSet.copy(indices_[i], distances_[i], n, params_.sorted); // mark the next element in the output buffers as unused if (n& r ) const { - int max_neighbors = get_param(params_, "max_neighbors", -1); - + int max_neighbors = params_.max_neighbors; // just count neighbors if (max_neighbors==0) { CountRadiusResultSet resultSet(radius_); @@ -404,7 +395,6 @@ public: } } else { - bool sorted = get_param(params_, "sorted", true); if (indices_.size() < queries_.rows ) indices_.resize(queries_.rows); if (distances_.size() < queries_.rows ) distances_.resize(queries_.rows); @@ -419,12 +409,12 @@ public: count_ += n; indices_[i].resize(n); distances_[i].resize(n); - resultSet.copy(&indices_[i][0], &distances_[i][0], n, sorted); + resultSet.copy(&indices_[i][0], &distances_[i][0], n, params_.sorted); } } else { // number of neighbors limited to max_neighbors - KNNRadiusResultSet resultSet(radius_, max_neighbors); + KNNRadiusResultSet resultSet(radius_, params_.max_neighbors); for (size_t i=r.begin(); i!=r.end(); ++i) { resultSet.clear(); @@ -434,7 +424,7 @@ public: if ((int)n>max_neighbors) n = max_neighbors; indices_[i].resize(n); distances_[i].resize(n); - resultSet.copy(&indices_[i][0], &distances_[i][0], n, sorted); + resultSet.copy(&indices_[i][0], &distances_[i][0], n, params_.sorted); } } } diff --git a/src/cpp/flann/util/params.h b/src/cpp/flann/util/params.h index 67155f98adc5c673bb3646fa9a69cc32f89e4b85..99d3e92e182705fe799aea7ba47c7482fa9faab4 100644 --- a/src/cpp/flann/util/params.h +++ b/src/cpp/flann/util/params.h @@ -41,21 +41,39 @@ namespace flann typedef std::map IndexParams; -struct SearchParams : public IndexParams -{ - SearchParams(int checks = 32, float eps = 0, bool sorted = true, int cores = 1 ) +typedef enum { + False = 0, + True = 1, + Undefined +} tri_type; + +struct SearchParams +{ + SearchParams(int checks_ = 32, float eps_ = 0.0, bool sorted_ = true ) : + checks(checks_), eps(eps_), sorted(sorted_) { - // how many leafs to visit when searching for neighbours (-1 for unlimited) - (*this)["checks"] = checks; - // search for eps-approximate neighbours (default: 0) - (*this)["eps"] = eps; - // only for radius search, require neighbours sorted by distance (default: true) - (*this)["sorted"] = sorted; - // how many cores to assign to the search - // this parameter will be ignored if Intel TBB isn't available on the system or no "TBB" macro is defined - (*this)["cores"] = cores; + max_neighbors = -1; + use_heap = Undefined; + cores = 1; + matrices_in_gpu_ram = false; } + + // how many leafs to visit when searching for neighbours (-1 for unlimited) + int checks; + // search for eps-approximate neighbours (default: 0) + float eps; + // only for radius search, require neighbours sorted by distance (default: true) + bool sorted; + // maximum number of neighbors radius search should return (-1 for unlimited) + int max_neighbors; + // use a heap to manage the result set (default: Undefined) + tri_type use_heap; + // how many cores to assign to the search + // this parameter will be ignored if Intel TBB isn't available on the system or no "TBB" macro is defined + int cores; + // for GPU search indicates if matrices are already in GPU ram + bool matrices_in_gpu_ram; }; @@ -97,6 +115,13 @@ inline void print_params(const IndexParams& params) } } +inline void print_params(const SearchParams& params) +{ + std::cout << "checks : " << params.checks << std::endl; + std::cout << "eps : " << params.eps << std::endl; + std::cout << "sorted : " << params.sorted << std::endl; + std::cout << "max_neighbors : " << params.max_neighbors << std::endl; +} } diff --git a/src/cpp/flann/util/result_set.h b/src/cpp/flann/util/result_set.h index bd48f13ea5d6b38ee6610c1788039c8d605775d0..505597ca84f55ea8562e396747c93953bd0deadd 100644 --- a/src/cpp/flann/util/result_set.h +++ b/src/cpp/flann/util/result_set.h @@ -200,7 +200,6 @@ private: std::vector dist_index_; }; - /** * K-Nearest neighbour result set. Ensures that the elements inserted are unique */ diff --git a/test/flann_multithreaded_test.cpp b/test/flann_multithreaded_test.cpp index 0dced63f210bcfffbbdcbd0ae2dca958ef0b8796..1104ad7c069229911515a619b57a533af802cfaf 100644 --- a/test/flann_multithreaded_test.cpp +++ b/test/flann_multithreaded_test.cpp @@ -100,7 +100,9 @@ TEST_F(FlannTest, HandlesSingleCoreSearch) int cores = 1; start_timer("Searching KNN..."); - index.knnSearch(query, indices, dists, GetNN(), flann::SearchParams(checks,eps,sorted,cores)); + SearchParams params(checks,eps,sorted); + params.cores = cores; + index.knnSearch(query, indices, dists, GetNN(), params); printf("done (%g seconds)\n", stop_timer()); float precision = compute_precision(match, indices); @@ -121,7 +123,9 @@ TEST_F(FlannTest, HandlesMultiCoreSearch) int cores = 2; start_timer("Searching KNN..."); - index.knnSearch(query, indices, dists, GetNN(), flann::SearchParams(checks,eps,sorted,cores)); + SearchParams params(checks,eps,sorted); + params.cores = cores; + index.knnSearch(query, indices, dists, GetNN(), params); printf("done (%g seconds)\n", stop_timer()); float precision = compute_precision(match, indices); @@ -187,11 +191,14 @@ TEST_F(FlannCompareKnnTest, CompareMultiSingleCoreKnnSearchSorted) int multi_core = -1; start_timer("Searching KNN (single core)..."); - int single_neighbor_count = index.knnSearch(query, indices_single, dists_single, GetNN(), flann::SearchParams(checks,eps,sorted,single_core)); + SearchParams params(checks,eps,sorted); + params.cores = single_core; + int single_neighbor_count = index.knnSearch(query, indices_single, dists_single, GetNN(), params); printf("done (%g seconds)\n", stop_timer()); start_timer("Searching KNN (multi core)..."); - int multi_neighbor_count = index.knnSearch(query, indices_multi, dists_multi, GetNN(), flann::SearchParams(checks,eps,sorted,multi_core)); + params.cores = multi_core; + int multi_neighbor_count = index.knnSearch(query, indices_multi, dists_multi, GetNN(), params); printf("done (%g seconds)\n", stop_timer()); EXPECT_EQ(single_neighbor_count, multi_neighbor_count); @@ -215,11 +222,14 @@ TEST_F(FlannCompareKnnTest, CompareMultiSingleCoreKnnSearchUnsorted) int multi_core = -1; start_timer("Searching KNN (single core)..."); - int single_neighbor_count = index.knnSearch(query, indices_single, dists_single, GetNN(), flann::SearchParams(checks,eps,sorted,single_core)); + SearchParams params(checks,eps,sorted); + params.cores = single_core; + int single_neighbor_count = index.knnSearch(query, indices_single, dists_single, GetNN(), params); printf("done (%g seconds)\n", stop_timer()); start_timer("Searching KNN (multi core)..."); - int multi_neighbor_count = index.knnSearch(query, indices_multi, dists_multi, GetNN(), flann::SearchParams(checks,eps,sorted,multi_core)); + params.cores = multi_core; + int multi_neighbor_count = index.knnSearch(query, indices_multi, dists_multi, GetNN(), params); printf("done (%g seconds)\n", stop_timer()); EXPECT_EQ(single_neighbor_count, multi_neighbor_count); @@ -293,11 +303,14 @@ TEST_F(FlannCompareRadiusTest, CompareMultiSingleCoreRadiusSearchSorted) int multi_core = -1; start_timer("Searching Radius (single core)..."); - int single_neighbor_count = index.radiusSearch(query, indices_single, dists_single, GetRadius(), flann::SearchParams(checks,eps,sorted,single_core)); + SearchParams params(checks,eps,sorted); + params.cores = single_core; + int single_neighbor_count = index.radiusSearch(query, indices_single, dists_single, GetRadius(), params); printf("done (%g seconds)\n", stop_timer()); start_timer("Searching Radius (multi core)..."); - int multi_neighbor_count = index.radiusSearch(query, indices_multi, dists_multi, GetRadius(), flann::SearchParams(checks,eps,sorted,multi_core)); + params.cores = multi_core; + int multi_neighbor_count = index.radiusSearch(query, indices_multi, dists_multi, GetRadius(), params); printf("done (%g seconds)\n", stop_timer()); EXPECT_EQ(single_neighbor_count, multi_neighbor_count); @@ -321,11 +334,14 @@ TEST_F(FlannCompareRadiusTest, CompareMultiSingleCoreRadiusSearchUnsorted) int multi_core = -1; start_timer("Searching Radius (single core)..."); - int single_neighbor_count = index.radiusSearch(query, indices_single, dists_single, GetRadius(), flann::SearchParams(checks,eps,sorted,single_core)); + SearchParams params(checks,eps,sorted); + params.cores = single_core; + int single_neighbor_count = index.radiusSearch(query, indices_single, dists_single, GetRadius(), params); printf("done (%g seconds)\n", stop_timer()); start_timer("Searching Radius (multi core)..."); - int multi_neighbor_count = index.radiusSearch(query, indices_multi, dists_multi, GetRadius(), flann::SearchParams(checks,eps,sorted,multi_core)); + params.cores = multi_core; + int multi_neighbor_count = index.radiusSearch(query, indices_multi, dists_multi, GetRadius(), params); printf("done (%g seconds)\n", stop_timer()); EXPECT_EQ(single_neighbor_count, multi_neighbor_count);