# PhasicFlow: src/phasicFlow/Kokkos/ViewAlgorithms.hpp Source File
PhasicFlow is an open-source parallel DEM (discrete element method) package for simulating granular flow. It is developed in C++ and can be exectued on both GPU (like CUDA) and CPU.

ViewAlgorithms.hpp
Go to the documentation of this file.
/*------------------------------- phasicFlow ---------------------------------
O C enter of
O O E ngineering and
O O M ultiscale modeling of
OOOOOOO F luid flow
------------------------------------------------------------------------------
Copyright (C): www.cemf.ir
email: hamid.r.norouzi AT gmail.com
------------------------------------------------------------------------------
Licence:
This file is part of phasicFlow code. It is a free software for simulating
granular and multiphase flows. You can redistribute it and/or modify it under
the terms of GNU General Public License v3 or any other later versions.
phasicFlow is distributed to help others in their research in the field of
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-----------------------------------------------------------------------------*/
#ifndef __ViewAlgorithms_hpp__
#define __ViewAlgorithms_hpp__
#include "KokkosUtilities.hpp"
#include "Range.hpp"
#include "numericConstants.hpp"
#include "cudaAlgorithms.hpp"
#include "kokkosAlgorithms.hpp"
#include "stdAlgorithms.hpp"
namespace pFlow
{
template<typename T, typename... properties>
INLINE_FUNCTION_H uint32
count(
const ViewType1D<T, properties...>& view,
uint32 start,
uint32 end,
const T& val
)
{
using ExecutionSpace =
typename ViewType1D<T, properties...>::execution_space;
uint32 numElems = end - start;
return pFlow::algorithms::KOKKOS::count<T, ExecutionSpace>(
view.data() + start, numElems, val
);
}
template<typename T, typename... properties>
INLINE_FUNCTION_H void
fill(ViewType1D<T, properties...>& view, rangeU32 span, T val)
{
using exe_space = typename ViewType1D<T, properties...>::execution_space;
auto subV = Kokkos::subview(view, span.getPair());
if constexpr (std::is_trivially_copyable_v<T>)
{
Kokkos::deep_copy(subV, val);
}
else if constexpr (isHostAccessible<exe_space>())
{
for (auto i = span.start(); i < span.end(); i++)
{
view[i] = val;
}
}
else
{
static_assert("fill is not valid for non-trivially-copyable data type");
}
}
template<typename T, typename... properties>
void
fill(ViewType1D<T, properties...>& view, uint32 start, uint32 end, T val)
{
fill(view, rangeU32(start, end), val);
}
template<typename T, typename... properties>
void
fill(
ViewType3D<T, properties...>& view,
rangeU32 range1,
rangeU32 range2,
rangeU32 range3,
const T& val
)
{
static_assert(std::is_trivially_copyable_v<T>, "Not valid type for fill");
auto subV = Kokkos::subview(view, range1, range2, range3);
Kokkos::deep_copy(subV, val);
}
template<typename T, typename... properties>
void
fill(ViewType3D<T, properties...>& view, const T& val)
{
static_assert(std::is_trivially_copyable_v<T>, "Not valid type for fill");
Kokkos::deep_copy(view, val);
}
template<typename Type, typename... properties>
void
fillSequence(
ViewType1D<Type, properties...>& view,
uint32 start,
uint32 end,
const Type startVal
)
{
static_assert(
std::is_trivially_copyable_v<Type>, "Not valid type for fill"
);
using ExecutionSpace =
typename ViewType1D<Type, properties...>::execution_space;
uint32 numElems = end - start;
pFlow::algorithms::KOKKOS::fillSequence<Type, ExecutionSpace>(
view.data() + start, numElems, startVal
);
return;
}
template<
typename Type,
typename... properties,
typename indexType,
typename... indexProperties>
bool
fillSelected(
ViewType1D<Type, properties...> view,
ViewType1D<indexType, indexProperties...> indices,
uint32 numElems,
Type val
)
{
static_assert(
std::is_trivially_copyable_v<Type>, "Not valid type for fillSelected"
);
static_assert(
areAccessible<
typename ViewType1D<Type, properties...>::execution_space,
typename ViewType1D<indexType, indexProperties...>::memory_space>(),
"In fillSelected, arguments view and indices must have similar spaces"
);
using ExSpace = typename ViewType1D<Type, properties...>::execution_space;
using policy = Kokkos::RangePolicy<ExSpace, Kokkos::IndexType<uint32>>;
Kokkos::parallel_for(
"ViewAlgorithms::fillSelected",
policy(0, numElems),
LAMBDA_HD(uint32 i){
// view[indices[i]]= val;
}
);
Kokkos::fence();
return true;
}
template<
typename Type,
typename... properties,
typename indexType,
typename... indexProperties>
bool
fillSelected(
ViewType1D<Type, properties...> view,
const ViewType1D<indexType, indexProperties...> indices,
const ViewType1D<Type, properties...> vals,
const uint32 numElems
)
{
static_assert(
std::is_trivially_copyable_v<Type>, "Not valid type for fillSelected"
);
static_assert(
areAccessible<
typename ViewType1D<Type, properties...>::execution_space,
typename ViewType1D<indexType, indexProperties...>::memory_space>(),
"In fillSelected arguments view and indices must have similar spaces"
);
using ExecutionSpace =
typename ViewType1D<Type, properties...>::execution_space;
pFlow::algorithms::KOKKOS::fillSelected<Type, indexType, ExecutionSpace>(
view.data(), indices.data(), vals.data(), numElems
);
return true;
}
template<typename T, typename... properties>
INLINE_FUNCTION_H T
min(const ViewType1D<T, properties...>& view, uint32 start, uint32 end)
{
using ExecutionSpace =
typename ViewType1D<T, properties...>::execution_space;
uint32 numElems = end - start;
return pFlow::algorithms::KOKKOS::min<T, ExecutionSpace>(
view.data() + start, numElems
);
}
template<typename T, typename... properties>
INLINE_FUNCTION_H T
max(const ViewType1D<T, properties...>& view, uint32 start, uint32 end)
{
using ExecutionSpace =
typename ViewType1D<T, properties...>::execution_space;
uint32 numElems = end - start;
return pFlow::algorithms::KOKKOS::max<T, ExecutionSpace>(
view.data() + start, numElems
);
}
template<
typename dType,
typename... dProperties,
typename sType,
typename... sProperties>
INLINE_FUNCTION_H void
copy(
const ViewType1D<dType, dProperties...>& dst,
const ViewType1D<sType, sProperties...>& src
)
{
Kokkos::deep_copy(dst, src);
}
template<
typename dType,
typename... dProperties,
typename sType,
typename... sProperties>
INLINE_FUNCTION_H void
copy(
const ViewType1D<dType, dProperties...>& dst,
uint32 dStart,
const ViewType1D<sType, sProperties...>& src,
uint32 sStart,
uint32 sEnd
)
{
auto srcSub = Kokkos::subview(
src,
Kokkos::make_pair(sStart, sEnd));
auto dstSub = Kokkos::subview(
dst,
Kokkos::make_pair(dStart, dStart + (sEnd - sStart)));
Kokkos::deep_copy(dstSub, srcSub);
}
template<typename Type, typename... sProperties>
INLINE_FUNCTION_H void
getNth(Type& dst, const ViewType1D<Type, sProperties...>& src, const uint32 n)
{
auto subV = Kokkos::subview(src, Kokkos::make_pair(n, n + 1));
hostViewType1D<Type> dstView("getNth", 1);
// hostViewTypeScalar
Kokkos::deep_copy(dstView, subV);
dst = *dstView.data();
}
template<typename T, typename... properties>
INLINE_FUNCTION_H void
sort(ViewType1D<T, properties...>& view, uint32 start, uint32 end)
{
using ExecutionSpace =
typename ViewType1D<T, properties...>::execution_space;
uint32 numElems = end - start;
if constexpr (isHostAccessible<ExecutionSpace>())
{
pFlow::algorithms::STD::sort<T, true>(view.data() + start, numElems);
return;
}
#ifdef __CUDACC__
pFlow::algorithms::CUDA::sort<T>(view.data() + start, numElems);
#else
static_assert("sort on device is not defined!");
#endif
return;
}
template<typename T, typename... properties, typename CompareFunc>
INLINE_FUNCTION_H void
sort(
ViewType1D<T, properties...>& view,
uint32 start,
uint32 end,
CompareFunc compare
)
{
using ExecutionSpace =
typename ViewType1D<T, properties...>::execution_space;
uint32 numElems = end - start;
if constexpr (isHostAccessible<ExecutionSpace>())
{
pFlow::algorithms::STD::sort<T, CompareFunc, true>(
view.data() + start, numElems, compare
);
return;
}
#ifdef __CUDACC__
pFlow::algorithms::CUDA::sort<T, CompareFunc>(
view.data() + start, numElems, compare
);
#else
static_assert("sort on device is not defined!");
#endif
return;
}
template<
typename Type,
typename... properties,
typename permType,
typename... permProperties>
void
permuteSort(
const ViewType1D<Type, properties...>& view,
uint32 start,
uint32 end,
ViewType1D<permType, permProperties...>& permuteView,
uint32 permStart
)
{
static_assert(
areAccessible<
typename ViewType1D<Type, properties...>::execution_space,
typename ViewType1D<permType, permProperties...>::memory_space>(),
"In permuteSort, view and permuteView should have the same space"
);
using ExecutionSpace =
typename ViewType1D<Type, properties...>::execution_space;
uint32 numElems = end - start;
pFlow::algorithms::STD::permuteSort<Type, permType, true>(
view.data() + start, permuteView.data() + permStart, numElems
);
return;
#ifdef __CUDACC__
pFlow::algorithms::CUDA::permuteSort(
view.data() + start, permuteView.data() + permStart, numElems
);
#else
static_assert("sort on device is not defined!");
#endif
}
template<typename T>
INLINE_FUNCTION_HD int32
binarySearch_(const T* array, int32 length, const T& val)
{
if (length <= 0)
return -1;
int low = 0;
int high = length - 1;
while (low <= high)
{
int mid = low + (high - low) / 2;
if (array[mid] > val)
{
high = mid - 1;
}
else if (array[mid] < val)
{
low = mid + 1;
}
else
{
return mid;
}
}
return -1; // val not found in array[0, length)
}
template<typename Type, typename... properties>
INLINE_FUNCTION_HD uint32
binarySearch(
const ViewType1D<Type, properties...>& view,
uint32 start,
uint32 end,
const Type& val
)
{
if (end <= start)
return static_cast< uint32 >(-1);
if (auto res = binarySearch_(view.data() + start, end - start, val);
res != static_cast< uint32 >(-1))
{
return res + start;
}
else
{
return res;
}
}
template<typename Type, typename... properties, typename... dProperties>
void
exclusiveScan(
const ViewType1D<Type, properties...>& view,
uint32 start,
uint32 end,
ViewType1D<Type, dProperties...>& dView,
uint32 dStart
)
{
static_assert(
areAccessible<
typename ViewType1D<Type, properties...>::execution_space,
typename ViewType1D<Type, dProperties...>::memory_space>(),
"In exclusiveScan, view and dView should have the same space"
);
using ExecutionSpace =
typename ViewType1D<Type, properties...>::execution_space;
uint32 numElems = end - start;
pFlow::algorithms::KOKKOS::exclusiveScan<Type, ExecutionSpace>(
view.data() + start, dView.data() + dStart, numElems
);
}
template<typename Type, typename... properties, typename... dProperties>
void
inclusiveScan(
const ViewType1D<Type, properties...>& view,
uint32 start,
uint32 end,
ViewType1D<Type, dProperties...>& dView,
uint32 dStart
)
{
using ExecutionSpace =
typename ViewType1D<Type, properties...>::execution_space;
static_assert(
areAccessible<
typename ViewType1D<Type, properties...>::execution_space,
typename ViewType1D<Type, dProperties...>::memory_space>(),
"In exclusiveScan, view and dView should have the same space"
);
uint32 numElems = end - start;
pFlow::algorithms::KOKKOS::inclusiveScan<Type, ExecutionSpace>(
view.data() + start, dView.data() + dStart, numElems
);
}
} // pFlow
#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