44 #ifndef TPETRA_DETAILS_COMPUTEOFFSETS_HPP 45 #define TPETRA_DETAILS_COMPUTEOFFSETS_HPP 53 #include "TpetraCore_config.h" 54 #include "Kokkos_Core.hpp" 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.dimension_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 143 offsets_[i] = update;
146 update += counts_[i];
152 offsets_view_type offsets_;
154 counts_view_type counts_;
176 template<
class OffsetsViewType,
178 class SizeType =
typename OffsetsViewType::size_type>
179 class ComputeOffsetsFromConstantCount {
181 static_assert (Kokkos::Impl::is_view<OffsetsViewType>::value,
182 "OffsetsViewType (the type of ptr) must be a Kokkos::View.");
183 static_assert (std::is_same<
typename OffsetsViewType::value_type,
184 typename OffsetsViewType::non_const_value_type>::value,
185 "OffsetsViewType (the type of ptr) must be a nonconst Kokkos::View.");
186 static_assert (static_cast<int> (OffsetsViewType::rank) == 1,
187 "OffsetsViewType (the type of ptr) must be a rank-1 Kokkos::View.");
188 static_assert (std::is_integral<typename OffsetsViewType::non_const_value_type>::value,
189 "The entries of ptr must be built-in integers.");
190 static_assert (std::is_integral<CountType>::value,
191 "CountType must be a built-in integer type.");
192 static_assert (std::is_integral<SizeType>::value,
193 "SizeType must be a built-in integer type.");
195 typedef OffsetsViewType offsets_view_type;
196 typedef CountType count_type;
197 typedef SizeType size_type;
198 typedef typename offsets_view_type::non_const_value_type value_type;
205 ComputeOffsetsFromConstantCount (
const offsets_view_type& offsets,
206 const count_type count) :
209 size_ (offsets_.dimension_0 () == 0 ?
210 static_cast<size_type> (0) :
211 static_cast<size_type> (offsets_.dimension_0 () - 1))
215 KOKKOS_INLINE_FUNCTION
void init (value_type& dst)
const 221 KOKKOS_INLINE_FUNCTION
void 222 join (
volatile value_type& dst,
223 const volatile value_type& src)
const 229 KOKKOS_INLINE_FUNCTION
void 230 operator () (
const size_type& i, value_type& update,
const bool final)
const 233 offsets_[i] = update;
242 offsets_view_type offsets_;
274 template<
class OffsetsViewType,
275 class CountsViewType,
276 class SizeType =
typename OffsetsViewType::size_type>
277 typename OffsetsViewType::non_const_value_type
279 const CountsViewType& counts)
281 static_assert (Kokkos::Impl::is_view<OffsetsViewType>::value,
282 "OffsetsViewType (the type of ptr) must be a Kokkos::View.");
283 static_assert (Kokkos::Impl::is_view<CountsViewType>::value,
284 "CountsViewType (the type of counts) must be a Kokkos::View.");
285 static_assert (std::is_same<
typename OffsetsViewType::value_type,
286 typename OffsetsViewType::non_const_value_type>::value,
287 "OffsetsViewType (the type of ptr) must be a nonconst Kokkos::View.");
288 static_assert (static_cast<int> (OffsetsViewType::rank) == 1,
289 "OffsetsViewType (the type of ptr) must be a rank-1 Kokkos::View.");
290 static_assert (static_cast<int> (CountsViewType::rank) == 1,
291 "CountsViewType (the type of counts) must be a rank-1 Kokkos::View.");
292 static_assert (std::is_integral<typename OffsetsViewType::non_const_value_type>::value,
293 "The entries of ptr must be built-in integers.");
294 static_assert (std::is_integral<typename CountsViewType::non_const_value_type>::value,
295 "The entries of counts must be built-in integers.");
296 static_assert (std::is_integral<SizeType>::value,
297 "SizeType must be a built-in integer type.");
299 typedef typename CountsViewType::non_const_value_type count_type;
300 typedef typename OffsetsViewType::non_const_value_type offset_type;
301 typedef typename OffsetsViewType::device_type device_type;
302 typedef typename device_type::execution_space execution_space;
303 typedef typename device_type::memory_space memory_space;
305 const auto numOffsets = ptr.size ();
306 const auto numCounts = counts.size ();
307 if (numOffsets != 0) {
308 TEUCHOS_TEST_FOR_EXCEPTION
309 (numCounts >= numOffsets, std::invalid_argument,
310 "computeOffsetsFromCounts: counts.dimension_0() = " << numCounts
311 <<
" >= ptr.dimension_0() = " << numOffsets <<
".");
313 Kokkos::RangePolicy<execution_space, SizeType> range (0, numCounts+1);
323 constexpr
bool countsAccessibleFromOffsets =
324 Kokkos::Impl::VerifyExecutionCanAccessMemorySpace<memory_space,
325 typename CountsViewType::memory_space>::value;
326 if (countsAccessibleFromOffsets) {
327 typedef ComputeOffsetsFromCounts<OffsetsViewType, CountsViewType,
328 SizeType> functor_type;
330 functor_type functor (ptr, counts);
331 Kokkos::parallel_scan (range, functor);
337 typedef Kokkos::View<count_type*,
typename CountsViewType::array_layout,
338 device_type> dev_counts_type;
339 dev_counts_type counts_d (
"counts_d", numCounts);
342 typedef ComputeOffsetsFromCounts<OffsetsViewType, dev_counts_type,
343 SizeType> functor_type;
344 functor_type functor (ptr, counts_d);
345 Kokkos::parallel_scan (range, functor);
348 catch (std::exception& e) {
349 TEUCHOS_TEST_FOR_EXCEPTION
350 (
true, std::runtime_error,
"computeOffsetsFromCounts: parallel_scan " 351 "(with device_type Kokkos::Device<" <<
352 typeid (execution_space).name () <<
", " <<
353 typeid (memory_space).name () <<
">) threw an std::exception: " 357 TEUCHOS_TEST_FOR_EXCEPTION
358 (
true, std::runtime_error,
"Kokkos::parallel_scan threw an " 359 "exception not a subclass of std::exception");
365 if (Kokkos::Impl::VerifyExecutionCanAccessMemorySpace<Kokkos::HostSpace,
366 memory_space>::value) {
367 return ptr[numCounts];
370 auto ptr_last = Kokkos::subview (ptr, numCounts);
371 auto ptr_last_h = Kokkos::create_mirror_view (ptr_last);
373 return ptr_last_h ();
377 return static_cast<offset_type
> (0);
403 template<
class OffsetsViewType,
405 class SizeType =
typename OffsetsViewType::size_type>
406 typename OffsetsViewType::non_const_value_type
408 const CountType& count)
410 static_assert (Kokkos::Impl::is_view<OffsetsViewType>::value,
411 "OffsetsViewType (the type of ptr) must be a Kokkos::View.");
412 static_assert (std::is_same<
typename OffsetsViewType::value_type,
413 typename OffsetsViewType::non_const_value_type>::value,
414 "OffsetsViewType (the type of ptr) must be a nonconst Kokkos::View.");
415 static_assert (static_cast<int> (OffsetsViewType::rank) == 1,
416 "OffsetsViewType (the type of ptr) must be a rank-1 Kokkos::View.");
417 static_assert (std::is_integral<typename OffsetsViewType::non_const_value_type>::value,
418 "The entries of ptr must be built-in integers.");
419 static_assert (std::is_integral<CountType>::value,
420 "CountType must be a built-in integer type.");
421 static_assert (std::is_integral<SizeType>::value,
422 "SizeType must be a built-in integer type.");
424 typedef typename std::decay<CountType>::type count_type;
425 typedef typename OffsetsViewType::non_const_value_type offset_type;
426 typedef typename OffsetsViewType::device_type device_type;
427 typedef typename device_type::execution_space execution_space;
428 typedef typename device_type::memory_space memory_space;
430 const auto numOffsets = ptr.size ();
431 if (numOffsets != 0) {
432 ComputeOffsetsFromConstantCount<OffsetsViewType, count_type,
433 SizeType> functor (ptr, count);
434 Kokkos::RangePolicy<execution_space, SizeType> range (0, numOffsets);
436 #ifdef KOKKOS_HAVE_CUDA 437 constexpr
bool isCuda = std::is_same<execution_space, Kokkos::Cuda>::value;
439 constexpr
bool isCuda =
false;
440 #endif // KOKKOS_HAVE_CUDA 445 Kokkos::parallel_scan (numOffsets, functor);
448 Kokkos::parallel_scan (range, functor);
451 catch (std::exception& e) {
452 TEUCHOS_TEST_FOR_EXCEPTION
453 (
true, std::runtime_error,
"computeOffsetsFromConstantCount: " 454 "parallel_scan (with device_type Kokkos::Device<" <<
455 typeid (execution_space).name () <<
", " <<
456 typeid (memory_space).name () <<
">) threw an std::exception: " 460 TEUCHOS_TEST_FOR_EXCEPTION
461 (
true, std::runtime_error,
"Kokkos::parallel_scan threw an " 462 "exception not a subclass of std::exception");
468 if (Kokkos::Impl::VerifyExecutionCanAccessMemorySpace<Kokkos::HostSpace,
469 memory_space>::value) {
470 return ptr[numOffsets - 1];
473 auto ptr_last = Kokkos::subview (ptr, numOffsets - 1);
474 auto ptr_last_h = Kokkos::create_mirror_view (ptr_last);
476 return ptr_last_h ();
480 return static_cast<offset_type
> (0);
487 #endif // TPETRA_DETAILS_COMPUTEOFFSETS_HPP Namespace Tpetra contains the class and methods constituting the Tpetra library.
void deep_copy(MultiVector< DS, DL, DG, DN, dstClassic > &dst, const MultiVector< SS, SL, SG, SN, srcClassic > &src)
Copy the contents of the MultiVector src into dst.
Implementation details of Tpetra.
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.