42 #ifndef TPETRA_DETAILS_COMPUTEOFFSETS_HPP
43 #define TPETRA_DETAILS_COMPUTEOFFSETS_HPP
52 #include "TpetraCore_config.h"
55 #include <type_traits>
75 template<
class OffsetType,
78 class ComputeOffsetsFromCounts {
80 static_assert (std::is_integral<OffsetType>::value,
81 "OffsetType must be a built-in integer.");
82 static_assert (std::is_integral<CountType>::value,
83 "CountType must be a built-in integer.");
84 static_assert (std::is_integral<SizeType>::value,
85 "SizeType must be a built-in integer.");
87 using offsets_view_type =
88 Kokkos::View<OffsetType*, Kokkos::AnonymousSpace>;
89 using counts_view_type =
90 Kokkos::View<const CountType*, Kokkos::AnonymousSpace>;
97 ComputeOffsetsFromCounts (
const offsets_view_type& offsets,
98 const counts_view_type& counts) :
101 size_ (counts.extent (0))
105 KOKKOS_INLINE_FUNCTION
void
106 operator () (
const SizeType i, OffsetType& update,
107 const bool finalPass)
const
109 const auto curVal = (i <
size_) ?
counts_[i] : OffsetType ();
113 update += (i <
size_) ? curVal : OffsetType ();
116 template<
class ExecutionSpace>
118 run (
const ExecutionSpace& execSpace,
119 const offsets_view_type& offsets,
120 const counts_view_type& counts)
122 const SizeType numCounts (counts.extent (0));
123 using range_type = Kokkos::RangePolicy<ExecutionSpace, SizeType>;
124 range_type range (execSpace, 0, numCounts + SizeType (1));
126 ComputeOffsetsFromCounts<OffsetType, CountType, SizeType>;
127 functor_type functor (offsets, counts);
128 OffsetType total (0);
129 const char funcName[] =
"Tpetra::Details::computeOffsetsFromCounts";
130 Kokkos::parallel_scan (range, functor, total, funcName);
152 template<
class OffsetType,
155 class ComputeOffsetsFromConstantCount {
157 static_assert (std::is_integral<OffsetType>::value,
158 "OffsetType must be a built-in integer.");
159 static_assert (std::is_integral<CountType>::value,
160 "CountType must be a built-in integer.");
161 static_assert (std::is_integral<SizeType>::value,
162 "SizeType must be a built-in integer.");
164 using offsets_view_type =
165 Kokkos::View<OffsetType*, Kokkos::AnonymousSpace>;
172 ComputeOffsetsFromConstantCount (
const offsets_view_type& offsets,
173 const CountType count) :
179 KOKKOS_INLINE_FUNCTION
void
180 operator () (
const SizeType i)
const
185 template<
class ExecutionSpace>
187 run (
const ExecutionSpace& execSpace,
188 const offsets_view_type& offsets,
189 const CountType count)
191 const SizeType numOffsets (offsets.extent (0));
192 using range_type = Kokkos::RangePolicy<ExecutionSpace, SizeType>;
193 range_type range (execSpace, 0, numOffsets);
195 ComputeOffsetsFromConstantCount<OffsetType, CountType, SizeType>;
196 functor_type functor (offsets, count);
197 const OffsetType total = numOffsets*count;
198 const char funcName[] =
199 "Tpetra::Details::computeOffsetsFromConstantCount";
200 Kokkos::parallel_for (range, functor, funcName);
238 template<
class ExecutionSpace,
239 class OffsetsViewType,
240 class CountsViewType,
241 class SizeType =
typename OffsetsViewType::size_type>
242 typename OffsetsViewType::non_const_value_type
244 const OffsetsViewType& ptr,
245 const CountsViewType& counts)
247 static_assert (Kokkos::is_execution_space<ExecutionSpace>::value,
248 "ExecutionSpace must be a Kokkos execution space.");
249 static_assert (Kokkos::Impl::is_view<OffsetsViewType>::value,
250 "OffsetsViewType (the type of ptr) must be a Kokkos::View.");
251 static_assert (Kokkos::Impl::is_view<CountsViewType>::value,
252 "CountsViewType (the type of counts) must be a Kokkos::View.");
253 static_assert (std::is_same<
typename OffsetsViewType::value_type,
254 typename OffsetsViewType::non_const_value_type>::value,
255 "OffsetsViewType (the type of ptr) must be a nonconst Kokkos::View.");
256 static_assert (static_cast<int> (OffsetsViewType::rank) == 1,
257 "OffsetsViewType (the type of ptr) must be a rank-1 Kokkos::View.");
258 static_assert (static_cast<int> (CountsViewType::rank) == 1,
259 "CountsViewType (the type of counts) must be a rank-1 Kokkos::View.");
261 using offset_type =
typename OffsetsViewType::non_const_value_type;
262 static_assert (std::is_integral<offset_type>::value,
263 "The entries of ptr must be built-in integers.");
264 using count_type =
typename CountsViewType::non_const_value_type;
265 static_assert (std::is_integral<count_type>::value,
266 "The entries of counts must be built-in integers.");
267 static_assert (std::is_integral<SizeType>::value,
268 "SizeType must be a built-in integer type.");
270 const char funcName[] =
"Tpetra::Details::computeOffsetsFromCounts";
272 const auto numOffsets = ptr.size ();
273 const auto numCounts = counts.size ();
274 offset_type total (0);
276 if (numOffsets != 0) {
277 TEUCHOS_TEST_FOR_EXCEPTION
278 (numCounts >= numOffsets, std::invalid_argument, funcName <<
279 ": counts.size() = " << numCounts <<
" >= ptr.size() = " <<
282 #ifdef TPETRA_AVOID_PARALLEL_SCAN
290 Kokkos::View<offset_type*,Kokkos::HostSpace>
291 ptrAPS(Kokkos::ViewAllocateWithoutInitializing(
"APS_offsets"),
293 Kokkos::View<count_type*,Kokkos::HostSpace>
294 countsAPS(Kokkos::ViewAllocateWithoutInitializing(
"APS_counts"),
300 for (
size_t i = 0; i < numCounts; i++)
301 ptrAPS(i+1) = ptrAPS(i) + countsAPS(i);
303 total = ptrAPS(numCounts);
308 using Kokkos::AnonymousSpace;
310 View<offset_type*, AnonymousSpace> ptr_a = ptr;
311 View<const count_type*, AnonymousSpace> counts_a;
313 using offsets_device_type =
typename OffsetsViewType::device_type;
314 using counts_copy_type = View<count_type*, offsets_device_type>;
315 counts_copy_type counts_copy;
317 using offsets_memory_space =
318 typename offsets_device_type::memory_space;
319 using counts_memory_space =
typename CountsViewType::memory_space;
320 constexpr
bool countsAccessibleFromOffsetsExecSpace =
321 Kokkos::Impl::VerifyExecutionCanAccessMemorySpace<
322 offsets_memory_space, counts_memory_space>::value;
323 if (countsAccessibleFromOffsetsExecSpace) {
331 using Kokkos::view_alloc;
332 using Kokkos::WithoutInitializing;
333 counts_copy = counts_copy_type
334 (view_alloc (
"counts_copy", WithoutInitializing), numCounts);
336 counts_a = counts_copy;
340 ComputeOffsetsFromCounts<offset_type, count_type, SizeType>;
341 total = functor_type::run (execSpace, ptr_a, counts_a);
349 template<
class OffsetsViewType,
350 class CountsViewType,
351 class SizeType =
typename OffsetsViewType::size_type>
352 typename OffsetsViewType::non_const_value_type
354 const CountsViewType& counts)
356 using execution_space =
typename OffsetsViewType::execution_space;
382 template<
class OffsetsViewType,
384 class SizeType =
typename OffsetsViewType::size_type>
385 typename OffsetsViewType::non_const_value_type
387 const CountType count)
389 static_assert (Kokkos::Impl::is_view<OffsetsViewType>::value,
390 "ptr must be a Kokkos::View.");
391 static_assert (std::is_same<
typename OffsetsViewType::value_type,
392 typename OffsetsViewType::non_const_value_type>::value,
393 "ptr must be a nonconst Kokkos::View.");
394 static_assert (static_cast<int> (OffsetsViewType::rank) == 1,
395 "ptr must be a rank-1 Kokkos::View.");
397 using offset_type =
typename OffsetsViewType::non_const_value_type;
398 static_assert (std::is_integral<offset_type>::value,
399 "The type of each entry of ptr must be a "
400 "built-in integer.");
401 static_assert (std::is_integral<CountType>::value,
402 "CountType must be a built-in integer.");
403 static_assert (std::is_integral<SizeType>::value,
404 "SizeType must be a built-in integer.");
406 using device_type =
typename OffsetsViewType::device_type;
407 using execution_space =
typename device_type::execution_space;
409 offset_type total (0);
410 if (ptr.extent (0) != 0) {
411 using CT = CountType;
413 ComputeOffsetsFromConstantCount<offset_type, CT, SizeType>;
414 execution_space execSpace;
415 functor_type::run (execSpace, ptr, count);
423 #endif // TPETRA_DETAILS_COMPUTEOFFSETS_HPP
counts_view_type counts_
Bucket counts (input argument).
OffsetsViewType::non_const_value_type computeOffsetsFromConstantCount(const OffsetsViewType &ptr, const CountType count)
Compute offsets from a constant count.
offsets_view_type offsets_
Offsets (output argument)
void deep_copy(MultiVector< DS, DL, DG, DN > &dst, const MultiVector< SS, SL, SG, SN > &src)
Copy the contents of the MultiVector src into dst.
CountType count_
"Count" input argument
SizeType size_
Number of entries in counts_.
OffsetsViewType::non_const_value_type computeOffsetsFromCounts(const ExecutionSpace &execSpace, const OffsetsViewType &ptr, const CountsViewType &counts)
Compute offsets from counts.
Declaration and definition of Tpetra::Details::getEntryOnHost.