42 #include "flann/flann.hpp"
106 void operator /=(
const double factor)
108 creationDuration /= factor;
109 executionDuration /= factor;
110 visitCount /= factor;
111 totalCount /= factor;
136 const unsigned creationOptionFlags,
141 const int searchCount)
149 nnsT*
nns(nnsT::create(d, d.rows(), type, creationOptionFlags));
152 for (
int s = 0; s < searchCount; ++s)
155 IndexMatrix indices(K,
q.cols());
156 Matrix dists2(K,
q.cols());
157 const unsigned long visitCount =
nns->knn(
q, indices, dists2, K, 0, 0);
166 result.
totalCount = double(
q.cols()) * double(d.cols());
177 const int ptCount(d.cols());
178 const double **pa =
new const double *[d.cols()];
179 for (
int i = 0; i < ptCount; ++i)
180 pa[i] = &d.coeff(0, i);
181 ANNkd_tree* ann_kdt =
new ANNkd_tree(
const_cast<double**
>(pa), ptCount, d.rows(), 8);
184 for (
int s = 0; s < searchCount; ++s)
189 for (
int i = 0; i < itCount; ++i)
192 ANNpoint queryPt(
const_cast<double*
>(&tq.coeff(0)));
211 const int ptCount(d.cols());
212 const double **pa =
new const double *[d.cols()];
213 for (
int i = 0; i < ptCount; ++i)
214 pa[i] = &d.coeff(0, i);
215 ANNkd_tree* ann_kdt =
new ANNkd_tree(
const_cast<double**
>(pa), ptCount, d.rows(), 8);
218 for (
int s = 0; s < searchCount; ++s)
223 for (
int i = 0; i < itCount; ++i)
226 ANNpoint queryPt(
const_cast<double*
>(&tq.coeff(0)));
227 ann_kdt->annkPriSearch(
246 BenchResult doBenchFLANN(
const Matrix& d,
const Matrix&
q,
const Index K,
const int itCount)
249 const int dimCount(d.rows());
250 const int dPtCount(d.cols());
251 const int qPtCount(itCount);
253 flann::Matrix<T> dataset(
new T[dPtCount*dimCount], dPtCount, dimCount);
254 for (
int point = 0; point < dPtCount; ++point)
255 for (
int dim = 0; dim < dimCount; ++dim)
256 dataset[point][dim] = d(dim, point);
257 flann::Matrix<T> query(
new T[qPtCount*dimCount], qPtCount, dimCount);
258 for (
int point = 0; point < qPtCount; ++point)
259 for (
int dim = 0; dim < dimCount; ++dim)
260 query[point][dim] =
q(dim, point);
262 flann::Matrix<int> indices(
new int[query.rows*K], query.rows, K);
263 flann::Matrix<float> dists(
new float[query.rows*K], query.rows, K);
267 flann::Index<T> index(dataset, flann::KDTreeIndexParams(4) );
273 index.knnSearch(query, indices, dists,
int(K), flann::SearchParams(128));
287 int main(
int argc,
char* argv[])
291 cerr <<
"Usage " << argv[0] <<
" DATA K METHOD RUN_COUNT SEARCH_COUNT" << endl;
295 const MatrixD dD(load<double>(argv[1]));
296 const MatrixF dF(load<float>(argv[1]));
297 const int K(atoi(argv[2]));
298 const int method(atoi(argv[3]));
299 const int itCount(method >= 0 ? method : dD.cols() * 2);
300 const int runCount(atoi(argv[4]));
301 const int searchCount(atoi(argv[5]));
306 cerr <<
"Requested more nearest neighbour than points in the data set" << endl;
311 MatrixD qD(createQuery<double>(dD, itCount, method));
312 MatrixF qF(createQuery<float>(dF, itCount, method));
314 const char* benchLabels[] =
322 "Nabo, double, unbalanced, stack, pt in leaves only, implicit bounds, ANN_KD_SL_MIDPT, brute-force vector heap, opt",
323 "Nabo, double, unbalanced, stack, pt in leaves only, implicit bounds, ANN_KD_SL_MIDPT, STL heap, opt",
324 "Nabo, float, unbalanced, stack, pt in leaves only, implicit bounds, ANN_KD_SL_MIDPT, brute-force vector heap, opt",
325 "Nabo, float, unbalanced, stack, pt in leaves only, implicit bounds, ANN_KD_SL_MIDPT, STL heap, opt",
326 "Nabo, float, unbalanced, stack, pt in leaves only, implicit bounds, ANN_KD_SL_MIDPT, STL heap, opt, stats",
328 "Nabo, float, OpenCL, GPU, balanced, points in nodes, stack, implicit bounds, balance aspect ratio, stats",
329 "Nabo, float, OpenCL, GPU, balanced, points in leaves, stack, implicit bounds, balance aspect ratio, stats",
331 #endif // HAVE_OPENCL
344 size_t benchCount(
sizeof(benchLabels) /
sizeof(
const char *));
345 cout <<
"Doing " << benchCount <<
" different benches " << runCount <<
" times, with " << searchCount <<
" query per run" << endl;
347 for (
int run = 0; run < runCount; ++run)
356 results.at(i++) += doBenchType<double>(NNSearchD::KDTREE_LINEAR_HEAP, 0, dD, qD, K, itCount, searchCount);
357 results.at(i++) += doBenchType<double>(NNSearchD::KDTREE_TREE_HEAP, 0, dD, qD, K, itCount, searchCount);
358 results.at(i++) += doBenchType<float>(NNSearchF::KDTREE_LINEAR_HEAP, 0, dF, qF, K, itCount, searchCount);
359 results.at(i++) += doBenchType<float>(NNSearchF::KDTREE_TREE_HEAP, 0, dF, qF, K, itCount, searchCount);
360 results.at(i++) += doBenchType<float>(NNSearchF::KDTREE_TREE_HEAP, NNSearchF::TOUCH_STATISTICS, dF, qF, K, itCount, searchCount);
362 results.at(i++) += doBenchType<float>(NNSearchF::KDTREE_CL_PT_IN_NODES, NNSearchF::TOUCH_STATISTICS, dF, qF, K, itCount, searchCount);
363 results.at(i++) += doBenchType<float>(NNSearchF::KDTREE_CL_PT_IN_LEAVES, NNSearchF::TOUCH_STATISTICS, dF, qF, K, itCount, searchCount);
365 #endif // HAVE_OPENCL
367 results.at(i++) += doBenchANNStack(dD, qD, K, itCount, searchCount);
371 results.at(i++) += doBenchFLANN<double>(dD, qD, K, itCount, searchCount);
372 results.at(i++) += doBenchFLANN<float>(dF, qF, K, itCount, searchCount);
377 cout <<
"Showing average over " << runCount <<
" runs\n\n";
378 for (
size_t i = 0; i < benchCount; ++i)
380 results[i] /= double(runCount);
381 cout <<
"Method " << benchLabels[i] <<
":\n";
382 cout <<
" creation duration: " << results[i].creationDuration <<
"\n";
383 cout <<
" execution duration: " << results[i].executionDuration <<
"\n";
384 if (results[i].totalCount != 0)
386 cout <<
" visit count: " << results[i].visitCount <<
"\n";
387 cout <<
" total count: " << results[i].totalCount <<
"\n";
388 cout <<
" precentage visit: " << (results[i].visitCount * 100.) / results[i].totalCount <<
"\n";
391 cout <<
" no stats for visits\n";