Skip to content

Commit 6650eeb

Browse files
author
guo.2154
committed
kdlite for mpas
1 parent 74f8d56 commit 6650eeb

File tree

2 files changed

+84
-14
lines changed

2 files changed

+84
-14
lines changed

include/ftk/basic/kd_lite.hh

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace ftk {
1111
// implementation of https://www.nvidia.com/content/gtc-2010/pdfs/2140_gtc2010.pdf
1212
template <int nd, typename I=int, typename F=double>
1313
__host__
14-
void kd_build_recursive(
14+
void kdlite_build_recursive(
1515
const I n,
1616
const I current,
1717
const F *X, // coordinates
@@ -47,15 +47,15 @@ void kd_build_recursive(
4747
// fprintf(stderr, "current=%d, offset=%d, length=%d, lbm=%d, median=%d\n", current, offset, length, lbm, heap[current]);
4848

4949
if (lbm - 1 >= 1)
50-
kd_build_recursive<nd, I, F>(n, current*2+1, X, level+1, offset, lbm-1, heap, ids); // left
50+
kdlite_build_recursive<nd, I, F>(n, current*2+1, X, level+1, offset, lbm-1, heap, ids); // left
5151
if (length - lbm >= 1)
52-
kd_build_recursive<nd, I, F>(n, current*2+2, X, level+1, offset+lbm, length-lbm, heap, ids); // right
52+
kdlite_build_recursive<nd, I, F>(n, current*2+2, X, level+1, offset+lbm, length-lbm, heap, ids); // right
5353
}
5454
}
5555

5656
template <int nd, typename I=int, typename F=double>
5757
__host__
58-
void kd_build(
58+
void kdlite_build(
5959
const I n, // number of points
6060
const F *X, // coordinates
6161
I *heap) // out: pre-allocated heap
@@ -65,15 +65,77 @@ void kd_build(
6565
for (int i = 0; i < n; i ++)
6666
ids[i] = i;
6767

68-
kd_build_recursive<nd, I, F>(n, 0, X, 0, 0, n, heap, ids.data());
68+
kdlite_build_recursive<nd, I, F>(n, 0, X, 0, 0, n, heap, ids.data());
6969

7070
// for (int i = 0; i < n; i ++)
7171
// fprintf(stderr, "i=%d, heap=%d\n", i, heap[i]);
7272
}
7373

7474
template <int nd, typename I=int, typename F=double>
7575
__device__ __host__
76-
I kd_nearest(I n, const F *X, const I *heap, const F *x)
76+
I kdlite_nearest(I n, const F *X, const I *heap, const F *x)
77+
{
78+
static size_t max_stack_size = 32; // TODO
79+
80+
I S[max_stack_size];
81+
I top = 0;
82+
83+
S[top++] = 0; // push root // S[top].depth = 0; // root // depth = log2(i+1);
84+
85+
I best = -1; // no best yet
86+
F best_d2 = 1e32; // no best distance yet
87+
88+
while (top != 0) { // stack is not empty
89+
const I i = S[--top]; // pop stack
90+
91+
const I xid = heap[i];
92+
const I depth = std::log2(i+1);
93+
const I axis = depth % nd;
94+
I next, other;
95+
96+
if (x[axis] < X[nd*xid+axis]) {
97+
next = i * 2 + 1; // left child
98+
other = i * 2 + 2; // right child
99+
} else {
100+
next = i * 2 + 2; // right child
101+
other = i * 2 + 1; // left child
102+
}
103+
104+
const F d2 = vector_dist_2norm2<F>(nd, x, X + nd*xid); // distance to the current node
105+
if (d2 < best_d2) {
106+
best = xid;
107+
best_d2 = d2;
108+
109+
// fprintf(stderr, "current_best=%d, d2=%f, X=%f, %f, %f\n",
110+
// best, best_d2,
111+
// X[nd*xid], X[nd*xid+1], X[nd*xid+2]);
112+
}
113+
114+
// const F dp = x[axis] - X[nd*xid+axis]; // distance to the median
115+
// const F dp2 = dp * dp;
116+
117+
if (next < n) { // the next node exists
118+
assert(top < max_stack_size);
119+
S[top++] = next; // push stack
120+
}
121+
122+
if (other < n) {
123+
const F dp = x[axis] - X[nd*xid+axis];
124+
const F dp2 = dp * dp;
125+
126+
if (dp2 <= best_d2) {
127+
assert(top < max_stack_size);
128+
S[top++] = other; // push stack
129+
}
130+
}
131+
}
132+
133+
return best;
134+
}
135+
136+
template <int nd, typename I=int, typename F=double>
137+
__device__ __host__
138+
I kdlite_nearest_bfs(I n, const F *X, const I *heap, const F *x)
77139
{
78140
static size_t max_queue_size = 32768; // TODO
79141
typedef struct {

include/ftk/mesh/mpas_mesh.hh

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public:
8888

8989
public:
9090
std::shared_ptr<kd_t<F, 3>> kd_cells, kd_vertices;
91-
std::vector<int> kdl_cells;
91+
std::vector<int> kdlite_heap;
9292

9393
ndarray<I> cellsOnVertex, cellsOnEdge, cellsOnCell,
9494
edgesOnCell,
@@ -126,12 +126,12 @@ public:
126126
template <typename I, typename F>
127127
void mpas_mesh<I, F>::initialize()
128128
{
129-
kd_cells.reset(new kd_t<F, 3>);
130-
kd_cells->set_inputs(this->xyzCells);
131-
kd_cells->build();
129+
// kd_cells.reset(new kd_t<F, 3>);
130+
// kd_cells->set_inputs(this->xyzCells);
131+
// kd_cells->build();
132132

133-
kdl_cells.resize( n_cells()*2, -1 );
134-
kd_build<3>((int)n_cells(), xyzCells.data(), kdl_cells.data());
133+
kdlite_heap.resize( n_cells()*3, -1 );
134+
kdlite_build<3>((int)n_cells(), xyzCells.data(), kdlite_heap.data());
135135
}
136136

137137
template <typename I, typename F>
@@ -738,14 +738,22 @@ bool mpas_mesh<I, F>::point_in_cell_i(const I cell_i, const F x[]) const
738738
template <typename I, typename F>
739739
I mpas_mesh<I, F>::locate_cell_i(const F x[]) const
740740
{
741-
I cell_i = kd_cells->find_nearest(x);
741+
const I cell_i = kdlite_nearest<3, I, F>(
742+
(int)n_cells(),
743+
xyzCells.data(),
744+
kdlite_heap.data(),
745+
x);
742746
#if 0
747+
I cell_i = kd_cells->find_nearest(x);
743748
I cell_i1 = kd_nearest<3, I, F>((int)n_cells(),
744749
xyzCells.data(),
745750
kdl_cells.data(),
746751
x);
747752

748-
fprintf(stderr, "cell_i=%d, %d\n", cell_i, cell_i1);
753+
F d1 = vector_dist_2norm2<3>(x, xyzCells.data() + cell_i*3);
754+
F d2 = vector_dist_2norm2<3>(x, xyzCells.data() + cell_i1*3);
755+
756+
fprintf(stderr, "cell_i=%d, %d, dist=%f, %f\n", cell_i, cell_i1, d1, d2);
749757
assert(cell_i == cell_i1);
750758
#endif
751759

0 commit comments

Comments
 (0)