44 #ifndef TPETRA_DETAILS_COMPUTEOFFSETS_HPP
45 #define TPETRA_DETAILS_COMPUTEOFFSETS_HPP
53 #include "TpetraCore_config.h"
56 #include <type_traits>
84 template<
class OffsetsViewType,
86 class SizeType =
typename OffsetsViewType::size_type>
87 class ComputeOffsetsFromCounts {
89 static_assert (Kokkos::Impl::is_view<OffsetsViewType>::value,
90 "OffsetsViewType (the type of ptr) must be a Kokkos::View.");
91 static_assert (Kokkos::Impl::is_view<CountsViewType>::value,
92 "CountsViewType (the type of counts) must be a Kokkos::View.");
93 static_assert (std::is_same<
typename OffsetsViewType::value_type,
94 typename OffsetsViewType::non_const_value_type>::value,
95 "OffsetsViewType (the type of ptr) must be a nonconst Kokkos::View.");
96 static_assert (static_cast<int> (OffsetsViewType::rank) == 1,
97 "OffsetsViewType (the type of ptr) must be a rank-1 Kokkos::View.");
98 static_assert (static_cast<int> (CountsViewType::rank) == 1,
99 "CountsViewType (the type of counts) must be a rank-1 Kokkos::View.");
100 static_assert (std::is_integral<typename OffsetsViewType::non_const_value_type>::value,
101 "The entries of ptr must be built-in integers.");
102 static_assert (std::is_integral<typename CountsViewType::non_const_value_type>::value,
103 "The entries of counts must be built-in integers.");
104 static_assert (std::is_integral<SizeType>::value,
105 "SizeType must be a built-in integer type.");
107 typedef OffsetsViewType offsets_view_type;
108 typedef typename CountsViewType::const_type counts_view_type;
109 typedef SizeType size_type;
110 typedef typename OffsetsViewType::non_const_value_type value_type;
117 ComputeOffsetsFromCounts (
const offsets_view_type& offsets,
118 const counts_view_type& counts) :
121 size_ (counts.extent (0))
125 KOKKOS_INLINE_FUNCTION
void init (value_type& dst)
const
131 KOKKOS_INLINE_FUNCTION
void
132 join (
volatile value_type& dst,
133 const volatile value_type& src)
const
139 KOKKOS_INLINE_FUNCTION
void
140 operator () (
const size_type& i, value_type& update,
const bool final)
const
142 const auto curVal = (i <
size_) ?
counts_[i] : value_type ();
146 update += (i <
size_) ? curVal : value_type ();
182 template<
class OffsetsViewType,
184 class SizeType =
typename OffsetsViewType::size_type>
185 class ComputeOffsetsFromConstantCount {
187 static_assert (Kokkos::Impl::is_view<OffsetsViewType>::value,
188 "OffsetsViewType (the type of ptr) must be a Kokkos::View.");
189 static_assert (std::is_same<
typename OffsetsViewType::value_type,
190 typename OffsetsViewType::non_const_value_type>::value,
191 "OffsetsViewType (the type of ptr) must be a nonconst Kokkos::View.");
192 static_assert (static_cast<int> (OffsetsViewType::rank) == 1,
193 "OffsetsViewType (the type of ptr) must be a rank-1 Kokkos::View.");
194 static_assert (std::is_integral<typename OffsetsViewType::non_const_value_type>::value,
195 "The entries of ptr must be built-in integers.");
196 static_assert (std::is_integral<CountType>::value,
197 "CountType must be a built-in integer type.");
198 static_assert (std::is_integral<SizeType>::value,
199 "SizeType must be a built-in integer type.");
201 typedef OffsetsViewType offsets_view_type;
202 typedef CountType count_type;
203 typedef SizeType size_type;
204 typedef typename offsets_view_type::non_const_value_type value_type;
211 ComputeOffsetsFromConstantCount (
const offsets_view_type& offsets,
212 const count_type count) :
216 static_cast<size_type
> (0) :
217 static_cast<size_type> (
offsets_.extent (0) - 1))
221 KOKKOS_INLINE_FUNCTION
void init (value_type& dst)
const
227 KOKKOS_INLINE_FUNCTION
void
228 join (
volatile value_type& dst,
229 const volatile value_type& src)
const
235 KOKKOS_INLINE_FUNCTION
void
236 operator () (
const size_type& i, value_type& update,
const bool final)
const
280 template<
class OffsetsViewType,
281 class CountsViewType,
282 class SizeType =
typename OffsetsViewType::size_type>
283 typename OffsetsViewType::non_const_value_type
285 const CountsViewType& counts)
287 static_assert (Kokkos::Impl::is_view<OffsetsViewType>::value,
288 "OffsetsViewType (the type of ptr) must be a Kokkos::View.");
289 static_assert (Kokkos::Impl::is_view<CountsViewType>::value,
290 "CountsViewType (the type of counts) must be a Kokkos::View.");
291 static_assert (std::is_same<
typename OffsetsViewType::value_type,
292 typename OffsetsViewType::non_const_value_type>::value,
293 "OffsetsViewType (the type of ptr) must be a nonconst Kokkos::View.");
294 static_assert (static_cast<int> (OffsetsViewType::rank) == 1,
295 "OffsetsViewType (the type of ptr) must be a rank-1 Kokkos::View.");
296 static_assert (static_cast<int> (CountsViewType::rank) == 1,
297 "CountsViewType (the type of counts) must be a rank-1 Kokkos::View.");
298 static_assert (std::is_integral<typename OffsetsViewType::non_const_value_type>::value,
299 "The entries of ptr must be built-in integers.");
300 static_assert (std::is_integral<typename CountsViewType::non_const_value_type>::value,
301 "The entries of counts must be built-in integers.");
302 static_assert (std::is_integral<SizeType>::value,
303 "SizeType must be a built-in integer type.");
305 typedef typename CountsViewType::non_const_value_type count_type;
306 typedef typename OffsetsViewType::non_const_value_type offset_type;
307 typedef typename OffsetsViewType::device_type device_type;
308 typedef typename device_type::execution_space execution_space;
309 typedef typename device_type::memory_space memory_space;
311 const auto numOffsets = ptr.size ();
312 const auto numCounts = counts.size ();
313 if (numOffsets != 0) {
314 TEUCHOS_TEST_FOR_EXCEPTION
315 (numCounts >= numOffsets, std::invalid_argument,
316 "Tpetra::Details::computeOffsetsFromCounts: "
317 "counts.extent(0) = " << numCounts
318 <<
" >= ptr.extent(0) = " << numOffsets <<
".");
320 Kokkos::RangePolicy<execution_space, SizeType> range (0, numCounts+1);
330 constexpr
bool countsAccessibleFromOffsets =
331 Kokkos::Impl::VerifyExecutionCanAccessMemorySpace<memory_space,
332 typename CountsViewType::memory_space>::value;
333 if (countsAccessibleFromOffsets) {
334 #ifdef KOKKOS_ENABLE_CUDA
338 using counts_memory_space =
typename CountsViewType::memory_space;
339 if (std::is_same<counts_memory_space, Kokkos::CudaUVMSpace>::value) {
340 using counts_exec_space =
typename counts_memory_space::execution_space;
341 counts_exec_space::fence ();
343 #endif // KOKKOS_ENABLE_CUDA
344 typedef ComputeOffsetsFromCounts<OffsetsViewType, CountsViewType,
345 SizeType> functor_type;
347 functor_type functor (ptr, counts);
348 Kokkos::parallel_scan (range, functor);
354 typedef Kokkos::View<count_type*,
typename CountsViewType::array_layout,
355 device_type> dev_counts_type;
356 dev_counts_type counts_d (
"counts_d", numCounts);
359 typedef ComputeOffsetsFromCounts<OffsetsViewType, dev_counts_type,
360 SizeType> functor_type;
361 functor_type functor (ptr, counts_d);
362 Kokkos::parallel_scan (range, functor);
365 catch (std::exception& e) {
366 TEUCHOS_TEST_FOR_EXCEPTION
367 (
true, std::runtime_error,
368 "Tpetra::Details::computeOffsetsFromCounts: "
369 "Kokkos::parallel_scan (with device_type Kokkos::Device<"
370 <<
typeid (execution_space).name () <<
", "
371 <<
typeid (memory_space).name () <<
">) threw an std::exception: "
375 TEUCHOS_TEST_FOR_EXCEPTION
376 (
true, std::runtime_error,
377 "Tpetra::Details::computeOffsetsFromCounts: "
378 "Kokkos::parallel_scan threw an exception "
379 "not a subclass of std::exception");
382 return ::Tpetra::Details::getEntryOnHost (ptr, numCounts);
385 return static_cast<offset_type
> (0);
411 template<
class OffsetsViewType,
413 class SizeType =
typename OffsetsViewType::size_type>
414 typename OffsetsViewType::non_const_value_type
416 const CountType& count)
418 static_assert (Kokkos::Impl::is_view<OffsetsViewType>::value,
419 "OffsetsViewType (the type of ptr) must be a Kokkos::View.");
420 static_assert (std::is_same<
typename OffsetsViewType::value_type,
421 typename OffsetsViewType::non_const_value_type>::value,
422 "OffsetsViewType (the type of ptr) must be a nonconst Kokkos::View.");
423 static_assert (static_cast<int> (OffsetsViewType::rank) == 1,
424 "OffsetsViewType (the type of ptr) must be a rank-1 Kokkos::View.");
425 static_assert (std::is_integral<typename OffsetsViewType::non_const_value_type>::value,
426 "The entries of ptr must be built-in integers.");
427 static_assert (std::is_integral<CountType>::value,
428 "CountType must be a built-in integer type.");
429 static_assert (std::is_integral<SizeType>::value,
430 "SizeType must be a built-in integer type.");
432 typedef typename std::decay<CountType>::type count_type;
433 typedef typename OffsetsViewType::non_const_value_type offset_type;
434 typedef typename OffsetsViewType::device_type device_type;
435 typedef typename device_type::execution_space execution_space;
436 typedef typename device_type::memory_space memory_space;
438 const auto numOffsets = ptr.size ();
439 if (numOffsets != 0) {
440 ComputeOffsetsFromConstantCount<OffsetsViewType, count_type,
441 SizeType> functor (ptr, count);
442 Kokkos::RangePolicy<execution_space, SizeType> range (0, numOffsets);
444 Kokkos::parallel_scan (range, functor);
446 catch (std::exception& e) {
447 TEUCHOS_TEST_FOR_EXCEPTION
448 (
true, std::runtime_error,
"computeOffsetsFromConstantCount: "
449 "parallel_scan (with device_type Kokkos::Device<" <<
450 typeid (execution_space).name () <<
", " <<
451 typeid (memory_space).name () <<
">) threw an std::exception: "
455 TEUCHOS_TEST_FOR_EXCEPTION
456 (
true, std::runtime_error,
"Kokkos::parallel_scan threw an "
457 "exception not a subclass of std::exception");
460 return ::Tpetra::Details::getEntryOnHost (ptr, numOffsets - 1);
463 return static_cast<offset_type
> (0);
470 #endif // TPETRA_DETAILS_COMPUTEOFFSETS_HPP
counts_view_type counts_
Bucket counts (input argument).
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.
OffsetsViewType::non_const_value_type computeOffsetsFromCounts(const OffsetsViewType &ptr, const CountsViewType &counts)
Compute offsets from counts.
OffsetsViewType::non_const_value_type computeOffsetsFromConstantCount(const OffsetsViewType &ptr, const CountType &count)
Compute offsets from a constant count.
size_type size_
Number of entries in counts_.
Declaration and definition of Tpetra::Details::getEntryOnHost.
count_type count_
"Count" input argument