ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
result_set.h
Go to the documentation of this file.
1 /**********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright 2011 Andreas Muetzel (amuetzel@uni-koblenz.de). All rights reserved.
5  *
6  * THE BSD LICENSE
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *************************************************************************/
29 #ifndef FLANN_UTIL_CUDA_RESULTSET_H
30 #define FLANN_UTIL_CUDA_RESULTSET_H
31 
32 #include <FLANN/util/cuda/heap.h>
33 #include <limits>
34 
35 __device__ __forceinline__
36 float infinity()
37 {
38  return __int_as_float(0x7f800000);
39 }
40 
41 #ifndef INFINITY
42 #define INFINITY infinity()
43 #endif
44 
45 namespace flann
46 {
47 namespace cuda
48 {
50 template< typename DistanceType >
52 {
53  int bestIndex;
54  DistanceType bestDist;
55  const DistanceType epsError;
56 
57  __device__ __host__
58  SingleResultSet( DistanceType eps ) : bestIndex(-1),bestDist(INFINITY), epsError(eps){ }
59 
60  __device__
61  inline float
63  {
64  return bestDist;
65  }
66 
67  __device__
68  inline void
69  insert(int index, DistanceType dist)
70  {
71  if( dist <= bestDist ) {
72  bestIndex=index;
73  bestDist=dist;
74  }
75  }
76 
77  DistanceType* resultDist;
79 
80  __device__
81  inline void
82  setResultLocation( DistanceType* dists, int* index, int thread, int stride )
83  {
84  resultDist=dists+thread*stride;
85  resultIndex=index+thread*stride;
86  if( stride != 1 ) {
87  for( int i=1; i<stride; i++ ) {
89  resultIndex[i]=-1;
90  }
91  }
92  }
93 
94  __device__
95  inline void
97  {
100  }
101 };
102 
103 template< typename DistanceType >
105 {
106  __device__
107  bool operator()(DistanceType a, DistanceType b)
108  {
109  return a>b;
110  }
111 };
112 
113 
114 // using this and the template uses 2 or 3 registers more than the direct implementation in the kNearestKernel, but
115 // there is no speed difference.
116 // Setting useHeap as a template parameter leads to a whole lot of things being
117 // optimized away by nvcc.
118 // Register counts are the same as when removing not-needed variables in explicit specializations
119 // and the "if( useHeap )" branches are eliminated at compile time.
120 // The downside of this: a bit more complex kernel launch code.
121 template< typename DistanceType, bool useHeap >
123 {
125  DistanceType largestHeapDist;
127  const int k;
128  const bool sorted;
129  const DistanceType epsError;
130 
131 
132  __device__ __host__
133  KnnResultSet(int knn, bool sortResults, DistanceType eps) : foundNeighbors(0),largestHeapDist(INFINITY),k(knn), sorted(sortResults), epsError(eps){ }
134 
135  // __host__ __device__
136  // KnnResultSet(const KnnResultSet& o):foundNeighbors(o.foundNeighbors),largestHeapDist(o.largestHeapDist),k(o.k){ }
137 
138  __device__
139  inline DistanceType
141  {
142  return largestHeapDist;
143  }
144 
145  __device__
146  inline void
147  insert(int index, DistanceType dist)
148  {
149  if( foundNeighbors<k ) {
152  if( foundNeighbors==k-1) {
153  if( useHeap ) {
156  }
157  else {
159  }
160 
161  }
162  foundNeighbors++;
163  }
164  else if( dist < largestHeapDist ) {
165  if( useHeap ) {
166  resultDist[0]=dist;
167  resultIndex[0]=index;
170  }
171  else {
173  resultIndex[maxDistIndex]=index;
175  }
176 
177  }
178  }
179 
180  __device__
181  void
183  {
185  maxDistIndex=0;
186  for( int i=1; i<k; i++ )
187  if( resultDist[i] > largestHeapDist ) {
188  maxDistIndex=i;
190  }
191  }
192 
193  float* resultDist;
195 
196  __device__
197  inline void
198  setResultLocation( DistanceType* dists, int* index, int thread, int stride )
199  {
200  resultDist=dists+stride*thread;
201  resultIndex=index+stride*thread;
202  for( int i=0; i<stride; i++ ) {
203  resultDist[i]=INFINITY;
204  resultIndex[i]=-1;
205  // resultIndex[tid+i*blockDim.x]=-1;
206  // resultDist[tid+i*blockDim.x]=INFINITY;
207  }
208  }
209 
210  __host__ __device__
211  inline void
213  {
214  if( sorted ) {
216  for( int i=k-1; i>0; i-- ) {
220  }
221  }
222  }
223 };
224 
225 template <typename DistanceType>
227 {
228  int count_;
229  DistanceType radius_sq_;
231 
232  __device__ __host__
233  CountingRadiusResultSet(DistanceType radius, int max_neighbors) : count_(0),radius_sq_(radius), max_neighbors_(max_neighbors){ }
234 
235  __device__
236  inline DistanceType
238  {
239  return radius_sq_;
240  }
241 
242  __device__
243  inline void
244  insert(int index, float dist)
245  {
246  if( dist < radius_sq_ ) {
247  count_++;
248  }
249  }
250 
252 
253  __device__
254  inline void
255  setResultLocation( DistanceType* /*dists*/, int* count, int thread, int stride )
256  {
257  resultIndex=count+thread*stride;
258  }
259 
260  __device__
261  inline void
263  {
265  else resultIndex[0]=max_neighbors_;
266  }
267 };
268 
269 template<typename DistanceType, bool useHeap>
271 {
273  DistanceType largestHeapDist;
275  const int k;
276  const bool sorted;
277  const DistanceType radius_sq_;
279  // int count_;
280 
281 
282  __device__ __host__
283  RadiusKnnResultSet(DistanceType radius, int knn, int* segment_starts, bool sortResults) : foundNeighbors(0),largestHeapDist(radius),k(knn), sorted(sortResults), radius_sq_(radius),segment_starts_(segment_starts) { }
284 
285  // __host__ __device__
286  // KnnResultSet(const KnnResultSet& o):foundNeighbors(o.foundNeighbors),largestHeapDist(o.largestHeapDist),k(o.k){ }
287 
288  __device__
289  inline DistanceType
291  {
292  return largestHeapDist;
293  }
294 
295  __device__
296  inline void
297  insert(int index, DistanceType dist)
298  {
299  if( dist < radius_sq_ ) {
300  if( foundNeighbors<k ) {
303  if(( foundNeighbors==k-1) && useHeap) {
304  if( useHeap ) {
307  }
308  else {
310  }
311  }
312  foundNeighbors++;
313 
314  }
315  else if( dist < largestHeapDist ) {
316  if( useHeap ) {
317  resultDist[0]=dist;
318  resultIndex[0]=index;
321  }
322  else {
324  resultIndex[maxDistElem]=index;
326  }
327  }
328  }
329  }
330 
331  __device__
332  void
334  {
336  maxDistElem=0;
337  for( int i=1; i<k; i++ )
338  if( resultDist[i] > largestHeapDist ) {
339  maxDistElem=i;
341  }
342  }
343 
344 
345  DistanceType* resultDist;
347 
348  __device__
349  inline void
350  setResultLocation( DistanceType* dists, int* index, int thread, int /*stride*/ )
351  {
352  resultDist=dists+segment_starts_[thread];
353  resultIndex=index+segment_starts_[thread];
354  }
355 
356  __device__
357  inline void
359  {
360  if( sorted ) {
362  for( int i=foundNeighbors-1; i>0; i-- ) {
366  }
367  }
368  }
369 };
370 
371 // Difference to RadiusKnnResultSet: Works like KnnResultSet, doesn't pack the results densely (as the RadiusResultSet does)
372 template <typename DistanceType, bool useHeap>
374 {
376  DistanceType largestHeapDist;
378  const int k;
379  const bool sorted;
380  const DistanceType epsError;
381  const DistanceType radius_sq;
382 
383 
384  __device__ __host__
385  KnnRadiusResultSet(int knn, bool sortResults, DistanceType eps, DistanceType radius) : foundNeighbors(0),largestHeapDist(radius),k(knn), sorted(sortResults), epsError(eps),radius_sq(radius){ }
386 
387  // __host__ __device__
388  // KnnResultSet(const KnnResultSet& o):foundNeighbors(o.foundNeighbors),largestHeapDist(o.largestHeapDist),k(o.k){ }
389 
390  __device__
391  inline DistanceType
393  {
394  return largestHeapDist;
395  }
396 
397  __device__
398  inline void
399  insert(int index, DistanceType dist)
400  {
401  if( dist < largestHeapDist ) {
402  if( foundNeighbors<k ) {
405  if( foundNeighbors==k-1 ) {
406  if( useHeap ) {
409  }
410  else {
412  }
413  }
414  foundNeighbors++;
415  }
416  else { //if( dist < largestHeapDist )
417  if( useHeap ) {
418  resultDist[0]=dist;
419  resultIndex[0]=index;
422  }
423  else {
425  resultIndex[maxDistIndex]=index;
427  }
428  }
429  }
430  }
431  __device__
432  void
434  {
436  maxDistIndex=0;
437  for( int i=1; i<k; i++ )
438  if( resultDist[i] > largestHeapDist ) {
439  maxDistIndex=i;
441  }
442  }
443 
444  DistanceType* resultDist;
446 
447  __device__
448  inline void
449  setResultLocation( DistanceType* dists, int* index, int thread, int stride )
450  {
451  resultDist=dists+stride*thread;
452  resultIndex=index+stride*thread;
453  for( int i=0; i<stride; i++ ) {
454  resultDist[i]=INFINITY;
455  resultIndex[i]=-1;
456  // resultIndex[tid+i*blockDim.x]=-1;
457  // resultDist[tid+i*blockDim.x]=INFINITY;
458  }
459  }
460 
461  __device__
462  inline void
464  {
465  if( sorted ) {
467  for( int i=k-1; i>0; i-- ) {
471  }
472  }
473  }
474 };
475 
479 template< typename DistanceType >
481 {
482  DistanceType radius_sq_;
484  int count_;
485  bool sorted_;
486 
487  __device__ __host__
488  RadiusResultSet(DistanceType radius, int* segment_starts, bool sorted) : radius_sq_(radius), segment_starts_(segment_starts), count_(0), sorted_(sorted){ }
489 
490  __device__
491  inline DistanceType
493  {
494  return radius_sq_;
495  }
496 
497  __device__
498  inline void
499  insert(int index, DistanceType dist)
500  {
501  if( dist < radius_sq_ ) {
502  resultIndex[count_]=index;
504  count_++;
505  }
506  }
507 
509  DistanceType* resultDist;
510 
511  __device__
512  inline void
513  setResultLocation( DistanceType* dists, int* index, int thread, int /*stride*/ )
514  {
515  resultIndex=index+segment_starts_[thread];
516  resultDist=dists+segment_starts_[thread];
517  }
518 
519  __device__
520  inline void
522  {
523  if( sorted_ ) {
525  for( int i=count_-1; i>0; i-- ) {
529  }
530  }
531  }
532 };
533 }
534 }
535 
536 #endif
int count
size_t stride
__device__ __forceinline__ float infinity()
Definition: result_set.h:36
#define INFINITY
Definition: result_set.h:42
static double dist(double x1, double y1, double x2, double y2)
Definition: lsd.c:207
__host__ __device__ void sift_down(RandomAccessIterator array, size_t begin, size_t length, GreaterThan c=GreaterThan())
Definition: heap.h:50
__host__ __device__ void make_heap(RandomAccessIterator begin, size_t length, GreaterThan c=GreaterThan())
Definition: heap.h:73
__device__ __host__ void swap(T &x, T &y)
Definition: heap.h:36
__device__ void insert(int index, float dist)
Definition: result_set.h:244
__device__ DistanceType worstDist()
Definition: result_set.h:237
__device__ void setResultLocation(DistanceType *, int *count, int thread, int stride)
Definition: result_set.h:255
__device__ __host__ CountingRadiusResultSet(DistanceType radius, int max_neighbors)
Definition: result_set.h:233
__device__ bool operator()(DistanceType a, DistanceType b)
Definition: result_set.h:107
__device__ void insert(int index, DistanceType dist)
Definition: result_set.h:399
__device__ DistanceType worstDist()
Definition: result_set.h:392
__device__ __host__ KnnRadiusResultSet(int knn, bool sortResults, DistanceType eps, DistanceType radius)
Definition: result_set.h:385
__device__ void setResultLocation(DistanceType *dists, int *index, int thread, int stride)
Definition: result_set.h:449
const DistanceType radius_sq
Definition: result_set.h:381
__device__ void findLargestDistIndex()
Definition: result_set.h:433
const DistanceType epsError
Definition: result_set.h:380
__device__ __host__ KnnResultSet(int knn, bool sortResults, DistanceType eps)
Definition: result_set.h:133
__host__ __device__ void finish()
Definition: result_set.h:212
__device__ void insert(int index, DistanceType dist)
Definition: result_set.h:147
DistanceType largestHeapDist
Definition: result_set.h:125
const DistanceType epsError
Definition: result_set.h:129
__device__ DistanceType worstDist()
Definition: result_set.h:140
__device__ void setResultLocation(DistanceType *dists, int *index, int thread, int stride)
Definition: result_set.h:198
__device__ void findLargestDistIndex()
Definition: result_set.h:182
const DistanceType radius_sq_
Definition: result_set.h:277
__device__ void insert(int index, DistanceType dist)
Definition: result_set.h:297
__device__ DistanceType worstDist()
Definition: result_set.h:290
__device__ void findLargestDistIndex()
Definition: result_set.h:333
__device__ __host__ RadiusKnnResultSet(DistanceType radius, int knn, int *segment_starts, bool sortResults)
Definition: result_set.h:283
__device__ void setResultLocation(DistanceType *dists, int *index, int thread, int)
Definition: result_set.h:350
__device__ __host__ RadiusResultSet(DistanceType radius, int *segment_starts, bool sorted)
Definition: result_set.h:488
__device__ void setResultLocation(DistanceType *dists, int *index, int thread, int)
Definition: result_set.h:513
__device__ void insert(int index, DistanceType dist)
Definition: result_set.h:499
__device__ void finish()
Definition: result_set.h:521
__device__ DistanceType worstDist()
Definition: result_set.h:492
result set for the 1nn search. Doesn't do any global memory accesses on its own,
Definition: result_set.h:52
__device__ float worstDist()
Definition: result_set.h:62
__device__ void finish()
Definition: result_set.h:96
__device__ void insert(int index, DistanceType dist)
Definition: result_set.h:69
__device__ __host__ SingleResultSet(DistanceType eps)
Definition: result_set.h:58
DistanceType * resultDist
Definition: result_set.h:77
const DistanceType epsError
Definition: result_set.h:55
__device__ void setResultLocation(DistanceType *dists, int *index, int thread, int stride)
Definition: result_set.h:82