49 #ifndef TPETRA_KOKKOS_REFACTOR_DETAILS_MULTI_VECTOR_DIST_OBJECT_KERNELS_HPP 50 #define TPETRA_KOKKOS_REFACTOR_DETAILS_MULTI_VECTOR_DIST_OBJECT_KERNELS_HPP 52 #include "Kokkos_Core.hpp" 53 #include "Kokkos_ArithTraits.hpp" 58 namespace KokkosRefactor {
74 template<
class IntegerType,
75 const bool isSigned = std::numeric_limits<IntegerType>::is_signed>
77 static KOKKOS_INLINE_FUNCTION
bool 78 test (
const IntegerType x,
79 const IntegerType exclusiveUpperBound);
83 template<
class IntegerType>
85 static KOKKOS_INLINE_FUNCTION
bool 86 test (
const IntegerType x,
87 const IntegerType exclusiveUpperBound)
89 return x < static_cast<IntegerType> (0) || x >= exclusiveUpperBound;
94 template<
class IntegerType>
96 static KOKKOS_INLINE_FUNCTION
bool 97 test (
const IntegerType x,
98 const IntegerType exclusiveUpperBound)
100 return x >= exclusiveUpperBound;
106 template<
class IntegerType>
107 KOKKOS_INLINE_FUNCTION
bool 108 outOfBounds (
const IntegerType x,
const IntegerType exclusiveUpperBound)
118 template <
typename DstView,
typename SrcView,
typename IdxView>
119 struct PackArraySingleColumn {
120 typedef typename DstView::execution_space execution_space;
121 typedef typename execution_space::size_type size_type;
128 PackArraySingleColumn(
const DstView& dst_,
132 dst(dst_), src(src_), idx(idx_), col(col_) {}
134 KOKKOS_INLINE_FUNCTION
135 void operator()(
const size_type k )
const {
136 dst(k) = src(idx(k), col);
140 pack (
const DstView& dst,
145 typedef Kokkos::RangePolicy<execution_space, size_type> range_type;
146 Kokkos::parallel_for (range_type (0, idx.size ()),
147 PackArraySingleColumn (dst,src,idx,col));
151 template <
typename DstView,
154 typename SizeType =
typename DstView::execution_space::size_type>
155 class PackArraySingleColumnWithBoundsCheck {
157 static_assert (Kokkos::Impl::is_view<DstView>::value,
158 "DstView must be a Kokkos::View.");
159 static_assert (Kokkos::Impl::is_view<SrcView>::value,
160 "SrcView must be a Kokkos::View.");
161 static_assert (Kokkos::Impl::is_view<IdxView>::value,
162 "IdxView must be a Kokkos::View.");
163 static_assert (static_cast<int> (DstView::rank) == 1,
164 "DstView must be a rank-1 Kokkos::View.");
165 static_assert (static_cast<int> (SrcView::rank) == 2,
166 "SrcView must be a rank-2 Kokkos::View.");
167 static_assert (static_cast<int> (IdxView::rank) == 1,
168 "IdxView must be a rank-1 Kokkos::View.");
169 static_assert (std::is_integral<SizeType>::value,
170 "SizeType must be a built-in integer type.");
172 typedef SizeType size_type;
174 typedef int value_type;
183 PackArraySingleColumnWithBoundsCheck (
const DstView& dst_,
186 const size_type col_) :
187 dst (dst_), src (src_), idx (idx_), col (col_) {}
189 KOKKOS_INLINE_FUNCTION
void 190 operator() (
const size_type& k, value_type& result)
const {
191 typedef typename IdxView::non_const_value_type index_type;
193 const index_type lclRow = idx(k);
194 if (lclRow < static_cast<index_type> (0) ||
195 lclRow >= static_cast<index_type> (src.dimension_0 ())) {
199 dst(k) = src(lclRow, col);
203 KOKKOS_INLINE_FUNCTION
204 void init (value_type& initialResult)
const {
208 KOKKOS_INLINE_FUNCTION
void 209 join (
volatile value_type& dstResult,
210 const volatile value_type& srcResult)
const 212 dstResult = (dstResult == 0 || srcResult == 0) ? 0 : 1;
216 pack (
const DstView& dst,
221 typedef typename DstView::execution_space execution_space;
222 typedef Kokkos::RangePolicy<execution_space, size_type> range_type;
223 typedef typename IdxView::non_const_value_type index_type;
226 Kokkos::parallel_reduce (range_type (0, idx.size ()),
227 PackArraySingleColumnWithBoundsCheck (dst, src,
234 auto idx_h = Kokkos::create_mirror_view (idx);
237 std::vector<index_type> badIndices;
238 const size_type numInds = idx_h.dimension_0 ();
239 for (size_type k = 0; k < numInds; ++k) {
240 if (idx_h(k) < static_cast<index_type> (0) ||
241 idx_h(k) >= static_cast<index_type> (src.dimension_0 ())) {
242 badIndices.push_back (idx_h(k));
246 std::ostringstream os;
247 os <<
"MultiVector single-column pack kernel had " 248 << badIndices.size () <<
" out-of bounds index/ices. " 250 for (
size_t k = 0; k < badIndices.size (); ++k) {
252 if (k + 1 < badIndices.size ()) {
257 throw std::runtime_error (os.str ());
263 template <
typename DstView,
typename SrcView,
typename IdxView>
265 pack_array_single_column (
const DstView& dst,
269 const bool debug =
true)
271 static_assert (Kokkos::Impl::is_view<DstView>::value,
272 "DstView must be a Kokkos::View.");
273 static_assert (Kokkos::Impl::is_view<SrcView>::value,
274 "SrcView must be a Kokkos::View.");
275 static_assert (Kokkos::Impl::is_view<IdxView>::value,
276 "IdxView must be a Kokkos::View.");
277 static_assert (static_cast<int> (DstView::rank) == 1,
278 "DstView must be a rank-1 Kokkos::View.");
279 static_assert (static_cast<int> (SrcView::rank) == 2,
280 "SrcView must be a rank-2 Kokkos::View.");
281 static_assert (static_cast<int> (IdxView::rank) == 1,
282 "IdxView must be a rank-1 Kokkos::View.");
285 typedef PackArraySingleColumnWithBoundsCheck<DstView,SrcView,IdxView> impl_type;
286 impl_type::pack (dst, src, idx, col);
289 typedef PackArraySingleColumn<DstView,SrcView,IdxView> impl_type;
290 impl_type::pack (dst, src, idx, col);
294 template <
typename DstView,
typename SrcView,
typename IdxView>
295 struct PackArrayMultiColumn {
296 typedef typename DstView::execution_space execution_space;
297 typedef typename execution_space::size_type size_type;
304 PackArrayMultiColumn(
const DstView& dst_,
308 dst(dst_), src(src_), idx(idx_), numCols(numCols_) {}
310 KOKKOS_INLINE_FUNCTION
311 void operator()(
const size_type k )
const {
312 const typename IdxView::value_type localRow = idx(k);
313 const size_t offset = k*numCols;
314 for (
size_t j = 0; j < numCols; ++j)
315 dst(offset + j) = src(localRow, j);
318 static void pack(
const DstView& dst,
322 typedef Kokkos::RangePolicy<execution_space, size_type> range_type;
323 Kokkos::parallel_for (range_type (0, idx.size ()),
324 PackArrayMultiColumn (dst,src,idx,numCols));
328 template <
typename DstView,
331 typename SizeType =
typename DstView::execution_space::size_type>
332 class PackArrayMultiColumnWithBoundsCheck {
334 typedef SizeType size_type;
336 typedef int value_type;
345 PackArrayMultiColumnWithBoundsCheck (
const DstView& dst_,
348 const size_type numCols_) :
349 dst (dst_), src (src_), idx (idx_), numCols (numCols_) {}
351 KOKKOS_INLINE_FUNCTION
void 352 operator() (
const size_type& k, value_type& result)
const {
353 typedef typename IdxView::non_const_value_type index_type;
355 const index_type lclRow = idx(k);
356 if (lclRow < static_cast<index_type> (0) ||
357 lclRow >= static_cast<index_type> (src.dimension_0 ())) {
361 const size_type offset = k*numCols;
362 for (size_type j = 0; j < numCols; ++j) {
363 dst(offset + j) = src(lclRow, j);
368 KOKKOS_INLINE_FUNCTION
369 void init (value_type& initialResult)
const {
373 KOKKOS_INLINE_FUNCTION
void 374 join (
volatile value_type& dstResult,
375 const volatile value_type& srcResult)
const 377 dstResult = (dstResult == 0 || srcResult == 0) ? 0 : 1;
381 pack (
const DstView& dst,
384 const size_type numCols)
386 typedef typename DstView::execution_space execution_space;
387 typedef Kokkos::RangePolicy<execution_space, size_type> range_type;
388 typedef typename IdxView::non_const_value_type index_type;
391 Kokkos::parallel_reduce (range_type (0, idx.size ()),
392 PackArrayMultiColumnWithBoundsCheck (dst, src,
399 auto idx_h = Kokkos::create_mirror_view (idx);
402 std::vector<index_type> badIndices;
403 const size_type numInds = idx_h.dimension_0 ();
404 for (size_type k = 0; k < numInds; ++k) {
405 if (idx_h(k) < static_cast<index_type> (0) ||
406 idx_h(k) >= static_cast<index_type> (src.dimension_0 ())) {
407 badIndices.push_back (idx_h(k));
411 std::ostringstream os;
412 os <<
"MultiVector multiple-column pack kernel had " 413 << badIndices.size () <<
" out-of bounds index/ices. " 415 for (
size_t k = 0; k < badIndices.size (); ++k) {
417 if (k + 1 < badIndices.size ()) {
422 throw std::runtime_error (os.str ());
428 template <
typename DstView,
432 pack_array_multi_column (
const DstView& dst,
435 const size_t numCols,
436 const bool debug =
true)
438 static_assert (Kokkos::Impl::is_view<DstView>::value,
439 "DstView must be a Kokkos::View.");
440 static_assert (Kokkos::Impl::is_view<SrcView>::value,
441 "SrcView must be a Kokkos::View.");
442 static_assert (Kokkos::Impl::is_view<IdxView>::value,
443 "IdxView must be a Kokkos::View.");
444 static_assert (static_cast<int> (DstView::rank) == 1,
445 "DstView must be a rank-1 Kokkos::View.");
446 static_assert (static_cast<int> (SrcView::rank) == 2,
447 "SrcView must be a rank-2 Kokkos::View.");
448 static_assert (static_cast<int> (IdxView::rank) == 1,
449 "IdxView must be a rank-1 Kokkos::View.");
452 typedef PackArrayMultiColumnWithBoundsCheck<DstView,
453 SrcView, IdxView> impl_type;
454 impl_type::pack (dst, src, idx, numCols);
457 typedef PackArrayMultiColumn<DstView, SrcView, IdxView> impl_type;
458 impl_type::pack (dst, src, idx, numCols);
462 template <
typename DstView,
typename SrcView,
typename IdxView,
464 struct PackArrayMultiColumnVariableStride {
465 typedef typename DstView::execution_space execution_space;
466 typedef typename execution_space::size_type size_type;
474 PackArrayMultiColumnVariableStride(
const DstView& dst_,
479 dst(dst_), src(src_), idx(idx_), col(col_), numCols(numCols_) {}
481 KOKKOS_INLINE_FUNCTION
482 void operator()(
const size_type k )
const {
483 const typename IdxView::value_type localRow = idx(k);
484 const size_t offset = k*numCols;
485 for (
size_t j = 0; j < numCols; ++j)
486 dst(offset + j) = src(localRow, col(j));
489 static void pack(
const DstView& dst,
494 typedef Kokkos::RangePolicy<execution_space, size_type> range_type;
495 Kokkos::parallel_for (range_type (0, idx.size ()),
496 PackArrayMultiColumnVariableStride(
497 dst,src,idx,col,numCols) );
501 template <
typename DstView,
505 typename SizeType =
typename DstView::execution_space::size_type>
506 class PackArrayMultiColumnVariableStrideWithBoundsCheck {
508 typedef SizeType size_type;
510 typedef Kokkos::pair<int, int> value_type;
520 PackArrayMultiColumnVariableStrideWithBoundsCheck (
const DstView& dst_,
524 const size_type numCols_) :
525 dst (dst_), src (src_), idx (idx_), col (col_), numCols (numCols_) {}
527 KOKKOS_INLINE_FUNCTION
void 528 operator() (
const size_type& k, value_type& result)
const {
529 typedef typename IdxView::non_const_value_type row_index_type;
530 typedef typename ColView::non_const_value_type col_index_type;
532 const row_index_type lclRow = idx(k);
533 if (lclRow < static_cast<row_index_type> (0) ||
534 lclRow >= static_cast<row_index_type> (src.dimension_0 ())) {
538 const size_type offset = k*numCols;
539 for (size_type j = 0; j < numCols; ++j) {
540 const col_index_type lclCol = col(j);
541 if (Impl::outOfBounds<col_index_type> (lclCol, src.dimension_1 ())) {
545 dst(offset + j) = src(lclRow, lclCol);
551 KOKKOS_INLINE_FUNCTION
void 552 init (value_type& initialResult)
const {
553 initialResult.first = 1;
554 initialResult.second = 1;
557 KOKKOS_INLINE_FUNCTION
void 558 join (
volatile value_type& dstResult,
559 const volatile value_type& srcResult)
const 561 dstResult.first = (dstResult.first == 0 || srcResult.first == 0) ? 0 : 1;
562 dstResult.second = (dstResult.second == 0 || srcResult.second == 0) ? 0 : 1;
566 pack (
const DstView& dst,
570 const size_type numCols)
572 using Kokkos::parallel_reduce;
573 typedef typename DstView::execution_space execution_space;
574 typedef Kokkos::RangePolicy<execution_space, size_type> range_type;
575 typedef typename IdxView::non_const_value_type row_index_type;
576 typedef typename ColView::non_const_value_type col_index_type;
578 Kokkos::pair<int, int> result (1, 1);
579 parallel_reduce (range_type (0, idx.size ()),
580 PackArrayMultiColumnVariableStrideWithBoundsCheck (dst, src,
584 const bool hasBadRows = (result.first != 1);
585 const bool hasBadCols = (result.second != 1);
586 const bool hasErr = hasBadRows || hasBadCols;
588 std::ostringstream os;
594 auto idx_h = Kokkos::create_mirror_view (idx);
597 std::vector<row_index_type> badRows;
598 const size_type numInds = idx_h.dimension_0 ();
599 for (size_type k = 0; k < numInds; ++k) {
600 if (Impl::outOfBounds<row_index_type> (idx_h(k), src.dimension_0 ())) {
601 badRows.push_back (idx_h(k));
604 os <<
"MultiVector multiple-column pack kernel had " 605 << badRows.size () <<
" out-of bounds row index/ices: [";
606 for (
size_t k = 0; k < badRows.size (); ++k) {
608 if (k + 1 < badRows.size ()) {
620 auto col_h = Kokkos::create_mirror_view (col);
623 std::vector<col_index_type> badCols;
624 const size_type numInds = col_h.dimension_0 ();
625 for (size_type k = 0; k < numInds; ++k) {
626 if (Impl::outOfBounds<col_index_type> (col_h(k), src.dimension_1 ())) {
627 badCols.push_back (col_h(k));
634 os <<
"MultiVector multiple-column pack kernel had " 635 << badCols.size () <<
" out-of bounds column index/ices: [";
636 for (
size_t k = 0; k < badCols.size (); ++k) {
638 if (k + 1 < badCols.size ()) {
645 throw std::runtime_error (os.str ());
650 template <
typename DstView,
655 pack_array_multi_column_variable_stride (
const DstView& dst,
659 const size_t numCols,
660 const bool debug =
true)
662 static_assert (Kokkos::Impl::is_view<DstView>::value,
663 "DstView must be a Kokkos::View.");
664 static_assert (Kokkos::Impl::is_view<SrcView>::value,
665 "SrcView must be a Kokkos::View.");
666 static_assert (Kokkos::Impl::is_view<IdxView>::value,
667 "IdxView must be a Kokkos::View.");
668 static_assert (Kokkos::Impl::is_view<ColView>::value,
669 "ColView must be a Kokkos::View.");
670 static_assert (static_cast<int> (DstView::rank) == 1,
671 "DstView must be a rank-1 Kokkos::View.");
672 static_assert (static_cast<int> (SrcView::rank) == 2,
673 "SrcView must be a rank-2 Kokkos::View.");
674 static_assert (static_cast<int> (IdxView::rank) == 1,
675 "IdxView must be a rank-1 Kokkos::View.");
676 static_assert (static_cast<int> (ColView::rank) == 1,
677 "ColView must be a rank-1 Kokkos::View.");
680 typedef PackArrayMultiColumnVariableStrideWithBoundsCheck<DstView,
681 SrcView, IdxView, ColView> impl_type;
682 impl_type::pack (dst, src, idx, col, numCols);
685 typedef PackArrayMultiColumnVariableStride<DstView,
686 SrcView, IdxView, ColView> impl_type;
687 impl_type::pack (dst, src, idx, col, numCols);
699 template<
class ExecutionSpace>
701 template <
typename Scalar>
702 KOKKOS_INLINE_FUNCTION
703 void operator() (Scalar& dest,
const Scalar& src)
const {
704 Kokkos::atomic_assign(&dest, src);
708 #ifdef KOKKOS_HAVE_SERIAL 710 struct InsertOp< ::Kokkos::Serial > {
711 template <
typename Scalar>
712 KOKKOS_INLINE_FUNCTION
713 void operator() (Scalar& dest,
const Scalar& src)
const {
717 #endif // KOKKOS_HAVE_SERIAL 719 template<
class ExecutionSpace>
721 template <
typename Scalar>
722 KOKKOS_INLINE_FUNCTION
723 void operator() (Scalar& dest,
const Scalar& src)
const {
724 Kokkos::atomic_add(&dest, src);
728 #ifdef KOKKOS_HAVE_SERIAL 730 struct AddOp< ::Kokkos::Serial > {
731 template <
typename Scalar>
732 KOKKOS_INLINE_FUNCTION
733 void operator() (Scalar& dest,
const Scalar& src)
const {
737 #endif // KOKKOS_HAVE_SERIAL 739 template<
class ExecutionSpace>
747 template <
typename T>
748 KOKKOS_INLINE_FUNCTION
749 T max(
const T& a,
const T& b)
const {
return a > b ? a : b; }
751 template <
typename Scalar>
752 KOKKOS_INLINE_FUNCTION
753 void operator() (Scalar& dest,
const Scalar& src)
const {
754 typedef Kokkos::Details::ArithTraits<Scalar> SCT;
755 Kokkos::atomic_assign(&dest, Scalar(max(SCT::abs(dest),SCT::abs(src))));
759 #ifdef KOKKOS_HAVE_SERIAL 761 struct AbsMaxOp< ::Kokkos::Serial > {
768 template <
typename T>
769 KOKKOS_INLINE_FUNCTION
770 T max(
const T& a,
const T& b)
const {
return a > b ? a : b; }
772 template <
typename Scalar>
773 KOKKOS_INLINE_FUNCTION
774 void operator() (Scalar& dest,
const Scalar& src)
const {
775 typedef Kokkos::Details::ArithTraits<Scalar> SCT;
777 dest =
static_cast<Scalar
> (max (SCT::abs (dest), SCT::abs (src)));
780 #endif // KOKKOS_HAVE_SERIAL 782 template <
typename DstView,
typename SrcView,
typename IdxView,
typename Op>
783 struct UnpackArrayMultiColumn {
784 typedef typename DstView::execution_space execution_space;
785 typedef typename execution_space::size_type size_type;
793 UnpackArrayMultiColumn(
const DstView& dst_,
798 dst(dst_), src(src_), idx(idx_), op(op_), numCols(numCols_) {}
800 KOKKOS_INLINE_FUNCTION
801 void operator()(
const size_type k )
const {
802 const typename IdxView::value_type localRow = idx(k);
803 const size_t offset = k*numCols;
804 for (
size_t j = 0; j < numCols; ++j)
805 op( dst(localRow,j), src(offset+j) );
808 static void unpack(
const DstView& dst,
813 typedef Kokkos::RangePolicy<execution_space, size_type> range_type;
814 Kokkos::parallel_for (range_type (0, idx.size ()),
815 UnpackArrayMultiColumn (dst,src,idx,op,numCols));
819 template <
typename DstView,
823 typename SizeType =
typename DstView::execution_space::size_type>
824 class UnpackArrayMultiColumnWithBoundsCheck {
825 static_assert (Kokkos::Impl::is_view<DstView>::value,
826 "DstView must be a Kokkos::View.");
827 static_assert (Kokkos::Impl::is_view<SrcView>::value,
828 "SrcView must be a Kokkos::View.");
829 static_assert (Kokkos::Impl::is_view<IdxView>::value,
830 "IdxView must be a Kokkos::View.");
831 static_assert (static_cast<int> (DstView::rank) == 2,
832 "DstView must be a rank-2 Kokkos::View.");
833 static_assert (static_cast<int> (SrcView::rank) == 1,
834 "SrcView must be a rank-1 Kokkos::View.");
835 static_assert (static_cast<int> (IdxView::rank) == 1,
836 "IdxView must be a rank-1 Kokkos::View.");
837 static_assert (std::is_integral<SizeType>::value,
838 "SizeType must be a built-in integer type.");
841 typedef SizeType size_type;
843 typedef int value_type;
853 UnpackArrayMultiColumnWithBoundsCheck (
const DstView& dst_,
857 const size_type numCols_) :
858 dst (dst_), src (src_), idx (idx_), op (op_), numCols (numCols_)
861 KOKKOS_INLINE_FUNCTION
862 void operator() (
const size_type& k, value_type& result)
const {
863 typedef typename IdxView::non_const_value_type index_type;
865 const index_type lclRow = idx(k);
866 if (lclRow < static_cast<index_type> (0) ||
867 lclRow >= static_cast<index_type> (dst.dimension_0 ())) {
871 const size_type offset = k*numCols;
872 for (size_type j = 0; j < numCols; ++j)
873 op (dst(lclRow,j), src(offset+j));
877 KOKKOS_INLINE_FUNCTION
878 void init (value_type& initialResult)
const {
882 KOKKOS_INLINE_FUNCTION
void 883 join (
volatile value_type& dstResult,
884 const volatile value_type& srcResult)
const 886 dstResult = (dstResult == 0 || srcResult == 0) ? 0 : 1;
890 unpack (
const DstView& dst,
894 const size_type numCols)
896 typedef typename DstView::execution_space execution_space;
897 typedef Kokkos::RangePolicy<execution_space, size_type> range_type;
898 typedef typename IdxView::non_const_value_type index_type;
901 Kokkos::parallel_reduce (range_type (0, idx.size ()),
902 UnpackArrayMultiColumnWithBoundsCheck (dst,src,idx,op,numCols),
908 auto idx_h = Kokkos::create_mirror_view (idx);
911 std::vector<index_type> badIndices;
912 const size_type numInds = idx_h.dimension_0 ();
913 for (size_type k = 0; k < numInds; ++k) {
914 if (idx_h(k) < static_cast<index_type> (0) ||
915 idx_h(k) >= static_cast<index_type> (dst.dimension_0 ())) {
916 badIndices.push_back (idx_h(k));
920 std::ostringstream os;
921 os <<
"MultiVector unpack kernel had " << badIndices.size ()
922 <<
" out-of bounds index/ices. Here they are: [";
923 for (
size_t k = 0; k < badIndices.size (); ++k) {
925 if (k + 1 < badIndices.size ()) {
930 throw std::runtime_error (os.str ());
935 template <
typename DstView,
typename SrcView,
typename IdxView,
typename Op>
937 unpack_array_multi_column (
const DstView& dst,
941 const size_t numCols,
942 const bool debug =
true)
944 static_assert (Kokkos::Impl::is_view<DstView>::value,
945 "DstView must be a Kokkos::View.");
946 static_assert (Kokkos::Impl::is_view<SrcView>::value,
947 "SrcView must be a Kokkos::View.");
948 static_assert (Kokkos::Impl::is_view<IdxView>::value,
949 "IdxView must be a Kokkos::View.");
950 static_assert (static_cast<int> (DstView::rank) == 2,
951 "DstView must be a rank-2 Kokkos::View.");
952 static_assert (static_cast<int> (SrcView::rank) == 1,
953 "SrcView must be a rank-1 Kokkos::View.");
954 static_assert (static_cast<int> (IdxView::rank) == 1,
955 "IdxView must be a rank-1 Kokkos::View.");
958 typedef UnpackArrayMultiColumnWithBoundsCheck<DstView,
959 SrcView, IdxView, Op> impl_type;
960 impl_type::unpack (dst, src, idx, op, numCols);
963 typedef UnpackArrayMultiColumn<DstView,
964 SrcView, IdxView, Op> impl_type;
965 impl_type::unpack (dst, src, idx, op, numCols);
969 template <
typename DstView,
typename SrcView,
typename IdxView,
970 typename ColView,
typename Op>
971 struct UnpackArrayMultiColumnVariableStride {
972 typedef typename DstView::execution_space execution_space;
973 typedef typename execution_space::size_type size_type;
982 UnpackArrayMultiColumnVariableStride(
const DstView& dst_,
988 dst(dst_), src(src_), idx(idx_), col(col_), op(op_), numCols(numCols_) {}
990 KOKKOS_INLINE_FUNCTION
991 void operator()(
const size_type k )
const {
992 const typename IdxView::value_type localRow = idx(k);
993 const size_t offset = k*numCols;
994 for (
size_t j = 0; j < numCols; ++j)
995 op( dst(localRow,col(j)), src(offset+j) );
998 static void unpack(
const DstView& dst,
1004 typedef Kokkos::RangePolicy<execution_space, size_type> range_type;
1005 Kokkos::parallel_for (range_type (0, idx.size ()),
1006 UnpackArrayMultiColumnVariableStride(
1007 dst,src,idx,col,op,numCols) );
1011 template <
typename DstView,
1016 typename SizeType =
typename DstView::execution_space::size_type>
1017 class UnpackArrayMultiColumnVariableStrideWithBoundsCheck {
1019 typedef SizeType size_type;
1021 typedef Kokkos::pair<int, int> value_type;
1032 UnpackArrayMultiColumnVariableStrideWithBoundsCheck (
const DstView& dst_,
1033 const SrcView& src_,
1034 const IdxView& idx_,
1035 const ColView& col_,
1037 const size_t numCols_) :
1038 dst (dst_), src (src_), idx (idx_), col (col_), op (op_),
1042 KOKKOS_INLINE_FUNCTION
void 1043 operator() (
const size_type& k, value_type& result)
const {
1044 typedef typename IdxView::non_const_value_type row_index_type;
1045 typedef typename ColView::non_const_value_type col_index_type;
1047 const row_index_type lclRow = idx(k);
1048 if (lclRow < static_cast<row_index_type> (0) ||
1049 lclRow >= static_cast<row_index_type> (dst.dimension_0 ())) {
1053 const size_type offset = k*numCols;
1054 for (size_type j = 0; j < numCols; ++j) {
1055 const col_index_type lclCol = col(j);
1057 if (Impl::outOfBounds<col_index_type> (lclCol, dst.dimension_1 ())) {
1061 op (dst(lclRow, col(j)), src(offset+j));
1067 KOKKOS_INLINE_FUNCTION
void 1068 init (value_type& initialResult)
const {
1069 initialResult.first = 1;
1070 initialResult.second = 1;
1073 KOKKOS_INLINE_FUNCTION
void 1074 join (
volatile value_type& dstResult,
1075 const volatile value_type& srcResult)
const 1077 dstResult.first = (dstResult.first == 0 || srcResult.first == 0) ? 0 : 1;
1078 dstResult.second = (dstResult.second == 0 || srcResult.second == 0) ? 0 : 1;
1082 unpack (
const DstView& dst,
1087 const size_type numCols)
1089 typedef typename DstView::execution_space execution_space;
1090 typedef Kokkos::RangePolicy<execution_space, size_type> range_type;
1091 typedef typename IdxView::non_const_value_type row_index_type;
1092 typedef typename ColView::non_const_value_type col_index_type;
1094 Kokkos::pair<int, int> result (1, 1);
1095 Kokkos::parallel_reduce (range_type (0, idx.size ()),
1096 UnpackArrayMultiColumnVariableStrideWithBoundsCheck (dst, src, idx,
1100 const bool hasBadRows = (result.first != 1);
1101 const bool hasBadCols = (result.second != 1);
1102 const bool hasErr = hasBadRows || hasBadCols;
1104 std::ostringstream os;
1111 auto idx_h = Kokkos::create_mirror_view (idx);
1114 std::vector<row_index_type> badRows;
1115 const size_type numInds = idx_h.dimension_0 ();
1116 for (size_type k = 0; k < numInds; ++k) {
1117 if (idx_h(k) < static_cast<row_index_type> (0) ||
1118 idx_h(k) >= static_cast<row_index_type> (dst.dimension_0 ())) {
1119 badRows.push_back (idx_h(k));
1122 os <<
"MultiVector multiple-column unpack kernel had " 1123 << badRows.size () <<
" out-of bounds row index/ices: [";
1124 for (
size_t k = 0; k < badRows.size (); ++k) {
1126 if (k + 1 < badRows.size ()) {
1138 auto col_h = Kokkos::create_mirror_view (col);
1141 std::vector<col_index_type> badCols;
1142 const size_type numInds = col_h.dimension_0 ();
1143 for (size_type k = 0; k < numInds; ++k) {
1144 if (Impl::outOfBounds<col_index_type> (col_h(k), dst.dimension_1 ())) {
1145 badCols.push_back (col_h(k));
1152 os <<
"MultiVector multiple-column unpack kernel had " 1153 << badCols.size () <<
" out-of bounds column index/ices: [";
1154 for (
size_t k = 0; k < badCols.size (); ++k) {
1156 if (k + 1 < badCols.size ()) {
1163 throw std::runtime_error (os.str ());
1168 template <
typename DstView,
1174 unpack_array_multi_column_variable_stride (
const DstView& dst,
1179 const size_t numCols,
1180 const bool debug =
true)
1182 static_assert (Kokkos::Impl::is_view<DstView>::value,
1183 "DstView must be a Kokkos::View.");
1184 static_assert (Kokkos::Impl::is_view<SrcView>::value,
1185 "SrcView must be a Kokkos::View.");
1186 static_assert (Kokkos::Impl::is_view<IdxView>::value,
1187 "IdxView must be a Kokkos::View.");
1188 static_assert (Kokkos::Impl::is_view<ColView>::value,
1189 "ColView must be a Kokkos::View.");
1190 static_assert (static_cast<int> (DstView::rank) == 2,
1191 "DstView must be a rank-2 Kokkos::View.");
1192 static_assert (static_cast<int> (SrcView::rank) == 1,
1193 "SrcView must be a rank-1 Kokkos::View.");
1194 static_assert (static_cast<int> (IdxView::rank) == 1,
1195 "IdxView must be a rank-1 Kokkos::View.");
1196 static_assert (static_cast<int> (ColView::rank) == 1,
1197 "ColView must be a rank-1 Kokkos::View.");
1200 typedef UnpackArrayMultiColumnVariableStrideWithBoundsCheck<DstView,
1201 SrcView, IdxView, ColView, Op> impl_type;
1202 impl_type::unpack (dst, src, idx, col, op, numCols);
1205 typedef UnpackArrayMultiColumnVariableStride<DstView,
1206 SrcView, IdxView, ColView, Op> impl_type;
1207 impl_type::unpack (dst, src, idx, col, op, numCols);
1211 template <
typename DstView,
typename SrcView,
1212 typename DstIdxView,
typename SrcIdxView>
1213 struct PermuteArrayMultiColumn {
1214 typedef typename DstView::execution_space execution_space;
1215 typedef typename execution_space::size_type size_type;
1223 PermuteArrayMultiColumn(
const DstView& dst_,
1224 const SrcView& src_,
1225 const DstIdxView& dst_idx_,
1226 const SrcIdxView& src_idx_,
1228 dst(dst_), src(src_), dst_idx(dst_idx_), src_idx(src_idx_),
1229 numCols(numCols_) {}
1231 KOKKOS_INLINE_FUNCTION
1232 void operator()(
const size_type k )
const {
1233 const typename DstIdxView::value_type toRow = dst_idx(k);
1234 const typename SrcIdxView::value_type fromRow = src_idx(k);
1235 for (
size_t j = 0; j < numCols; ++j)
1236 dst(toRow, j) = src(fromRow, j);
1239 static void permute(
const DstView& dst,
1241 const DstIdxView& dst_idx,
1242 const SrcIdxView& src_idx,
1244 const size_type n = std::min( dst_idx.size(), src_idx.size() );
1245 typedef Kokkos::RangePolicy<execution_space, size_type> range_type;
1246 Kokkos::parallel_for (range_type (0, n),
1247 PermuteArrayMultiColumn (dst,src,dst_idx,src_idx,numCols));
1253 template <
typename DstView,
typename SrcView,
1254 typename DstIdxView,
typename SrcIdxView>
1255 void permute_array_multi_column(
const DstView& dst,
1257 const DstIdxView& dst_idx,
1258 const SrcIdxView& src_idx,
1260 PermuteArrayMultiColumn<DstView,SrcView,DstIdxView,SrcIdxView>::permute(
1261 dst, src, dst_idx, src_idx, numCols);
1264 template <
typename DstView,
typename SrcView,
1265 typename DstIdxView,
typename SrcIdxView,
1266 typename DstColView,
typename SrcColView>
1267 struct PermuteArrayMultiColumnVariableStride {
1268 typedef typename DstView::execution_space execution_space;
1269 typedef typename execution_space::size_type size_type;
1279 PermuteArrayMultiColumnVariableStride(
const DstView& dst_,
1280 const SrcView& src_,
1281 const DstIdxView& dst_idx_,
1282 const SrcIdxView& src_idx_,
1283 const DstColView& dst_col_,
1284 const SrcColView& src_col_,
1286 dst(dst_), src(src_), dst_idx(dst_idx_), src_idx(src_idx_),
1287 dst_col(dst_col_), src_col(src_col_),
1288 numCols(numCols_) {}
1290 KOKKOS_INLINE_FUNCTION
1291 void operator()(
const size_type k )
const {
1292 const typename DstIdxView::value_type toRow = dst_idx(k);
1293 const typename SrcIdxView::value_type fromRow = src_idx(k);
1294 for (
size_t j = 0; j < numCols; ++j)
1295 dst(toRow, dst_col(j)) = src(fromRow, src_col(j));
1298 static void permute(
const DstView& dst,
1300 const DstIdxView& dst_idx,
1301 const SrcIdxView& src_idx,
1302 const DstColView& dst_col,
1303 const SrcColView& src_col,
1305 const size_type n = std::min( dst_idx.size(), src_idx.size() );
1306 typedef Kokkos::RangePolicy<execution_space, size_type> range_type;
1307 Kokkos::parallel_for (range_type (0, n),
1308 PermuteArrayMultiColumnVariableStride (dst, src,
1319 template <
typename DstView,
typename SrcView,
1320 typename DstIdxView,
typename SrcIdxView,
1321 typename DstColView,
typename SrcColView>
1322 void permute_array_multi_column_variable_stride(
const DstView& dst,
1324 const DstIdxView& dst_idx,
1325 const SrcIdxView& src_idx,
1326 const DstColView& dst_col,
1327 const SrcColView& src_col,
1329 PermuteArrayMultiColumnVariableStride<DstView,SrcView,
1330 DstIdxView,SrcIdxView,DstColView,SrcColView>::permute(
1331 dst, src, dst_idx, src_idx, dst_col, src_col, numCols);
1338 #endif // TPETRA_KOKKOS_REFACTOR_DETAILS_MULTI_VECTOR_DIST_OBJECT_KERNELS_HPP Namespace Tpetra contains the class and methods constituting the Tpetra library.
KOKKOS_INLINE_FUNCTION bool outOfBounds(const IntegerType x, const IntegerType exclusiveUpperBound)
Is x out of bounds? That is, is x less than zero, or greater than or equal to the given exclusive upp...
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.
Is x out of bounds? That is, is x less than zero, or greater than or equal to the given exclusive upp...