www.cemf.ir
ViewAlgorithms.hpp
Go to the documentation of this file.
1 /*------------------------------- phasicFlow ---------------------------------
2  O C enter of
3  O O E ngineering and
4  O O M ultiscale modeling of
5  OOOOOOO F luid flow
6 ------------------------------------------------------------------------------
7  Copyright (C): www.cemf.ir
8  email: hamid.r.norouzi AT gmail.com
9 ------------------------------------------------------------------------------
10 Licence:
11  This file is part of phasicFlow code. It is a free software for simulating
12  granular and multiphase flows. You can redistribute it and/or modify it under
13  the terms of GNU General Public License v3 or any other later versions.
14 
15  phasicFlow is distributed to help others in their research in the field of
16  granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
17  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 
19 -----------------------------------------------------------------------------*/
20 
21 #ifndef __ViewAlgorithms_hpp__
22 #define __ViewAlgorithms_hpp__
23 
24 #include "KokkosUtilities.hpp"
25 #include "Range.hpp"
26 #include "numericConstants.hpp"
27 
28 #include "cudaAlgorithms.hpp"
29 #include "kokkosAlgorithms.hpp"
30 #include "stdAlgorithms.hpp"
31 
32 namespace pFlow
33 {
34 template<typename T, typename... properties>
37  const ViewType1D<T, properties...>& view,
38  uint32 start,
39  uint32 end,
40  const T& val
41 )
42 {
43  using ExecutionSpace =
44  typename ViewType1D<T, properties...>::execution_space;
45 
46  uint32 numElems = end - start;
47 
48  return pFlow::algorithms::KOKKOS::count<T, ExecutionSpace>(
49  view.data() + start, numElems, val
50  );
51 }
52 
53 template<typename T, typename... properties>
56 {
57  using exe_space = typename ViewType1D<T, properties...>::execution_space;
58  auto subV = Kokkos::subview(view, span.getPair());
59  if constexpr (std::is_trivially_copyable_v<T>)
60  {
61  Kokkos::deep_copy(subV, val);
62  }
63  else if constexpr (isHostAccessible<exe_space>())
64  {
65  for (auto i = span.start(); i < span.end(); i++)
66  {
67  view[i] = val;
68  }
69  }
70  else
71  {
72  static_assert("fill is not valid for non-trivially-copyable data type");
73  }
74 }
75 
76 template<typename T, typename... properties>
77 void
79 {
80  fill(view, rangeU32(start, end), val);
81 }
82 
83 template<typename T, typename... properties>
84 void
87  rangeU32 range1,
88  rangeU32 range2,
89  rangeU32 range3,
90  const T& val
91 )
92 {
93  static_assert(std::is_trivially_copyable_v<T>, "Not valid type for fill");
94  auto subV = Kokkos::subview(view, range1, range2, range3);
95  Kokkos::deep_copy(subV, val);
96 }
97 
98 template<typename T, typename... properties>
99 void
100 fill(ViewType3D<T, properties...>& view, const T& val)
101 {
102  static_assert(std::is_trivially_copyable_v<T>, "Not valid type for fill");
103  Kokkos::deep_copy(view, val);
104 }
105 
106 template<typename Type, typename... properties>
107 void
110  uint32 start,
111  uint32 end,
112  const Type startVal
113 )
114 {
115  static_assert(
116  std::is_trivially_copyable_v<Type>, "Not valid type for fill"
117  );
118  using ExecutionSpace =
119  typename ViewType1D<Type, properties...>::execution_space;
120  uint32 numElems = end - start;
121 
122  pFlow::algorithms::KOKKOS::fillSequence<Type, ExecutionSpace>(
123  view.data() + start, numElems, startVal
124  );
125 
126  return;
127 }
128 
129 template<
130  typename Type,
131  typename... properties,
132  typename indexType,
133  typename... indexProperties>
134 bool
138  uint32 numElems,
139  Type val
140 )
141 {
142  static_assert(
143  std::is_trivially_copyable_v<Type>, "Not valid type for fillSelected"
144  );
145  static_assert(
149  "In fillSelected, arguments view and indices must have similar spaces"
150  );
151 
152  using ExSpace = typename ViewType1D<Type, properties...>::execution_space;
153  using policy = Kokkos::RangePolicy<ExSpace, Kokkos::IndexType<uint32>>;
154 
155  Kokkos::parallel_for(
156  "ViewAlgorithms::fillSelected",
157  policy(0, numElems),
158  LAMBDA_HD(uint32 i){
159  // view[indices[i]]= val;
160  }
161  );
162  Kokkos::fence();
163 
164  return true;
165 }
166 
167 template<
168  typename Type,
169  typename... properties,
170  typename indexType,
171  typename... indexProperties>
172 bool
177  const uint32 numElems
178 )
179 {
180  static_assert(
181  std::is_trivially_copyable_v<Type>, "Not valid type for fillSelected"
182  );
183  static_assert(
187  "In fillSelected arguments view and indices must have similar spaces"
188  );
189 
190  using ExecutionSpace =
191  typename ViewType1D<Type, properties...>::execution_space;
192 
193  pFlow::algorithms::KOKKOS::fillSelected<Type, indexType, ExecutionSpace>(
194  view.data(), indices.data(), vals.data(), numElems
195  );
196 
197  return true;
198 }
199 
200 template<typename T, typename... properties>
203 {
204  using ExecutionSpace =
205  typename ViewType1D<T, properties...>::execution_space;
206 
207  uint32 numElems = end - start;
208 
209  return pFlow::algorithms::KOKKOS::min<T, ExecutionSpace>(
210  view.data() + start, numElems
211  );
212 }
213 
214 template<typename T, typename... properties>
217 {
218  using ExecutionSpace =
219  typename ViewType1D<T, properties...>::execution_space;
220 
221  uint32 numElems = end - start;
222 
223  return pFlow::algorithms::KOKKOS::max<T, ExecutionSpace>(
224  view.data() + start, numElems
225  );
226 }
227 
228 template<
229  typename dType,
230  typename... dProperties,
231  typename sType,
232  typename... sProperties>
237 )
238 {
239  Kokkos::deep_copy(dst, src);
240 }
241 
242 template<
243  typename dType,
244  typename... dProperties,
245  typename sType,
246  typename... sProperties>
250  uint32 dStart,
252  uint32 sStart,
253  uint32 sEnd
254 )
255 {
256 
257  auto srcSub = Kokkos::subview(
258  src,
259  Kokkos::make_pair(sStart, sEnd));
260 
261  auto dstSub = Kokkos::subview(
262  dst,
263  Kokkos::make_pair(dStart, dStart + (sEnd - sStart)));
264 
265  Kokkos::deep_copy(dstSub, srcSub);
266 }
267 
268 template<typename Type, typename... sProperties>
270 getNth(Type& dst, const ViewType1D<Type, sProperties...>& src, const uint32 n)
271 {
272  auto subV = Kokkos::subview(src, Kokkos::make_pair(n, n + 1));
273  hostViewType1D<Type> dstView("getNth", 1);
274  // hostViewTypeScalar
275  Kokkos::deep_copy(dstView, subV);
276  dst = *dstView.data();
277 }
278 
279 template<typename T, typename... properties>
282 {
283  using ExecutionSpace =
284  typename ViewType1D<T, properties...>::execution_space;
285 
286  uint32 numElems = end - start;
287 
288  if constexpr (isHostAccessible<ExecutionSpace>())
289  {
290  pFlow::algorithms::STD::sort<T, true>(view.data() + start, numElems);
291  return;
292  }
293 
294 #ifdef __CUDACC__
295 
296  pFlow::algorithms::CUDA::sort<T>(view.data() + start, numElems);
297 #else
298  static_assert("sort on device is not defined!");
299 
300 #endif
301 
302  return;
303 }
304 
305 template<typename T, typename... properties, typename CompareFunc>
309  uint32 start,
310  uint32 end,
311  CompareFunc compare
312 )
313 {
314  using ExecutionSpace =
315  typename ViewType1D<T, properties...>::execution_space;
316 
317  uint32 numElems = end - start;
318 
319  if constexpr (isHostAccessible<ExecutionSpace>())
320  {
321  pFlow::algorithms::STD::sort<T, CompareFunc, true>(
322  view.data() + start, numElems, compare
323  );
324  return;
325  }
326 
327 #ifdef __CUDACC__
328 
329  pFlow::algorithms::CUDA::sort<T, CompareFunc>(
330  view.data() + start, numElems, compare
331  );
332 #else
333  static_assert("sort on device is not defined!");
334 
335 #endif
336 
337  return;
338 }
339 
340 template<
341  typename Type,
342  typename... properties,
343  typename permType,
344  typename... permProperties>
345 void
348  uint32 start,
349  uint32 end,
351  uint32 permStart
352 )
353 {
354  static_assert(
358  "In permuteSort, view and permuteView should have the same space"
359  );
360 
361  using ExecutionSpace =
362  typename ViewType1D<Type, properties...>::execution_space;
363 
364  uint32 numElems = end - start;
365 
366  pFlow::algorithms::STD::permuteSort<Type, permType, true>(
367  view.data() + start, permuteView.data() + permStart, numElems
368  );
369  return;
370 
371 #ifdef __CUDACC__
372 
374  view.data() + start, permuteView.data() + permStart, numElems
375  );
376 #else
377  static_assert("sort on device is not defined!");
378 
379 #endif
380 }
381 
382 template<typename T>
384 binarySearch_(const T* array, int32 length, const T& val)
385 {
386  if (length <= 0)
387  return -1;
388 
389  int low = 0;
390  int high = length - 1;
391 
392  while (low <= high)
393  {
394  int mid = low + (high - low) / 2;
395 
396  if (array[mid] > val)
397  {
398  high = mid - 1;
399  }
400  else if (array[mid] < val)
401  {
402  low = mid + 1;
403  }
404  else
405  {
406  return mid;
407  }
408  }
409 
410  return -1; // val not found in array[0, length)
411 }
412 
414 template<typename Type, typename... properties>
418  uint32 start,
419  uint32 end,
420  const Type& val
421 )
422 {
423  if (end <= start)
424  return static_cast<uint32>(-1);
425 
426  if (auto res = binarySearch_(view.data() + start, end - start, val);
427  res != static_cast<uint32>(-1))
428  {
429  return res + start;
430  }
431  else
432  {
433  return res;
434  }
435 }
436 
437 template<typename Type, typename... properties, typename... dProperties>
438 void
441  uint32 start,
442  uint32 end,
444  uint32 dStart
445 )
446 {
447  static_assert(
451  "In exclusiveScan, view and dView should have the same space"
452 
453  );
454 
455  using ExecutionSpace =
456  typename ViewType1D<Type, properties...>::execution_space;
457 
458  uint32 numElems = end - start;
459 
460  pFlow::algorithms::KOKKOS::exclusiveScan<Type, ExecutionSpace>(
461  view.data() + start, dView.data() + dStart, numElems
462  );
463 }
464 
465 template<typename Type, typename... properties, typename... dProperties>
466 void
469  uint32 start,
470  uint32 end,
472  uint32 dStart
473 )
474 {
475  using ExecutionSpace =
476  typename ViewType1D<Type, properties...>::execution_space;
477 
478  static_assert(
482  "In exclusiveScan, view and dView should have the same space"
483  );
484 
485  uint32 numElems = end - start;
486 
487  pFlow::algorithms::KOKKOS::inclusiveScan<Type, ExecutionSpace>(
488  view.data() + start, dView.data() + dStart, numElems
489  );
490 }
491 
492 } // pFlow
493 
494 #endif // __ViewAlgorithms_hpp__
pFlow::inclusiveScan
void inclusiveScan(const ViewType1D< Type, properties... > &view, uint32 start, uint32 end, ViewType1D< Type, dProperties... > &dView, uint32 dStart)
Definition: ViewAlgorithms.hpp:467
pFlow::span
Definition: span.hpp:31
pFlow::fill
void fill(Vector< T, Allocator > &vec, const T &val)
Definition: VectorAlgorithm.hpp:44
KokkosUtilities.hpp
pFlow::copy
INLINE_FUNCTION_H void copy(const ViewType1D< dType, dProperties... > &dst, const ViewType1D< sType, sProperties... > &src)
Definition: ViewAlgorithms.hpp:234
pFlow::uint32
unsigned int uint32
Definition: builtinTypes.hpp:56
pFlow::max
T max(const internalField< T, MemorySpace > &iField)
Definition: internalFieldAlgorithms.hpp:79
cudaAlgorithms.hpp
pFlow::binarySearch
INLINE_FUNCTION_HD uint32 binarySearch(const ViewType1D< Type, properties... > &view, uint32 start, uint32 end, const Type &val)
On DEVICE and HOST calls.
Definition: ViewAlgorithms.hpp:416
pFlow::rangeU32
Range< uint32 > rangeU32
Definition: Range.hpp:143
pFlow::getNth
INLINE_FUNCTION_H void getNth(Type &dst, const ViewType1D< Type, sProperties... > &src, const uint32 n)
Definition: ViewAlgorithms.hpp:270
pFlow
Definition: demGeometry.hpp:27
policy
Kokkos::RangePolicy< pFlow::DefaultExecutionSpace, Kokkos::Schedule< Kokkos::Static >, Kokkos::IndexType< pFlow::uint32 > > policy
Definition: grainParticlesKernels.cpp:25
pFlow::fillSelected
bool fillSelected(ViewType1D< Type, properties... > view, ViewType1D< indexType, indexProperties... > indices, uint32 numElems, Type val)
Definition: ViewAlgorithms.hpp:135
pFlow::permuteSort
void permuteSort(const ViewType1D< Type, properties... > &view, uint32 start, uint32 end, ViewType1D< permType, permProperties... > &permuteView, uint32 permStart)
Definition: ViewAlgorithms.hpp:346
length
INLINE_FUNCTION_HD T length(const triple< T > &v1)
pFlow::int32
int int32
Definition: builtinTypes.hpp:50
INLINE_FUNCTION_H
#define INLINE_FUNCTION_H
Definition: pFlowMacros.hpp:57
pFlow::count
auto count(const Vector< T, Allocator > &vec, const T &val)
Definition: VectorAlgorithm.hpp:26
pFlow::binarySearch_
INLINE_FUNCTION_HD int32 binarySearch_(const T *array, int32 length, const T &val)
Definition: ViewAlgorithms.hpp:384
pFlow::min
T min(const internalField< T, MemorySpace > &iField)
Definition: internalFieldAlgorithms.hpp:28
pFlow::Range< uint32 >
pFlow::ViewType1D
Kokkos::View< T *, properties... > ViewType1D
1D veiw as a vector
Definition: KokkosTypes.hpp:93
pFlow::ViewType3D
Kokkos::View< T ***, properties... > ViewType3D
3D view as an array
Definition: KokkosTypes.hpp:101
pFlow::hostViewType1D
Kokkos::View< T *, Kokkos::HostSpace > hostViewType1D
1D array (vector with host memeory space)
Definition: KokkosTypes.hpp:136
n
uint32 n
Definition: NBSLoop.hpp:24
pFlow::sort
void sort(Vector< T, Allocator > &vec)
Definition: VectorAlgorithm.hpp:62
LAMBDA_HD
#define LAMBDA_HD
Definition: pFlowMacros.hpp:58
pFlow::areAccessible
INLINE_FUNCTION_H constexpr bool areAccessible()
Is MemoerySpace accessible from ExecutionSpace.
Definition: KokkosUtilities.hpp:50
numericConstants.hpp
pFlow::fillSequence
void fillSequence(internalField< T, MemorySpace > &iField, const T &startVal)
Definition: internalFieldAlgorithms.hpp:198
INLINE_FUNCTION_HD
#define INLINE_FUNCTION_HD
Definition: pFlowMacros.hpp:55
pFlow::span::end
INLINE_FUNCTION_HD constIterator end() const
Returns an iterator to one past the end of the span.
Definition: span.hpp:122
kokkosAlgorithms.hpp
stdAlgorithms.hpp
Range.hpp
pFlow::exclusiveScan
void exclusiveScan(const ViewType1D< Type, properties... > &view, uint32 start, uint32 end, ViewType1D< Type, dProperties... > &dView, uint32 dStart)
Definition: ViewAlgorithms.hpp:439