OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
SupportBuilder.cuh
1//
2// Created by Serhii
3//
4
5#ifndef OPENFPM_PDATA_SUPPORTBUILDER_CUH
6#define OPENFPM_PDATA_SUPPORTBUILDER_CUH
7
8#include <Space/Shape/Point.hpp>
9#include <Vector/vector_dist.hpp>
10#include "Support.hpp"
11#include <utility>
12#include "SupportBuilder.hpp"
13
14
15template <unsigned int dim>
16__device__ __host__ bool nextCell(size_t (&offset)[dim], size_t maxOffset) {
17 size_t i = 0;
18
19 while (i < dim) {
20 if ((++offset[i++])/maxOffset)
21 for (size_t j = 0; j < i; ++j)
22 offset[j] = 0;
23 else
24 return true;
25 }
26 return false;
27}
28
29template<unsigned int dim, typename T, typename particles_type, typename CellList_type, typename supportSize_type>
30__global__ void gatherSupportSize_gpu(
31 particles_type particles, CellList_type cl, supportSize_type supportSize, T rCut) {
32 auto p_key = GET_PARTICLE(particles);
33 Point<dim, T> pos = particles.getPos(p_key);
34 auto cell = cl.getCellGrid(pos);
35
36 size_t grSize[dim]; cl.getGrid().getSize(grSize);
37 size_t offset[dim]; for (int i = 0; i < dim; ++i) offset[i] = 0;
38 grid_key_dx<dim> middle; for (int i = 0; i < dim; ++i) middle.set_d(i,1);
39
40 size_t N = 0;
41 do {
42 auto key=grid_key_dx<dim>(offset); key=cell+key-middle;
43
44 for (size_t i = 0; i < dim; ++i)
45 if (key.value(i) < 0 || key.value(i) >= grSize[i])
46 continue;
47
48 mem_id id = cl.getGrid().LinId(key);
49 const size_t cellLinId = static_cast<size_t>(id);
50 const size_t elemsInCell = cl.getNelements(cellLinId);
51
52 for (size_t k = 0; k < elemsInCell; ++k) {
53 size_t el = cl.get(cellLinId, k);
54
55 if (p_key == el) continue;
56 if (pos.distance(particles.getPosOrig(el)) < rCut) ++N;
57 }
58
59 } while (nextCell<dim>(offset, 2+1));
60
61 supportSize.get(p_key) = N;
62}
63
64template<unsigned int dim, typename T, typename particles_type, typename CellList_type, typename supportKey_type>
65__global__ void assembleSupport_gpu(particles_type particles, CellList_type cl, supportKey_type supportSize, supportKey_type supportKeys1D, T rCut) {
66 auto p_key = GET_PARTICLE(particles);
67 Point<dim, T> pos = particles.getPos(p_key);
68 auto cell = cl.getCellGrid(pos);
69
70 size_t supportKeysSize = supportSize.get(p_key+1)-supportSize.get(p_key);
71 size_t* supportKeys = &((size_t*)supportKeys1D.getPointer())[supportSize.get(p_key)];
72
73 size_t grSize[dim]; cl.getGrid().getSize(grSize);
74 size_t offset[dim]; for (int i = 0; i < dim; ++i) offset[i] = 0;
75 grid_key_dx<dim> middle; for (int i = 0; i < dim; ++i) middle.set_d(i,1);
76
77 size_t N = 0;
78 do {
79 auto key=grid_key_dx<dim>(offset); key=cell+key-middle;
80
81 for (size_t i = 0; i < dim; ++i)
82 if (key.value(i) < 0 || key.value(i) >= grSize[i])
83 continue;
84
85 mem_id id = cl.getGrid().LinId(key);
86 const size_t cellLinId = static_cast<size_t>(id);
87 const size_t elemsInCell = cl.getNelements(cellLinId);
88
89 for (size_t k = 0; k < elemsInCell; ++k) {
90 size_t el = cl.get(cellLinId, k);
91
92 if (p_key == el) continue;
93 if (pos.distance(particles.getPosOrig(el)) < rCut) supportKeys[N++] = el;
94 }
95
96 } while (nextCell<dim>(offset, 2+1));
97}
98
99
100
101template<typename vector_type>
103{
104private:
105 vector_type &domain;
106 typename vector_type::stype rCut;
107
108public:
109 SupportBuilderGPU(vector_type &domain, typename vector_type::stype rCut)
110 : domain(domain), rCut(rCut) {}
111
112 void getSupport(size_t N, openfpm::vector_custd<size_t>& kerOffsets, openfpm::vector_custd<size_t>& supportKeys1D,
113 size_t& maxSupport, size_t& supportKeysTotalN)
114 {
115 domain.hostToDevicePos();
116 auto it = domain.getDomainIteratorGPU(512);
118 // auto NN = domain.getCellListGPU(rCut);
119 auto NN = domain.template getCellList<params>(rCut);
120 NN.hostToDevice();
121
122
123 // +1 to allow getting size from cumulative sum: "size[i+1] - size[i]"
124 kerOffsets.resize(N+1);
125 gatherSupportSize_gpu<vector_type::dims><<<it.wthr,it.thr>>>(domain.toKernel(), NN.toKernel(), kerOffsets.toKernel(), rCut);
126 kerOffsets.template deviceToHost();
127
128 supportKeysTotalN = 0; maxSupport = 0;
129
130 for (size_t i = 0; i < N; ++i) {
131 size_t sz = kerOffsets.get(i);
132 kerOffsets.get(i) = supportKeysTotalN;
133 supportKeysTotalN += sz;
134 if (maxSupport < sz) maxSupport = sz;
135 }
136 kerOffsets.get(N) = supportKeysTotalN;
137
138 supportKeys1D.resize(supportKeysTotalN);
139 kerOffsets.template hostToDevice();
140 assembleSupport_gpu<vector_type::dims><<<it.wthr,it.thr>>>(domain.toKernel(), NN.toKernel(), kerOffsets.toKernel(), supportKeys1D.toKernel(), rCut);
141 supportKeys1D.template deviceToHost();
142 }
143};
144
145
146#endif //OPENFPM_PDATA_SUPPORTBUILDER_CUH
This class implement the point shape in an N-dimensional space.
Definition Point.hpp:28
__device__ __host__ T distance(const Point< dim, T > &q) const
It calculate the distance between 2 points.
Definition Point.hpp:250
grid_key_dx is the key to access any element in the grid
Definition grid_key.hpp:19
__device__ __host__ void set_d(index_type i, index_type id)
Set the i index.
Definition grid_key.hpp:516
__device__ __host__ index_type get(index_type i) const
Get the i index.
Definition grid_key.hpp:503
Implementation of 1-D std::vector like structure.
Distributed vector.
auto getPos(vect_dist_key_dx vec_key) -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
auto getPosOrig(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.