Block-Structured AMR Software Framework
AMReX_SparseBins.H
Go to the documentation of this file.
1 #ifndef AMREX_SPARSEBINS_H_
2 #define AMREX_SPARSEBINS_H_
3 #include <AMReX_Config.H>
4 
5 #include <AMReX_Gpu.H>
6 #include <AMReX_IntVect.H>
7 #include <AMReX_BLProfiler.H>
8 #include <AMReX_BinIterator.H>
9 
10 namespace amrex
11 {
12 
13 template <typename T>
15 {
16 
17  using index_type = int;
18 
19  using const_pointer_type = std::conditional_t<IsParticleTileData<T>(),
20  T,
21  const T*
22  >;
23 
24  using const_pointer_input_type = std::conditional_t<IsParticleTileData<T>(),
25  const T&,
26  const T*
27  >;
28 
30  const Gpu::DeviceVector<index_type>& offsets,
31  const Gpu::DeviceVector<index_type>& permutation,
33  : m_bins_ptr(bins.dataPtr()),
34  m_offsets_ptr(offsets.dataPtr()),
35  m_permutation_ptr(permutation.dataPtr()),
36  m_items(items), m_num_bins(int(bins.size()))
37  {}
38 
39  [[nodiscard]] AMREX_GPU_HOST_DEVICE
40  index_type getIndex (const index_type bin_number) const noexcept
41  {
42  if (m_num_bins == 1) { return 0; }
43 
44  index_type lo = 0;
45  index_type hi = m_num_bins - 1;
46 
47  while (lo < hi) {
48  if (m_bins_ptr[lo] == bin_number) { return lo; }
49  if (m_bins_ptr[hi] == bin_number) { return hi; }
50 
51  index_type mid = (lo + hi) / 2;
52  index_type mid_value = m_bins_ptr[mid];
53  if (mid_value == bin_number) { return mid; }
54 
55  mid_value < bin_number ? lo = mid+1 : hi = mid;
56  }
57 
58  return m_not_found;
59  }
60 
61  [[nodiscard]] AMREX_GPU_HOST_DEVICE
62  BinIterator<T> getBinIterator (const index_type bin_number) const noexcept
63  {
64  auto index = getIndex(bin_number);
66  }
67 
73 
75 };
76 
93 template <typename T>
95 {
96 public:
97 
99  using bin_type = IntVect;
100  using index_type = int;
101 
102  using const_pointer_type = std::conditional_t<IsParticleTileData<T>(),
103  T,
104  const T*
105  >;
106 
107  using const_pointer_input_type = std::conditional_t<IsParticleTileData<T>(),
108  const T&,
109  const T*
110  >;
111 
123  template <typename N, typename F>
124  void build (N nitems, const_pointer_input_type v, const Box& bx, F const& f)
125  {
126  BL_PROFILE("SparseBins<T>::build");
127 
128  m_items = v;
129 
130  Gpu::HostVector<index_type> host_cells(nitems);
131  std::map<index_type, index_type> bins_map;
132  const auto lo = lbound(bx);
133  const auto hi = ubound(bx);
134  for (int i = 0; i < nitems; ++i)
135  {
136  bin_type iv = f(v[i]);
137  auto iv3 = iv.dim3();
138  int nx = hi.x-lo.x+1;
139  int ny = hi.y-lo.y+1;
140  int nz = hi.z-lo.z+1;
141  index_type uix = amrex::min(nx-1,amrex::max(0,iv3.x));
142  index_type uiy = amrex::min(ny-1,amrex::max(0,iv3.y));
143  index_type uiz = amrex::min(nz-1,amrex::max(0,iv3.z));
144  host_cells[i] = (uix * ny + uiy) * nz + uiz;
145  bins_map[host_cells[i]] += 1;
146  }
147 
148  Gpu::HostVector<index_type> host_perm(nitems);
149  std::iota(host_perm.begin(), host_perm.end(), 0);
150  std::sort(host_perm.begin(), host_perm.end(),
151  [&](int i, int j) {return host_cells[i] < host_cells[j];});
152 
153  Gpu::HostVector<index_type> host_bins;
154  Gpu::HostVector<index_type> host_offsets = {0};
155  for (const auto& kv : bins_map)
156  {
157  host_bins.push_back(kv.first);
158  host_offsets.push_back(host_offsets.back() + kv.second);
159  }
160 
161  m_bins.resize(host_bins.size());
162  Gpu::copyAsync(Gpu::hostToDevice, host_bins.begin(), host_bins.end(), m_bins.begin());
163 
164  m_offsets.resize(host_offsets.size());
165  Gpu::copyAsync(Gpu::hostToDevice, host_offsets.begin(), host_offsets.end(), m_offsets.begin());
166 
167  m_perm.resize(host_perm.size());
168  Gpu::copyAsync(Gpu::hostToDevice, host_perm.begin(), host_perm.end(), m_perm.begin());
169 
171  }
172 
174  [[nodiscard]] Long numItems () const noexcept { return m_perm.size(); }
175 
177  [[nodiscard]] Long numBins () const noexcept { return m_offsets.size()-1; }
178 
180  [[nodiscard]] index_type* permutationPtr () noexcept { return m_perm.dataPtr(); }
181 
183  [[nodiscard]] index_type* offsetsPtr () noexcept { return m_offsets.dataPtr(); }
184 
186  [[nodiscard]] index_type* getNonZeroBinsPtr() noexcept { return m_bins.dataPtr(); }
187 
189  [[nodiscard]] const index_type* permutationPtr () const noexcept { return m_perm.dataPtr(); }
190 
192  [[nodiscard]] const index_type* offsetsPtr () const noexcept { return m_offsets.dataPtr(); }
193 
195  [[nodiscard]] const index_type* getNonZeroBinsPtr() const noexcept { return m_bins.dataPtr(); }
196 
198  [[nodiscard]] SparseBinIteratorFactory<T> getBinIteratorFactory() const noexcept
199  {
201  }
202 
203 private:
204 
206 
210 };
211 
212 }
213 
214 #endif
#define BL_PROFILE(a)
Definition: AMReX_BLProfiler.H:551
#define AMREX_GPU_HOST_DEVICE
Definition: AMReX_GpuQualifiers.H:20
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Dim3 dim3() const noexcept
Definition: AMReX_IntVect.H:163
Definition: AMReX_PODVector.H:246
size_type size() const noexcept
Definition: AMReX_PODVector.H:575
T & back() noexcept
Definition: AMReX_PODVector.H:589
iterator begin() noexcept
Definition: AMReX_PODVector.H:601
iterator end() noexcept
Definition: AMReX_PODVector.H:605
void push_back(const T &a_value)
Definition: AMReX_PODVector.H:556
A container for storing items in a set of bins using "sparse" storage.
Definition: AMReX_SparseBins.H:95
Gpu::DeviceVector< index_type > m_perm
Definition: AMReX_SparseBins.H:209
index_type * permutationPtr() noexcept
returns the pointer to the permutation array
Definition: AMReX_SparseBins.H:180
index_type * getNonZeroBinsPtr() noexcept
returns the pointer to the array of non-zero bins
Definition: AMReX_SparseBins.H:186
const index_type * permutationPtr() const noexcept
returns const pointer to the permutation array
Definition: AMReX_SparseBins.H:189
std::conditional_t< IsParticleTileData< T >(), T, const T * > const_pointer_type
Definition: AMReX_SparseBins.H:105
SparseBinIteratorFactory< T > getBinIteratorFactory() const noexcept
returns a GPU-capable object that can create iterators over the items in a bin.
Definition: AMReX_SparseBins.H:198
const index_type * getNonZeroBinsPtr() const noexcept
returns the pointer to the array of non-zero bins
Definition: AMReX_SparseBins.H:195
Gpu::DeviceVector< index_type > m_offsets
Definition: AMReX_SparseBins.H:208
const index_type * offsetsPtr() const noexcept
returns const pointer to the offsets array
Definition: AMReX_SparseBins.H:192
Long numItems() const noexcept
the number of items in the container
Definition: AMReX_SparseBins.H:174
index_type * offsetsPtr() noexcept
returns the pointer to the offsets array
Definition: AMReX_SparseBins.H:183
int index_type
Definition: AMReX_SparseBins.H:100
Long numBins() const noexcept
the number of bins in the container
Definition: AMReX_SparseBins.H:177
std::conditional_t< IsParticleTileData< T >(), const T &, const T * > const_pointer_input_type
Definition: AMReX_SparseBins.H:110
void build(N nitems, const_pointer_input_type v, const Box &bx, F const &f)
Populate the bins with a set of items.
Definition: AMReX_SparseBins.H:124
const_pointer_type m_items
Definition: AMReX_SparseBins.H:205
Gpu::DeviceVector< index_type > m_bins
Definition: AMReX_SparseBins.H:207
AMREX_GPU_HOST_DEVICE Long size(T const &b) noexcept
integer version
Definition: AMReX_GpuRange.H:26
void copyAsync(HostToDevice, InIter begin, InIter end, OutIter result) noexcept
A host-to-device copy routine. Note this is just a wrapper around memcpy, so it assumes contiguous st...
Definition: AMReX_GpuContainers.H:233
static constexpr HostToDevice hostToDevice
Definition: AMReX_GpuContainers.H:98
void streamSynchronize() noexcept
Definition: AMReX_GpuDevice.H:237
static int f(amrex::Real t, N_Vector y_data, N_Vector y_rhs, void *user_data)
Definition: AMReX_SundialsIntegrator.H:44
@ max
Definition: AMReX_ParallelReduce.H:17
Definition: AMReX_Amr.cpp:49
AMREX_GPU_HOST_DEVICE constexpr AMREX_FORCE_INLINE const T & max(const T &a, const T &b) noexcept
Definition: AMReX_Algorithm.H:35
AMREX_GPU_HOST_DEVICE constexpr AMREX_FORCE_INLINE const T & min(const T &a, const T &b) noexcept
Definition: AMReX_Algorithm.H:21
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Dim3 ubound(Array4< T > const &a) noexcept
Definition: AMReX_Array4.H:315
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Dim3 lbound(Array4< T > const &a) noexcept
Definition: AMReX_Array4.H:308
IntVectND< AMREX_SPACEDIM > IntVect
Definition: AMReX_BaseFwd.H:30
const int[]
Definition: AMReX_BLProfiler.cpp:1664
Definition: AMReX_BinIterator.H:24
int x
Definition: AMReX_Dim3.H:12
Definition: AMReX_SparseBins.H:15
const_pointer_type m_items
Definition: AMReX_SparseBins.H:71
index_type m_num_bins
Definition: AMReX_SparseBins.H:72
SparseBinIteratorFactory(const Gpu::DeviceVector< index_type > &bins, const Gpu::DeviceVector< index_type > &offsets, const Gpu::DeviceVector< index_type > &permutation, const_pointer_input_type items)
Definition: AMReX_SparseBins.H:29
const index_type * m_permutation_ptr
Definition: AMReX_SparseBins.H:70
static constexpr index_type m_not_found
Definition: AMReX_SparseBins.H:74
std::conditional_t< IsParticleTileData< T >(), T, const T * > const_pointer_type
Definition: AMReX_SparseBins.H:22
std::conditional_t< IsParticleTileData< T >(), const T &, const T * > const_pointer_input_type
Definition: AMReX_SparseBins.H:27
const index_type * m_offsets_ptr
Definition: AMReX_SparseBins.H:69
int index_type
Definition: AMReX_SparseBins.H:17
AMREX_GPU_HOST_DEVICE index_type getIndex(const index_type bin_number) const noexcept
Definition: AMReX_SparseBins.H:40
const index_type * m_bins_ptr
Definition: AMReX_SparseBins.H:68
AMREX_GPU_HOST_DEVICE BinIterator< T > getBinIterator(const index_type bin_number) const noexcept
Definition: AMReX_SparseBins.H:62