PeriDyno 1.0.0
Loading...
Searching...
No Matches
GridHash.cu
Go to the documentation of this file.
1#include "GridHash.h"
2
3#include "Object.h"
4#include "DataTypes.h"
5
6namespace dyno
7{
8 __constant__ int offset[27][3] = { 0, 0, 0,
9 0, 0, 1,
10 0, 1, 0,
11 1, 0, 0,
12 0, 0, -1,
13 0, -1, 0,
14 -1, 0, 0,
15 0, 1, 1,
16 0, 1, -1,
17 0, -1, 1,
18 0, -1, -1,
19 1, 0, 1,
20 1, 0, -1,
21 -1, 0, 1,
22 -1, 0, -1,
23 1, 1, 0,
24 1, -1, 0,
25 -1, 1, 0,
26 -1, -1, 0,
27 1, 1, 1,
28 1, 1, -1,
29 1, -1, 1,
30 -1, 1, 1,
31 1, -1, -1,
32 -1, 1, -1,
33 -1, -1, 1,
34 -1, -1, -1
35 };
36
37 template<typename TDataType>
38 GridHash<TDataType>::GridHash()
39 {
40 }
41
42 template<typename TDataType>
43 GridHash<TDataType>::~GridHash()
44 {
45 }
46
47 template<typename TDataType>
48 void GridHash<TDataType>::setSpace(Real _h, Coord _lo, Coord _hi)
49 {
50 release();
51
52 int padding = 2;
53 ds = _h;
54 lo = _lo - padding * ds;
55
56 Coord nSeg = (_hi - _lo) / ds;
57
58 nx = (int)ceil(nSeg[0]);
59 ny = (int)ceil(nSeg[1]);
60 nz = (int)ceil(nSeg[2]);
61
62 //To avoid values less or equal to zero
63 nx = nx < 1 ? 1 : nx;
64 ny = ny < 1 ? 1 : ny;
65 nz = nz < 1 ? 1 : nz;
66
67 nx += 2 * padding;
68 ny += 2 * padding;
69 nz += 2 * padding;
70 hi = lo + Coord((Real)nx, (Real)ny, (Real)nz) * ds;
71
72 num = nx * ny * nz;
73
74 // npMax = 128;
75
76 cuSafeCall(cudaMalloc((void**)&counter, num * sizeof(int)));
77 cuSafeCall(cudaMalloc((void**)&index, num * sizeof(int)));
78
79 if (m_reduce != nullptr)
80 {
81 delete m_reduce;
82 }
83
84 m_reduce = Reduction<int>::Create(num);
85 }
86
87 template<typename TDataType>
88 __global__ void K_CalculateParticleNumber(GridHash<TDataType> hash, const DArray<typename TDataType::Coord> pos)
89 {
90 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
91 if (pId >= pos.size()) return;
92
93 int gId = hash.getIndex(pos[pId]);
94
95 if (gId != INVALID)
96 atomicAdd(&(hash.index[gId]), 1);
97 }
98
99 template<typename TDataType>
100 __global__ void K_ConstructHashTable(GridHash<TDataType> hash, DArray<typename TDataType::Coord> pos)
101 {
102 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
103 if (pId >= pos.size()) return;
104
105 int gId = hash.getIndex(pos[pId]);
106
107 if (gId < 0) return;
108
109 int index = atomicAdd(&(hash.counter[gId]), 1);
110 hash.ids[hash.index[gId] + index] = pId;
111 }
112
113 template<typename TDataType>
114 void GridHash<TDataType>::construct(const DArray<Coord>& pos)
115 {
116 clear();
117
118 dim3 pDims = int(ceil(pos.size() / BLOCK_SIZE + 0.5f));
119
120 K_CalculateParticleNumber << <pDims, BLOCK_SIZE >> > (*this, pos);
121 particle_num = m_reduce->accumulate(index, num);
122
123 if (m_scan == nullptr)
124 {
125 m_scan = new Scan<int>();
126 }
127 m_scan->exclusive(index, num);
128
129 if (ids != nullptr)
130 {
131 cuSafeCall(cudaFree(ids));
132 }
133 cuSafeCall(cudaMalloc((void**)&ids, particle_num * sizeof(int)));
134
135 // std::cout << "Particle number: " << particle_num << std::endl;
136
137 K_ConstructHashTable << <pDims, BLOCK_SIZE >> > (*this, pos);
138 cuSynchronize();
139 }
140
141 template<typename TDataType>
142 void GridHash<TDataType>::clear()
143 {
144 if (counter != nullptr)
145 cuSafeCall(cudaMemset(counter, 0, num * sizeof(int)));
146
147 if (index != nullptr)
148 cuSafeCall(cudaMemset(index, 0, num * sizeof(int)));
149 }
150
151 template<typename TDataType>
152 void GridHash<TDataType>::release()
153 {
154 if (counter != nullptr)
155 cuSafeCall(cudaFree(counter));
156
157 if (ids != nullptr)
158 cuSafeCall(cudaFree(ids));
159
160 if (index != nullptr)
161 cuSafeCall(cudaFree(index));
162
163 if (m_scan != nullptr)
164 delete m_scan;
165
166 if (m_reduce != nullptr)
167 delete m_reduce;
168 }
169
170 DEFINE_CLASS(GridHash);
171}