42 #ifndef TPETRA_MULTIVECTOR_DEF_HPP 43 #define TPETRA_MULTIVECTOR_DEF_HPP 54 #include "Tpetra_Vector.hpp" 55 #include "Tpetra_Details_MultiVectorDistObjectKernels.hpp" 56 #include "Tpetra_KokkosRefactor_Details_MultiVectorDistObjectKernels.hpp" 58 #include "KokkosCompat_View.hpp" 59 #include "Kokkos_MV_GEMM.hpp" 60 #include "Kokkos_Blas1_MV.hpp" 61 #include "Kokkos_Random.hpp" 63 #ifdef HAVE_TPETRA_INST_FLOAT128 66 template<
class Generator>
67 struct rand<Generator, __float128> {
68 static KOKKOS_INLINE_FUNCTION __float128 max ()
70 return static_cast<__float128
> (1.0);
72 static KOKKOS_INLINE_FUNCTION __float128
77 const __float128 scalingFactor =
78 static_cast<__float128
> (std::numeric_limits<double>::min ()) /
79 static_cast<__float128> (2.0);
80 const __float128 higherOrderTerm =
static_cast<__float128
> (gen.drand ());
81 const __float128 lowerOrderTerm =
82 static_cast<__float128
> (gen.drand ()) * scalingFactor;
83 return higherOrderTerm + lowerOrderTerm;
85 static KOKKOS_INLINE_FUNCTION __float128
86 draw (Generator& gen,
const __float128& range)
89 const __float128 scalingFactor =
90 static_cast<__float128
> (std::numeric_limits<double>::min ()) /
91 static_cast<__float128> (2.0);
92 const __float128 higherOrderTerm =
93 static_cast<__float128
> (gen.drand (range));
94 const __float128 lowerOrderTerm =
95 static_cast<__float128
> (gen.drand (range)) * scalingFactor;
96 return higherOrderTerm + lowerOrderTerm;
98 static KOKKOS_INLINE_FUNCTION __float128
99 draw (Generator& gen,
const __float128& start,
const __float128& end)
102 const __float128 scalingFactor =
103 static_cast<__float128
> (std::numeric_limits<double>::min ()) /
104 static_cast<__float128> (2.0);
105 const __float128 higherOrderTerm =
106 static_cast<__float128
> (gen.drand (start, end));
107 const __float128 lowerOrderTerm =
108 static_cast<__float128
> (gen.drand (start, end)) * scalingFactor;
109 return higherOrderTerm + lowerOrderTerm;
113 #endif // HAVE_TPETRA_INST_FLOAT128 129 template<
class ST,
class LO,
class GO,
class NT>
131 allocDualView (
const size_t lclNumRows,
const size_t numCols,
const bool zeroOut =
true)
134 const char* label =
"MV::DualView";
138 return dual_view_type (label, lclNumRows, numCols);
141 return dual_view_type (label, lclNumRows, numCols);
149 typename dual_view_type::t_dev d_view (Kokkos::ViewAllocateWithoutInitializing (label), lclNumRows, numCols);
150 #ifdef HAVE_TPETRA_DEBUG 158 const ST nan = Kokkos::Details::ArithTraits<ST>::nan ();
159 KokkosBlas::fill (d_view, nan);
160 #endif // HAVE_TPETRA_DEBUG 161 typename dual_view_type::t_host h_view = Kokkos::create_mirror_view (d_view);
166 dual_view_type dv (d_view, h_view);
167 dv.template modify<typename dual_view_type::t_dev::memory_space> ();
169 return dual_view_type (d_view, h_view);
178 template<
class T,
class ExecSpace>
179 struct MakeUnmanagedView {
188 typedef typename Kokkos::Impl::if_c<
189 Kokkos::Impl::VerifyExecutionCanAccessMemorySpace<ExecSpace, Kokkos::HostSpace>::value,
190 typename ExecSpace::device_type,
191 typename Kokkos::DualView<T*, ExecSpace>::host_mirror_space>::type host_exec_space;
192 typedef Kokkos::LayoutLeft array_layout;
193 typedef Kokkos::View<T*, array_layout, host_exec_space,
194 Kokkos::MemoryUnmanaged> view_type;
196 static view_type getView (
const Teuchos::ArrayView<T>& x_in)
198 const size_t numEnt =
static_cast<size_t> (x_in.size ());
202 return view_type (x_in.getRawPtr (), numEnt);
210 template<
class DualViewType>
212 takeSubview (
const DualViewType& X,
214 const std::pair<size_t, size_t>& colRng)
216 if (X.dimension_0 () == 0 && X.dimension_1 () != 0) {
217 return DualViewType (
"MV::DualView", 0, colRng.second - colRng.first);
220 return subview (X, Kokkos::ALL (), colRng);
227 template<
class DualViewType>
229 takeSubview (
const DualViewType& X,
230 const std::pair<size_t, size_t>& rowRng,
231 const std::pair<size_t, size_t>& colRng)
233 if (X.dimension_0 () == 0 && X.dimension_1 () != 0) {
234 return DualViewType (
"MV::DualView", 0, colRng.second - colRng.first);
237 return subview (X, rowRng, colRng);
245 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
247 MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic>::
248 vectorIndexOutOfRange (
const size_t VectorIndex)
const {
249 return (VectorIndex < 1 && VectorIndex != 0) || VectorIndex >= getNumVectors();
252 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
253 MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic>::
258 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
261 const size_t numVecs,
262 const bool zeroOut) :
265 TEUCHOS_TEST_FOR_EXCEPTION(
266 numVecs < 1, std::invalid_argument,
"Tpetra::MultiVector::MultiVector" 267 "(map,numVecs,zeroOut): numVecs = " << numVecs <<
" < 1.");
269 view_ = allocDualView<Scalar, LocalOrdinal, GlobalOrdinal, Node> (lclNumRows, numVecs, zeroOut);
273 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
282 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
285 const Teuchos::DataAccess copyOrView) :
292 const char tfecfFuncName[] =
"MultiVector(const MultiVector&, " 293 "const Teuchos::DataAccess): ";
295 if (copyOrView == Teuchos::Copy) {
299 this->
view_ = cpy.view_;
303 else if (copyOrView == Teuchos::View) {
306 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
307 true, std::invalid_argument,
"Second argument 'copyOrView' has an " 308 "invalid value " << copyOrView <<
". Valid values include " 309 "Teuchos::Copy = " << Teuchos::Copy <<
" and Teuchos::View = " 310 << Teuchos::View <<
".");
314 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
317 const dual_view_type& view) :
322 const char tfecfFuncName[] =
"MultiVector(map,view): ";
328 const size_t LDA = (
origView_.dimension_1 () > 1) ? stride[1] :
331 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
332 LDA < lclNumRows, std::invalid_argument,
"The input Kokkos::DualView's " 333 "column stride LDA = " << LDA <<
" < getLocalLength() = " << lclNumRows
334 <<
". This may also mean that the input view's first dimension (number " 335 "of rows = " << view.dimension_0 () <<
") does not not match the number " 336 "of entries in the Map on the calling process.");
340 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
343 const typename dual_view_type::t_dev& d_view) :
346 using Teuchos::ArrayRCP;
348 const char tfecfFuncName[] =
"MultiVector(map,d_view): ";
353 d_view.stride (stride);
354 const size_t LDA = (d_view.dimension_1 () > 1) ? stride[1] :
355 d_view.dimension_0 ();
357 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
358 LDA < lclNumRows, std::invalid_argument,
"The input Kokkos::View's " 359 "column stride LDA = " << LDA <<
" < getLocalLength() = " << lclNumRows
360 <<
". This may also mean that the input view's first dimension (number " 361 "of rows = " << d_view.dimension_0 () <<
") does not not match the " 362 "number of entries in the Map on the calling process.");
371 view_.template modify<execution_space> ();
375 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
378 const dual_view_type& view,
379 const dual_view_type& origView) :
384 const char tfecfFuncName[] =
"MultiVector(map,view,origView): ";
390 const size_t LDA = (
origView_.dimension_1 () > 1) ? stride[1] :
393 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
394 LDA < lclNumRows, std::invalid_argument,
"The input Kokkos::DualView's " 395 "column stride LDA = " << LDA <<
" < getLocalLength() = " << lclNumRows
396 <<
". This may also mean that the input origView's first dimension (number " 397 "of rows = " << origView.dimension_0 () <<
") does not not match the number " 398 "of entries in the Map on the calling process.");
402 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
405 const dual_view_type& view,
406 const Teuchos::ArrayView<const size_t>& whichVectors) :
413 using Kokkos::subview;
414 const char tfecfFuncName[] =
"MultiVector(map,view,whichVectors): ";
416 const size_t lclNumRows = map.is_null () ? size_t (0) :
417 map->getNodeNumElements ();
424 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
425 view.dimension_1 () != 0 &&
static_cast<size_t> (view.dimension_0 ()) < lclNumRows,
426 std::invalid_argument,
"view.dimension_0() = " << view.dimension_0 ()
427 <<
" < map->getNodeNumElements() = " << lclNumRows <<
".");
428 if (whichVectors.size () != 0) {
429 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
430 view.dimension_1 () != 0 && view.dimension_1 () == 0,
431 std::invalid_argument,
"view.dimension_1() = 0, but whichVectors.size()" 432 " = " << whichVectors.size () <<
" > 0.");
433 size_t maxColInd = 0;
434 typedef Teuchos::ArrayView<const size_t>::size_type size_type;
435 for (size_type k = 0; k < whichVectors.size (); ++k) {
436 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
437 whichVectors[k] == Teuchos::OrdinalTraits<size_t>::invalid (),
438 std::invalid_argument,
"whichVectors[" << k <<
"] = " 439 "Teuchos::OrdinalTraits<size_t>::invalid().");
440 maxColInd = std::max (maxColInd, whichVectors[k]);
442 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
443 view.dimension_1 () != 0 &&
static_cast<size_t> (view.dimension_1 ()) <= maxColInd,
444 std::invalid_argument,
"view.dimension_1() = " << view.dimension_1 ()
445 <<
" <= max(whichVectors) = " << maxColInd <<
".");
452 const size_t LDA = (
origView_.dimension_1 () > 1) ? stride[1] :
454 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
455 LDA < lclNumRows, std::invalid_argument,
456 "LDA = " << LDA <<
" < this->getLocalLength() = " << lclNumRows <<
".");
458 if (whichVectors.size () == 1) {
467 const std::pair<size_t, size_t> colRng (whichVectors[0],
468 whichVectors[0] + 1);
476 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
479 const dual_view_type& view,
480 const dual_view_type& origView,
481 const Teuchos::ArrayView<const size_t>& whichVectors) :
488 using Kokkos::subview;
489 const char tfecfFuncName[] =
"MultiVector(map,view,origView,whichVectors): ";
498 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
499 view.dimension_1 () != 0 &&
static_cast<size_t> (view.dimension_0 ()) < lclNumRows,
500 std::invalid_argument,
"view.dimension_0() = " << view.dimension_0 ()
501 <<
" < map->getNodeNumElements() = " << lclNumRows <<
".");
502 if (whichVectors.size () != 0) {
503 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
504 view.dimension_1 () != 0 && view.dimension_1 () == 0,
505 std::invalid_argument,
"view.dimension_1() = 0, but whichVectors.size()" 506 " = " << whichVectors.size () <<
" > 0.");
507 size_t maxColInd = 0;
508 typedef Teuchos::ArrayView<const size_t>::size_type size_type;
509 for (size_type k = 0; k < whichVectors.size (); ++k) {
510 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
511 whichVectors[k] == Teuchos::OrdinalTraits<size_t>::invalid (),
512 std::invalid_argument,
"whichVectors[" << k <<
"] = " 513 "Teuchos::OrdinalTraits<size_t>::invalid().");
514 maxColInd = std::max (maxColInd, whichVectors[k]);
516 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
517 view.dimension_1 () != 0 &&
static_cast<size_t> (view.dimension_1 ()) <= maxColInd,
518 std::invalid_argument,
"view.dimension_1() = " << view.dimension_1 ()
519 <<
" <= max(whichVectors) = " << maxColInd <<
".");
525 const size_t LDA = (
origView_.dimension_1 () > 1) ? stride[1] :
527 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
528 LDA < lclNumRows, std::invalid_argument,
"Input DualView's column stride" 529 " = " << LDA <<
" < this->getLocalLength() = " << lclNumRows <<
".");
531 if (whichVectors.size () == 1) {
540 const std::pair<size_t, size_t> colRng (whichVectors[0],
541 whichVectors[0] + 1);
549 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
552 const Teuchos::ArrayView<const Scalar>& data,
554 const size_t numVecs) :
557 using Kokkos::subview;
558 using Teuchos::ArrayView;
559 using Teuchos::av_reinterpret_cast;
561 typedef LocalOrdinal LO;
562 typedef GlobalOrdinal GO;
563 typedef typename dual_view_type::host_mirror_space HMS;
564 typedef MakeUnmanagedView<const IST, device_type> view_getter_type;
565 typedef typename view_getter_type::view_type in_view_type;
566 typedef Kokkos::View<IST*, Kokkos::LayoutLeft, HMS> out_view_type;
567 const char tfecfFuncName[] =
"MultiVector(map,data,LDA,numVecs): ";
572 const size_t lclNumRows =
573 map.is_null () ? size_t (0) : map->getNodeNumElements ();
574 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
575 (LDA < lclNumRows, std::invalid_argument,
"LDA = " << LDA <<
" < " 576 "map->getNodeNumElements() = " << lclNumRows <<
".");
578 const size_t minNumEntries = LDA * (numVecs - 1) + lclNumRows;
579 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
580 (static_cast<size_t> (data.size ()) < minNumEntries,
581 std::invalid_argument,
"Input Teuchos::ArrayView does not have enough " 582 "entries, given the input Map and number of vectors in the MultiVector." 583 " data.size() = " << data.size () <<
" < (LDA*(numVecs-1)) + " 584 "map->getNodeNumElements () = " << minNumEntries <<
".");
586 view_ = allocDualView<Scalar, LO, GO, Node> (lclNumRows, numVecs);
587 view_.template modify<HMS> ();
589 ArrayView<const IST> X_in_av = av_reinterpret_cast<
const IST> (data);
590 in_view_type X_in = view_getter_type::getView (X_in_av);
591 const std::pair<size_t, size_t> rowRng (0, lclNumRows);
592 for (
size_t j = 0; j < numVecs; ++j) {
593 const std::pair<size_t, size_t> rng (j*LDA, j*LDA + lclNumRows);
594 in_view_type X_j_in = subview (X_in, rng);
595 out_view_type X_j_out = subview (view_.h_view, rowRng, j);
601 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
603 MultiVector (
const Teuchos::RCP<const map_type>& map,
604 const Teuchos::ArrayView<
const ArrayView<const Scalar> >& ArrayOfPtrs,
605 const size_t numVecs) :
608 using Kokkos::subview;
609 using Teuchos::ArrayView;
610 using Teuchos::av_reinterpret_cast;
612 typedef LocalOrdinal LO;
613 typedef GlobalOrdinal GO;
614 typedef typename dual_view_type::host_mirror_space HMS;
615 typedef MakeUnmanagedView<const IST, device_type> view_getter_type;
616 typedef typename view_getter_type::view_type in_view_type;
617 typedef Kokkos::View<IST*, Kokkos::LayoutLeft, HMS> out_view_type;
618 const char tfecfFuncName[] =
"MultiVector(map,ArrayOfPtrs,numVecs): ";
620 const size_t lclNumRows =
621 map.is_null () ? size_t (0) : map->getNodeNumElements ();
622 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
623 numVecs < 1 || numVecs != static_cast<size_t> (ArrayOfPtrs.size ()),
625 "ArrayOfPtrs.size() must be strictly positive and as large as ArrayOfPtrs.");
626 for (
size_t j = 0; j < numVecs; ++j) {
627 ArrayView<const Scalar> X_j_av = ArrayOfPtrs[j];
628 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
629 static_cast<size_t> (X_j_av.size ()) < lclNumRows,
630 std::invalid_argument,
"ArrayOfPtrs[" << j <<
"].size() = " 631 << X_j_av.size () <<
" < map->getNodeNumElements() = " << lclNumRows
635 view_ = allocDualView<Scalar, LO, GO, Node> (lclNumRows, numVecs);
636 view_.template modify<HMS> ();
638 const std::pair<size_t, size_t> rowRng (0, lclNumRows);
639 for (
size_t j = 0; j < numVecs; ++j) {
640 ArrayView<const IST> X_j_av =
641 av_reinterpret_cast<
const IST> (ArrayOfPtrs[j]);
642 in_view_type X_j_in (X_j_av.getRawPtr (), lclNumRows);
643 out_view_type X_j_out = subview (view_.h_view, rowRng, j);
649 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
653 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
659 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
664 if (this->
getMap ().is_null ()) {
665 return static_cast<size_t> (0);
667 return this->
getMap ()->getNodeNumElements ();
671 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
676 if (this->
getMap ().is_null ()) {
677 return static_cast<size_t> (0);
679 return this->
getMap ()->getGlobalNumElements ();
683 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
693 const size_t LDA = (
origView_.dimension_1 () > 1) ? stride[1] :
origView_.dimension_0 ();
697 return static_cast<size_t> (0);
701 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
710 const this_type* src =
dynamic_cast<const this_type*
> (&sourceObj);
724 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
731 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
736 const Kokkos::View<const LocalOrdinal*, execution_space>& permuteToLIDs,
737 const Kokkos::View<const LocalOrdinal*, execution_space>& permuteFromLIDs)
739 using Teuchos::ArrayRCP;
740 using Teuchos::ArrayView;
742 using Kokkos::Compat::getKokkosViewDeepCopy;
743 using Kokkos::subview;
745 typename dual_view_type::array_layout,
749 const char tfecfFuncName[] =
"copyAndPermute";
751 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
752 permuteToLIDs.size() != permuteFromLIDs.size(), std::runtime_error,
753 ": permuteToLIDs and permuteFromLIDs must have the same size." 754 << std::endl <<
"permuteToLIDs.size() = " << permuteToLIDs.size ()
755 <<
" != permuteFromLIDs.size() = " << permuteFromLIDs.size () <<
".");
758 const MV& sourceMV =
dynamic_cast<const MV&
> (sourceObj);
782 if (numSameIDs > 0) {
783 const std::pair<size_t, size_t> rows (0, numSameIDs);
784 for (
size_t j = 0; j < numCols; ++j) {
786 const size_t srcCol =
787 sourceMV.isConstantStride () ? j : sourceMV.whichVectors_[j];
788 col_dual_view_type dst_j =
789 subview (
view_, rows, dstCol);
790 col_dual_view_type src_j =
791 subview (sourceMV.view_, rows, srcCol);
806 if (permuteFromLIDs.size() == 0 || permuteToLIDs.size() == 0)
810 KokkosRefactor::Details::permute_array_multi_column(
812 sourceMV.getKokkosView(),
818 KokkosRefactor::Details::permute_array_multi_column_variable_stride(
820 sourceMV.getKokkosView(),
824 getKokkosViewDeepCopy<execution_space> (sourceMV.whichVectors_ ()),
829 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
833 const Kokkos::View<const local_ordinal_type*, execution_space> &exportLIDs,
834 Kokkos::View<impl_scalar_type*, execution_space> &exports,
835 const Kokkos::View<size_t*, execution_space> &numExportPacketsPerLID,
836 size_t& constantNumPackets,
839 using Teuchos::Array;
840 using Teuchos::ArrayView;
841 using Kokkos::Compat::getKokkosViewDeepCopy;
846 if (exportLIDs.size () == 0) {
851 const MV& sourceMV =
dynamic_cast<const MV&
> (sourceObj);
855 (void) numExportPacketsPerLID;
877 constantNumPackets = numCols;
879 const size_t numExportLIDs = exportLIDs.size ();
880 const size_t newExportsSize = numCols * numExportLIDs;
881 if (exports.size () != newExportsSize) {
882 Kokkos::Compat::realloc (exports, newExportsSize);
893 if (sourceMV.isConstantStride ()) {
894 KokkosRefactor::Details::pack_array_single_column(
896 sourceMV.getKokkosView (),
901 KokkosRefactor::Details::pack_array_single_column(
903 sourceMV.getKokkosView (),
905 sourceMV.whichVectors_[0]);
909 if (sourceMV.isConstantStride ()) {
910 KokkosRefactor::Details::pack_array_multi_column(
912 sourceMV.getKokkosView (),
917 KokkosRefactor::Details::pack_array_multi_column_variable_stride(
919 sourceMV.getKokkosView (),
921 getKokkosViewDeepCopy<execution_space> (sourceMV.whichVectors_ ()),
928 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
931 unpackAndCombineNew (
const Kokkos::View<const local_ordinal_type*, execution_space> &importLIDs,
932 const Kokkos::View<const impl_scalar_type*, execution_space> &imports,
933 const Kokkos::View<size_t*, execution_space> &numPacketsPerLID,
934 size_t constantNumPackets,
938 using Teuchos::ArrayView;
939 using Kokkos::Compat::getKokkosViewDeepCopy;
940 const char tfecfFuncName[] =
"unpackAndCombine";
943 if (importLIDs.size () == 0) {
949 (void) numPacketsPerLID;
961 #ifdef HAVE_TPETRA_DEBUG 962 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
963 static_cast<size_t> (imports.size()) !=
getNumVectors()*importLIDs.size(),
965 ": 'imports' buffer size must be consistent with the amount of data to " 966 "be sent. " << std::endl <<
"imports.size() = " << imports.size()
967 <<
" != getNumVectors()*importLIDs.size() = " <<
getNumVectors() <<
"*" 968 << importLIDs.size() <<
" = " <<
getNumVectors() * importLIDs.size()
971 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
972 constantNumPackets == static_cast<size_t> (0), std::runtime_error,
973 ": constantNumPackets input argument must be nonzero.");
975 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
976 static_cast<size_t> (numVecs) != static_cast<size_t> (constantNumPackets),
977 std::runtime_error,
": constantNumPackets must equal numVecs.");
978 #endif // HAVE_TPETRA_DEBUG 980 if (numVecs > 0 && importLIDs.size () > 0) {
988 KokkosRefactor::Details::unpack_array_multi_column(
992 KokkosRefactor::Details::InsertOp(),
996 KokkosRefactor::Details::unpack_array_multi_column_variable_stride(
1001 KokkosRefactor::Details::InsertOp(),
1005 else if (CM ==
ADD) {
1007 KokkosRefactor::Details::unpack_array_multi_column(
1011 KokkosRefactor::Details::AddOp(),
1015 KokkosRefactor::Details::unpack_array_multi_column_variable_stride(
1020 KokkosRefactor::Details::AddOp(),
1026 KokkosRefactor::Details::unpack_array_multi_column(
1030 KokkosRefactor::Details::AbsMaxOp(),
1034 KokkosRefactor::Details::unpack_array_multi_column_variable_stride(
1039 KokkosRefactor::Details::AbsMaxOp(),
1044 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1046 std::invalid_argument,
": Invalid CombineMode: " << CM <<
". Valid " 1047 "CombineMode values are ADD, REPLACE, INSERT, and ABSMAX.");
1052 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1058 return static_cast<size_t> (
view_.dimension_1 ());
1066 template<
class RV,
class XMV>
1068 lclDotImpl (
const RV& dotsOut,
1071 const size_t lclNumRows,
1072 const size_t numVecs,
1073 const Teuchos::ArrayView<const size_t>& whichVecsX,
1074 const Teuchos::ArrayView<const size_t>& whichVecsY,
1075 const bool constantStrideX,
1076 const bool constantStrideY)
1079 using Kokkos::subview;
1080 typedef typename RV::non_const_value_type
dot_type;
1081 #ifdef HAVE_TPETRA_DEBUG 1082 const char prefix[] =
"Tpetra::MultiVector::lclDotImpl: ";
1083 #endif // HAVE_TPETRA_DEBUG 1085 static_assert (Kokkos::Impl::is_view<RV>::value,
1086 "Tpetra::MultiVector::lclDotImpl: " 1087 "The first argument dotsOut is not a Kokkos::View.");
1088 static_assert (RV::rank == 1,
"Tpetra::MultiVector::lclDotImpl: " 1089 "The first argument dotsOut must have rank 1.");
1090 static_assert (Kokkos::Impl::is_view<XMV>::value,
1091 "Tpetra::MultiVector::lclDotImpl: The type of the 2nd and " 1092 "3rd arguments (X_lcl and Y_lcl) is not a Kokkos::View.");
1093 static_assert (XMV::rank == 2,
"Tpetra::MultiVector::lclDotImpl: " 1094 "X_lcl and Y_lcl must have rank 2.");
1099 const std::pair<size_t, size_t> rowRng (0, lclNumRows);
1100 const std::pair<size_t, size_t> colRng (0, numVecs);
1101 RV theDots = subview (dotsOut, colRng);
1102 XMV X = subview (X_lcl, rowRng, colRng);
1103 XMV Y = subview (Y_lcl, rowRng, colRng);
1105 #ifdef HAVE_TPETRA_DEBUG 1106 TEUCHOS_TEST_FOR_EXCEPTION(
1108 (X.dimension_0 () != lclNumRows || X.dimension_1 () != numVecs),
1109 std::logic_error, prefix <<
"X's dimensions are " << X.dimension_0 ()
1110 <<
" x " << X.dimension_1 () <<
", which differ from the local " 1111 "dimensions " << lclNumRows <<
" x " << numVecs <<
". " 1112 "Please report this bug to the Tpetra developers.");
1113 TEUCHOS_TEST_FOR_EXCEPTION(
1115 (Y.dimension_0 () != lclNumRows || Y.dimension_1 () != numVecs),
1116 std::logic_error, prefix <<
"Y's dimensions are " << Y.dimension_0 ()
1117 <<
" x " << Y.dimension_1 () <<
", which differ from the local " 1118 "dimensions " << lclNumRows <<
" x " << numVecs <<
". " 1119 "Please report this bug to the Tpetra developers.");
1120 #endif // HAVE_TPETRA_DEBUG 1122 if (lclNumRows == 0) {
1123 const dot_type zero = Kokkos::Details::ArithTraits<dot_type>::zero ();
1124 Kokkos::Impl::ViewFill<RV> (theDots, zero);
1127 if (constantStrideX && constantStrideY) {
1128 if(X.dimension_1() == 1) {
1129 typename RV::non_const_value_type result =
1130 KokkosBlas::dot (Kokkos::subview(X,Kokkos::ALL(),0),
1131 Kokkos::subview(Y,Kokkos::ALL(),0));
1134 KokkosBlas::dot (theDots, X, Y);
1142 for (
size_t k = 0; k < numVecs; ++k) {
1143 const size_t X_col = constantStrideX ? k : whichVecsX[k];
1144 const size_t Y_col = constantStrideY ? k : whichVecsY[k];
1145 KokkosBlas::dot (subview (theDots, k), subview (X, ALL (), X_col),
1146 subview (Y, ALL (), Y_col));
1154 gblDotImpl (
const RV& dotsOut,
1155 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
1156 const bool distributed)
1158 using Teuchos::REDUCE_MAX;
1159 using Teuchos::REDUCE_SUM;
1160 using Teuchos::reduceAll;
1161 typedef typename RV::non_const_value_type
dot_type;
1163 const size_t numVecs = dotsOut.dimension_0 ();
1178 if (distributed && ! comm.is_null ()) {
1184 typename RV::non_const_type lclDots (Kokkos::ViewAllocateWithoutInitializing (
"tmp"), numVecs);
1186 const dot_type*
const lclSum = lclDots.ptr_on_device ();
1187 dot_type*
const gblSum = dotsOut.ptr_on_device ();
1188 const int nv =
static_cast<int> (numVecs);
1189 reduceAll<int, dot_type> (*comm, REDUCE_SUM, nv, lclSum, gblSum);
1194 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1198 const Kokkos::View<dot_type*, device_type>& dots)
const 1200 using Kokkos::create_mirror_view;
1201 using Kokkos::subview;
1202 using Teuchos::Comm;
1203 using Teuchos::null;
1206 typedef Kokkos::View<dot_type*, device_type> RV;
1207 const char tfecfFuncName[] =
"Tpetra::MultiVector::dot: ";
1214 const size_t numDots =
static_cast<size_t> (dots.dimension_0 ());
1216 #ifdef HAVE_TPETRA_DEBUG 1218 const bool compat = this->
getMap ()->isCompatible (* (A.
getMap ()));
1219 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1220 ! compat, std::invalid_argument,
"Tpetra::MultiVector::dot: *this is " 1221 "not compatible with the input MultiVector A. We only test for this " 1222 "in a debug build.");
1224 #endif // HAVE_TPETRA_DEBUG 1233 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1235 "MultiVectors do not have the same local length. " 1236 "this->getLocalLength() = " << lclNumRows <<
" != " 1238 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1240 "MultiVectors must have the same number of columns (vectors). " 1241 "this->getNumVectors() = " << numVecs <<
" != " 1243 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1244 numDots != numVecs, std::runtime_error,
1245 "The output array 'dots' must have the same number of entries as the " 1246 "number of columns (vectors) in *this and A. dots.dimension_0() = " <<
1247 numDots <<
" != this->getNumVectors() = " << numVecs <<
".");
1249 const std::pair<size_t, size_t> colRng (0, numVecs);
1250 RV dotsOut = subview (dots, colRng);
1251 RCP<const Comm<int> > comm = this->
getMap ().is_null () ? null :
1252 this->
getMap ()->getComm ();
1256 const bool oneMemorySpace =
1257 Kokkos::Impl::is_same<
typename dual_view_type::t_dev::memory_space,
1258 typename dual_view_type::t_host::memory_space>::value;
1259 if (! oneMemorySpace && A.
view_.modified_host >= A.
view_.modified_device) {
1262 typedef typename dual_view_type::t_host XMV;
1265 this->
view_.template sync<typename XMV::memory_space> ();
1266 lclDotImpl<RV, XMV> (dotsOut,
view_.h_view, A.
view_.h_view,
1267 lclNumRows, numVecs,
1270 typename RV::HostMirror dotsOutHost = create_mirror_view (dotsOut);
1272 gblDotImpl<typename RV::HostMirror> (dotsOutHost, comm,
1278 typedef typename dual_view_type::t_dev XMV;
1281 this->
view_.template sync<typename XMV::memory_space> ();
1282 lclDotImpl<RV, XMV> (dotsOut,
view_.d_view, A.
view_.d_view,
1283 lclNumRows, numVecs,
1291 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1295 const Teuchos::ArrayView<dot_type>& dots)
const 1297 typedef Kokkos::View<dot_type*, device_type> dev_dots_view_type;
1298 typedef MakeUnmanagedView<dot_type, device_type> view_getter_type;
1299 typedef typename view_getter_type::view_type host_dots_view_type;
1301 const size_t numDots =
static_cast<size_t> (dots.size ());
1302 host_dots_view_type dotsHostView (dots.getRawPtr (), numDots);
1303 dev_dots_view_type dotsDevView (
"MV::dot tmp", numDots);
1304 this->
dot (A, dotsDevView);
1309 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1312 norm2 (
const Teuchos::ArrayView<mag_type>& norms)
const 1314 typedef Kokkos::View<mag_type*, device_type> dev_norms_view_type;
1315 typedef MakeUnmanagedView<mag_type, device_type> view_getter_type;
1316 typedef typename view_getter_type::view_type host_norms_view_type;
1318 const size_t numNorms =
static_cast<size_t> (norms.size ());
1319 host_norms_view_type normsHostView (norms.getRawPtr (), numNorms);
1320 dev_norms_view_type normsDevView (
"MV::norm2 tmp", numNorms);
1321 this->
norm2 (normsDevView);
1326 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1329 norm2 (
const Kokkos::View<mag_type*, device_type>& norms)
const 1335 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1339 const Teuchos::ArrayView<mag_type> &norms)
const 1342 using Kokkos::subview;
1343 using Teuchos::Comm;
1344 using Teuchos::null;
1346 using Teuchos::reduceAll;
1347 using Teuchos::REDUCE_SUM;
1348 typedef Kokkos::Details::ArithTraits<impl_scalar_type> ATS;
1349 typedef Kokkos::Details::ArithTraits<mag_type> ATM;
1350 typedef Kokkos::View<mag_type*, device_type> norms_view_type;
1351 const char tfecfFuncName[] =
"normWeighted: ";
1354 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1355 static_cast<size_t> (norms.size ()) != numVecs, std::runtime_error,
1356 "norms.size() = " << norms.size () <<
" != this->getNumVectors() = " 1360 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1361 ! OneW && weights.
getNumVectors () != numVecs, std::runtime_error,
1362 "The input MultiVector of weights must contain either one column, " 1363 "or must have the same number of columns as *this. " 1365 <<
" and this->getNumVectors() = " << numVecs <<
".");
1367 #ifdef HAVE_TPETRA_DEBUG 1368 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1369 ! this->
getMap ()->isCompatible (*weights.
getMap ()), std::runtime_error,
1370 "MultiVectors do not have compatible Maps:" << std::endl
1371 <<
"this->getMap(): " << std::endl << *this->
getMap()
1372 <<
"weights.getMap(): " << std::endl << *weights.
getMap() << std::endl);
1375 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
1377 "MultiVectors do not have the same local length.");
1378 #endif // HAVE_TPETRA_DEBUG 1380 norms_view_type lclNrms (
"lclNrms", numVecs);
1382 view_.template sync<device_type> ();
1383 weights.
view_.template sync<device_type> ();
1385 typename dual_view_type::t_dev X_lcl = this->
view_.d_view;
1386 typename dual_view_type::t_dev W_lcl = weights.
view_.d_view;
1389 KokkosBlas::nrm2w_squared (lclNrms, X_lcl, W_lcl);
1392 for (
size_t j = 0; j < numVecs; ++j) {
1395 const size_t W_col = OneW ?
static_cast<size_t> (0) :
1397 KokkosBlas::nrm2w_squared (subview (lclNrms, j),
1398 subview (X_lcl, ALL (), X_col),
1399 subview (W_lcl, ALL (), W_col));
1405 RCP<const Comm<int> > comm = this->
getMap ().is_null () ?
1406 Teuchos::null : this->
getMap ()->getComm ();
1410 reduceAll<int, mag_type> (*comm, REDUCE_SUM,
static_cast<int> (numVecs),
1411 lclNrms.ptr_on_device (), norms.getRawPtr ());
1412 for (
size_t k = 0; k < numVecs; ++k) {
1413 norms[k] = ATM::sqrt (norms[k] * OneOverN);
1417 typename norms_view_type::HostMirror lclNrms_h =
1418 Kokkos::create_mirror_view (lclNrms);
1420 for (
size_t k = 0; k < numVecs; ++k) {
1421 norms[k] = ATM::sqrt (ATS::magnitude (lclNrms_h(k)) * OneOverN);
1427 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1430 norm1 (
const Teuchos::ArrayView<mag_type>& norms)
const 1432 typedef Kokkos::View<mag_type*, device_type> dev_norms_view_type;
1433 typedef MakeUnmanagedView<mag_type, device_type> view_getter_type;
1434 typedef typename view_getter_type::view_type host_norms_view_type;
1436 const size_t numNorms =
static_cast<size_t> (norms.size ());
1437 host_norms_view_type normsHostView (norms.getRawPtr (), numNorms);
1438 dev_norms_view_type normsDevView (
"MV::norm1 tmp", numNorms);
1439 this->
norm1 (normsDevView);
1444 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1447 norm1 (
const Kokkos::View<mag_type*, device_type>& norms)
const 1453 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1456 normInf (
const Teuchos::ArrayView<mag_type>& norms)
const 1458 typedef Kokkos::View<mag_type*, device_type> dev_norms_view_type;
1459 typedef MakeUnmanagedView<mag_type, device_type> view_getter_type;
1460 typedef typename view_getter_type::view_type host_norms_view_type;
1462 const size_t numNorms =
static_cast<size_t> (norms.size ());
1463 host_norms_view_type normsHostView (norms.getRawPtr (), numNorms);
1464 dev_norms_view_type normsDevView (
"MV::normInf tmp", numNorms);
1470 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1473 normInf (
const Kokkos::View<mag_type*, device_type>& norms)
const 1487 template<
class RV,
class XMV>
1489 lclNormImpl (
const RV& normsOut,
1491 const size_t lclNumRows,
1492 const size_t numVecs,
1493 const Teuchos::ArrayView<const size_t>& whichVecs,
1494 const bool constantStride,
1498 using Kokkos::subview;
1499 typedef typename RV::non_const_value_type
mag_type;
1501 static_assert (Kokkos::Impl::is_view<RV>::value,
1502 "Tpetra::MultiVector::lclNormImpl: " 1503 "The first argument RV is not a Kokkos::View.");
1504 static_assert (RV::rank == 1,
"Tpetra::MultiVector::lclNormImpl: " 1505 "The first argument normsOut must have rank 1.");
1506 static_assert (Kokkos::Impl::is_view<XMV>::value,
1507 "Tpetra::MultiVector::lclNormImpl: " 1508 "The second argument X_lcl is not a Kokkos::View.");
1509 static_assert (XMV::rank == 2,
"Tpetra::MultiVector::lclNormImpl: " 1510 "The second argument X_lcl must have rank 2.");
1515 const std::pair<size_t, size_t> rowRng (0, lclNumRows);
1516 const std::pair<size_t, size_t> colRng (0, numVecs);
1517 RV theNorms = subview (normsOut, colRng);
1518 XMV X = subview (X_lcl, rowRng, colRng);
1523 TEUCHOS_TEST_FOR_EXCEPTION(
1524 lclNumRows != 0 && (X.dimension_0 () != lclNumRows || X.dimension_1 () != numVecs),
1525 std::logic_error,
"X's dimensions are " << X.dimension_0 () <<
" x " 1526 << X.dimension_1 () <<
", which differ from the local dimensions " 1527 << lclNumRows <<
" x " << numVecs <<
". Please report this bug to " 1528 "the Tpetra developers.");
1530 if (lclNumRows == 0) {
1531 const mag_type zeroMag = Kokkos::Details::ArithTraits<mag_type>::zero ();
1532 Kokkos::Impl::ViewFill<RV> (theNorms, zeroMag);
1535 if (constantStride) {
1536 if (whichNorm == IMPL_NORM_INF) {
1537 KokkosBlas::nrmInf (theNorms, X);
1539 else if (whichNorm == IMPL_NORM_ONE) {
1540 KokkosBlas::nrm1 (theNorms, X);
1542 else if (whichNorm == IMPL_NORM_TWO) {
1543 KokkosBlas::nrm2_squared (theNorms, X);
1546 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Should never get here!");
1555 for (
size_t k = 0; k < numVecs; ++k) {
1556 const size_t X_col = constantStride ? k : whichVecs[k];
1557 if (whichNorm == IMPL_NORM_INF) {
1558 KokkosBlas::nrmInf (subview (theNorms, k),
1559 subview (X, ALL (), X_col));
1561 else if (whichNorm == IMPL_NORM_ONE) {
1562 KokkosBlas::nrm1 (subview (theNorms, k),
1563 subview (X, ALL (), X_col));
1565 else if (whichNorm == IMPL_NORM_TWO) {
1566 KokkosBlas::nrm2_squared (subview (theNorms, k),
1567 subview (X, ALL (), X_col));
1570 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Should never get here!");
1579 gblNormImpl (
const RV& normsOut,
1580 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
1581 const bool distributed,
1584 using Teuchos::REDUCE_MAX;
1585 using Teuchos::REDUCE_SUM;
1586 using Teuchos::reduceAll;
1587 typedef typename RV::non_const_value_type
mag_type;
1589 const size_t numVecs = normsOut.dimension_0 ();
1604 if (distributed && ! comm.is_null ()) {
1610 RV lclNorms (
"MV::normImpl lcl", numVecs);
1612 const mag_type*
const lclSum = lclNorms.ptr_on_device ();
1613 mag_type*
const gblSum = normsOut.ptr_on_device ();
1614 const int nv =
static_cast<int> (numVecs);
1615 if (whichNorm == IMPL_NORM_INF) {
1616 reduceAll<int, mag_type> (*comm, REDUCE_MAX, nv, lclSum, gblSum);
1618 reduceAll<int, mag_type> (*comm, REDUCE_SUM, nv, lclSum, gblSum);
1622 if (whichNorm == IMPL_NORM_TWO) {
1628 const bool inHostMemory =
1629 Kokkos::Impl::is_same<
typename RV::memory_space,
1630 typename RV::host_mirror_space::memory_space>::value;
1632 for (
size_t j = 0; j < numVecs; ++j) {
1633 normsOut(j) = Kokkos::Details::ArithTraits<mag_type>::sqrt (normsOut(j));
1641 KokkosBlas::Impl::SquareRootFunctor<RV> f (normsOut);
1642 Kokkos::parallel_for (numVecs, f);
1649 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1652 normImpl (
const Kokkos::View<mag_type*, device_type>& norms,
1655 using Kokkos::create_mirror_view;
1656 using Kokkos::subview;
1657 using Teuchos::Comm;
1658 using Teuchos::null;
1661 typedef Kokkos::View<mag_type*, device_type> RV;
1668 const size_t numNorms =
static_cast<size_t> (norms.dimension_0 ());
1669 TEUCHOS_TEST_FOR_EXCEPTION(
1670 numNorms < numVecs, std::runtime_error,
"Tpetra::MultiVector::normImpl: " 1671 "'norms' must have at least as many entries as the number of vectors in " 1672 "*this. norms.dimension_0() = " << numNorms <<
" < this->getNumVectors()" 1673 " = " << numVecs <<
".");
1675 const std::pair<size_t, size_t> colRng (0, numVecs);
1676 RV normsOut = subview (norms, colRng);
1678 EWhichNormImpl lclNormType;
1679 if (whichNorm == NORM_ONE) {
1680 lclNormType = IMPL_NORM_ONE;
1681 }
else if (whichNorm == NORM_TWO) {
1682 lclNormType = IMPL_NORM_TWO;
1684 lclNormType = IMPL_NORM_INF;
1687 RCP<const Comm<int> > comm = this->
getMap ().is_null () ? null :
1688 this->
getMap ()->getComm ();
1692 const bool oneMemorySpace =
1693 Kokkos::Impl::is_same<
typename dual_view_type::t_dev::memory_space,
1694 typename dual_view_type::t_host::memory_space>::value;
1695 if (! oneMemorySpace &&
view_.modified_host >=
view_.modified_device) {
1698 typedef typename dual_view_type::t_host XMV;
1699 lclNormImpl<RV, XMV> (normsOut,
view_.h_view, lclNumRows, numVecs,
1702 typename RV::HostMirror normsOutHost = create_mirror_view (normsOut);
1704 gblNormImpl<typename RV::HostMirror> (normsOutHost, comm,
1711 typedef typename dual_view_type::t_dev XMV;
1712 lclNormImpl<RV, XMV> (normsOut,
view_.d_view, lclNumRows, numVecs,
1715 gblNormImpl<RV> (normsOut, comm, this->
isDistributed (), lclNormType);
1719 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1722 meanValue (
const Teuchos::ArrayView<impl_scalar_type>& means)
const 1726 using Kokkos::subview;
1727 using Teuchos::Comm;
1729 using Teuchos::reduceAll;
1730 using Teuchos::REDUCE_SUM;
1731 typedef Kokkos::Details::ArithTraits<impl_scalar_type> ATS;
1735 const size_t numMeans =
static_cast<size_t> (means.size ());
1737 TEUCHOS_TEST_FOR_EXCEPTION(
1738 numMeans != numVecs, std::runtime_error,
1739 "Tpetra::MultiVector::meanValue: means.size() = " << numMeans
1740 <<
" != this->getNumVectors() = " << numVecs <<
".");
1742 const std::pair<size_t, size_t> rowRng (0, lclNumRows);
1743 const std::pair<size_t, size_t> colRng (0, numVecs);
1748 typedef Kokkos::View<impl_scalar_type*, device_type> local_view_type;
1750 typename local_view_type::HostMirror::array_layout,
1752 Kokkos::MemoryTraits<Kokkos::Unmanaged>,
1753 typename local_view_type::HostMirror::specialize> host_local_view_type;
1754 host_local_view_type meansOut (means.getRawPtr (), numMeans);
1756 RCP<const Comm<int> > comm = this->
getMap ().is_null () ? Teuchos::null :
1757 this->
getMap ()->getComm ();
1761 const bool oneMemorySpace =
1762 Kokkos::Impl::is_same<
typename dual_view_type::t_dev::memory_space,
1763 typename dual_view_type::t_host::memory_space>::value;
1764 if (! oneMemorySpace &&
view_.modified_host >=
view_.modified_device) {
1766 typename dual_view_type::t_host X_lcl =
1767 subview (this->
view_.h_view, rowRng, colRng);
1770 typename local_view_type::HostMirror lclSums (
"MV::meanValue tmp", numVecs);
1772 KokkosBlas::sum (lclSums, X_lcl);
1775 for (
size_t j = 0; j < numVecs; ++j) {
1777 KokkosBlas::sum (subview (lclSums, j), subview (X_lcl, ALL (), col));
1785 reduceAll (*comm, REDUCE_SUM, static_cast<int> (numVecs),
1786 lclSums.ptr_on_device (), meansOut.ptr_on_device ());
1794 typename dual_view_type::t_dev X_lcl =
1795 subview (this->
view_.d_view, rowRng, colRng);
1798 local_view_type lclSums (
"MV::meanValue tmp", numVecs);
1800 KokkosBlas::sum (lclSums, X_lcl);
1803 for (
size_t j = 0; j < numVecs; ++j) {
1805 KokkosBlas::sum (subview (lclSums, j), subview (X_lcl, ALL (), col));
1814 reduceAll (*comm, REDUCE_SUM, static_cast<int> (numVecs),
1815 lclSums.ptr_on_device (), meansOut.ptr_on_device ());
1825 const impl_scalar_type OneOverN =
1827 for (
size_t k = 0; k < numMeans; ++k) {
1828 meansOut(k) = meansOut(k) * OneOverN;
1833 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1839 using Kokkos::subview;
1841 typedef Kokkos::Details::ArithTraits<IST> ATS;
1842 typedef Kokkos::Random_XorShift64_Pool<typename device_type::execution_space> pool_type;
1843 typedef typename pool_type::generator_type generator_type;
1854 const uint64_t myRank =
1855 static_cast<uint64_t
> (this->
getMap ()->getComm ()->getRank ());
1856 uint64_t seed64 =
static_cast<uint64_t
> (std::rand ()) + myRank + 17311uLL;
1857 unsigned int seed =
static_cast<unsigned int> (seed64&0xffffffff);
1859 pool_type rand_pool (seed);
1860 const IST max = Kokkos::rand<generator_type, IST>::max ();
1861 const IST min = ATS::is_signed ? IST (-max) : ATS::zero ();
1864 Kokkos::fill_random (
view_.d_view, rand_pool, min, max);
1865 view_.template modify<device_type> ();
1869 view_.template sync<device_type> ();
1870 typedef Kokkos::View<IST*, device_type> view_type;
1871 for (
size_t k = 0; k < numVecs; ++k) {
1873 view_type X_k = subview (
view_.d_view, ALL (), col);
1874 Kokkos::fill_random (X_k, rand_pool, min, max);
1876 view_.template modify<device_type> ();
1881 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1887 using Kokkos::Impl::ViewFill;
1888 using Kokkos::subview;
1889 typedef typename dual_view_type::t_dev::device_type DMS;
1890 typedef typename dual_view_type::t_host::device_type HMS;
1895 const std::pair<size_t, size_t> rowRng (0, lclNumRows);
1896 const std::pair<size_t, size_t> colRng (0, numVecs);
1900 if (
view_.modified_device >=
view_.modified_host) {
1905 typedef typename dual_view_type::t_dev mv_view_type;
1908 typename mv_view_type::array_layout, DMS> vec_view_type;
1910 this->
template modify<DMS> ();
1912 subview (this->
getDualView ().
template view<DMS> (),
1916 subview (X, ALL (), static_cast<size_t> (0));
1919 ViewFill<vec_view_type> vf (X_0, theAlpha);
1922 ViewFill<mv_view_type> vf (X, theAlpha);
1925 for (
size_t k = 0; k < numVecs; ++k) {
1927 vec_view_type X_k = subview (X, ALL (), col);
1928 ViewFill<vec_view_type> vf (X_k, theAlpha);
1933 typedef typename dual_view_type::t_host mv_view_type;
1935 typename mv_view_type::array_layout, HMS> vec_view_type;
1937 this->
template modify<HMS> ();
1939 subview (this->
getDualView ().
template view<HMS> (),
1943 subview (X, ALL (), static_cast<size_t> (0));
1946 ViewFill<vec_view_type> vf (X_0, theAlpha);
1949 ViewFill<mv_view_type> vf (X, theAlpha);
1952 for (
size_t k = 0; k < numVecs; ++k) {
1954 vec_view_type X_k = subview (X, ALL (), col);
1955 ViewFill<vec_view_type> vf (X_k, theAlpha);
1962 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1967 using Teuchos::ArrayRCP;
1968 using Teuchos::Comm;
1975 TEUCHOS_TEST_FOR_EXCEPTION(
1977 "Tpetra::MultiVector::replaceMap: This method does not currently work " 1978 "if the MultiVector is a column view of another MultiVector (that is, if " 1979 "isConstantStride() == false).");
2009 #ifdef HAVE_TEUCHOS_DEBUG 2023 #endif // HAVE_TEUCHOS_DEBUG 2025 if (this->
getMap ().is_null ()) {
2030 TEUCHOS_TEST_FOR_EXCEPTION(
2031 newMap.is_null (), std::invalid_argument,
2032 "Tpetra::MultiVector::replaceMap: both current and new Maps are null. " 2033 "This probably means that the input Map is incorrect.");
2037 const size_t newNumRows = newMap->getNodeNumElements ();
2038 const size_t origNumRows =
view_.dimension_0 ();
2041 if (origNumRows != newNumRows ||
view_.dimension_1 () != numCols) {
2042 view_ = allocDualView<Scalar, LocalOrdinal, GlobalOrdinal, Node> (newNumRows, numCols);
2045 else if (newMap.is_null ()) {
2048 const size_t newNumRows =
static_cast<size_t> (0);
2050 view_ = allocDualView<Scalar, LocalOrdinal, GlobalOrdinal, Node> (newNumRows, numCols);
2053 this->
map_ = newMap;
2056 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2062 using Kokkos::subview;
2065 if (theAlpha == Kokkos::Details::ArithTraits<impl_scalar_type>::one ()) {
2070 const std::pair<size_t, size_t> rowRng (0, lclNumRows);
2071 const std::pair<size_t, size_t> colRng (0, numVecs);
2073 typedef typename dual_view_type::t_dev dev_view_type;
2074 typedef typename dual_view_type::t_host host_view_type;
2083 const bool oneMemorySpace =
2084 Kokkos::Impl::is_same<
typename dev_view_type::memory_space,
2085 typename host_view_type::memory_space>::value;
2086 if (! oneMemorySpace &&
view_.modified_host >=
view_.modified_device) {
2087 auto Y_lcl = subview (this->
view_.h_view, rowRng, colRng);
2090 KokkosBlas::scal (Y_lcl, theAlpha, Y_lcl);
2093 for (
size_t k = 0; k < numVecs; ++k) {
2095 auto Y_k = subview (Y_lcl, ALL (), Y_col);
2096 KokkosBlas::scal (Y_k, theAlpha, Y_k);
2101 auto Y_lcl = subview (this->
view_.d_view, rowRng, colRng);
2104 KokkosBlas::scal (Y_lcl, theAlpha, Y_lcl);
2107 for (
size_t k = 0; k < numVecs; ++k) {
2109 auto Y_k = subview (Y_lcl, ALL (), Y_col);
2110 KokkosBlas::scal (Y_k, theAlpha, Y_k);
2117 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2120 scale (
const Teuchos::ArrayView<const Scalar>& alphas)
2123 const size_t numAlphas =
static_cast<size_t> (alphas.size ());
2124 TEUCHOS_TEST_FOR_EXCEPTION(
2125 numAlphas != numVecs, std::invalid_argument,
"Tpetra::MultiVector::" 2126 "scale: alphas.size() = " << numAlphas <<
" != this->getNumVectors() = " 2130 typedef Kokkos::DualView<impl_scalar_type*, device_type> k_alphas_type ;
2131 k_alphas_type k_alphas (
"alphas::tmp", numAlphas);
2132 k_alphas.template modify<typename k_alphas_type::host_mirror_space> ();
2133 for (
size_t i = 0; i < numAlphas; ++i) {
2136 k_alphas.template sync<typename k_alphas_type::memory_space> ();
2138 this->
scale (k_alphas.d_view);
2141 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2144 scale (
const Kokkos::View<const impl_scalar_type*, device_type>& alphas)
2147 using Kokkos::subview;
2151 TEUCHOS_TEST_FOR_EXCEPTION(
2152 static_cast<size_t> (alphas.dimension_0 ()) != numVecs,
2153 std::invalid_argument,
"Tpetra::MultiVector::scale(alphas): " 2154 "alphas.dimension_0() = " << alphas.dimension_0 ()
2155 <<
" != this->getNumVectors () = " << numVecs <<
".");
2156 const std::pair<size_t, size_t> rowRng (0, lclNumRows);
2157 const std::pair<size_t, size_t> colRng (0, numVecs);
2159 typedef typename dual_view_type::t_dev dev_view_type;
2160 typedef typename dual_view_type::t_host host_view_type;
2168 const bool oneMemorySpace =
2169 Kokkos::Impl::is_same<
typename dev_view_type::memory_space,
2170 typename host_view_type::memory_space>::value;
2171 if (! oneMemorySpace &&
2172 this->
view_.modified_host >= this->view_.modified_device) {
2177 typename input_view_type::HostMirror alphas_h =
2178 Kokkos::create_mirror_view (alphas);
2181 auto Y_lcl = subview (this->
view_.h_view, rowRng, colRng);
2184 KokkosBlas::scal (Y_lcl, alphas_h, Y_lcl);
2187 for (
size_t k = 0; k < numVecs; ++k) {
2189 auto Y_k = subview (Y_lcl, ALL (), Y_col);
2192 KokkosBlas::scal (Y_k, alphas_h(k), Y_k);
2197 auto Y_lcl = subview (this->
view_.d_view, rowRng, colRng);
2200 KokkosBlas::scal (Y_lcl, alphas, Y_lcl);
2203 for (
size_t k = 0; k < numVecs; ++k) {
2205 auto Y_k = subview (Y_lcl, ALL (), Y_col);
2211 KokkosBlas::scal (Y_k, alphas(k), Y_k);
2217 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2224 using Kokkos::subview;
2225 const char tfecfFuncName[] =
"scale: ";
2230 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2232 "this->getLocalLength() = " << lclNumRows <<
" != A.getLocalLength() = " 2234 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2236 "this->getNumVectors() = " << numVecs <<
" != A.getNumVectors() = " 2240 const std::pair<size_t, size_t> rowRng (0, lclNumRows);
2241 const std::pair<size_t, size_t> colRng (0, numVecs);
2243 typedef typename dual_view_type::t_dev dev_view_type;
2244 typedef typename dual_view_type::t_host host_view_type;
2248 const bool oneMemorySpace =
2249 Kokkos::Impl::is_same<
typename dev_view_type::memory_space,
2250 typename host_view_type::memory_space>::value;
2251 if (! oneMemorySpace && A.
view_.modified_host >= A.
view_.modified_device) {
2255 this->
view_.template sync<typename host_view_type::memory_space> ();
2256 this->
view_.template modify<typename host_view_type::memory_space> ();
2257 auto Y_lcl = subview (this->
view_.h_view, rowRng, colRng);
2258 auto X_lcl = subview (A.
view_.h_view, rowRng, colRng);
2261 KokkosBlas::scal (Y_lcl, theAlpha, X_lcl);
2265 for (
size_t k = 0; k < numVecs; ++k) {
2268 auto Y_k = subview (Y_lcl, ALL (), Y_col);
2269 auto X_k = subview (X_lcl, ALL (), X_col);
2271 KokkosBlas::scal (Y_k, theAlpha, X_k);
2278 this->
view_.template sync<typename dev_view_type::memory_space> ();
2279 this->
view_.template modify<typename dev_view_type::memory_space> ();
2280 auto Y_lcl = subview (this->
view_.d_view, rowRng, colRng);
2281 auto X_lcl = subview (A.
view_.d_view, rowRng, colRng);
2284 KokkosBlas::scal (Y_lcl, theAlpha, X_lcl);
2288 for (
size_t k = 0; k < numVecs; ++k) {
2291 auto Y_k = subview (Y_lcl, ALL (), Y_col);
2292 auto X_k = subview (X_lcl, ALL (), X_col);
2294 KokkosBlas::scal (Y_k, theAlpha, X_k);
2301 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2306 const char tfecfFuncName[] =
"reciprocal";
2308 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2310 ": MultiVectors do not have the same local length. " 2313 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2315 ": MultiVectors do not have the same number of columns (vectors). " 2317 <<
" != A.getNumVectors() = " << A.
getNumVectors () <<
".");
2324 view_.template sync<device_type> ();
2325 view_.template modify<device_type> ();
2326 KokkosBlas::reciprocal (
view_.d_view, A.
view_.d_view);
2330 using Kokkos::subview;
2331 typedef Kokkos::View<impl_scalar_type*, device_type> view_type;
2333 view_.template sync<device_type> ();
2334 view_.template modify<device_type> ();
2338 A.
view_.template sync<device_type> ();
2339 A.
view_.template modify<device_type> ();
2341 for (
size_t k = 0; k < numVecs; ++k) {
2343 view_type vector_k = subview (
view_.d_view, ALL (), this_col);
2345 view_type vector_Ak = subview (A.
view_.d_view, ALL (), A_col);
2346 KokkosBlas::reciprocal(vector_k, vector_Ak);
2350 catch (std::runtime_error &e) {
2351 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
true, std::runtime_error,
2352 ": Caught exception from Kokkos: " << e.what () << std::endl);
2357 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2362 const char tfecfFuncName[] =
"abs";
2363 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2365 ": MultiVectors do not have the same local length. " 2368 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2370 ": MultiVectors do not have the same number of columns (vectors). " 2372 <<
" != A.getNumVectors() = " << A.
getNumVectors () <<
".");
2378 view_.template sync<device_type>();
2379 view_.template modify<device_type>();
2380 KokkosBlas::abs (
view_.d_view, A.
view_.d_view);
2384 using Kokkos::subview;
2385 typedef Kokkos::View<impl_scalar_type*, device_type> view_type;
2387 view_.template sync<device_type> ();
2388 view_.template modify<device_type> ();
2389 A.
view_.template sync<device_type> ();
2390 A.
view_.template modify<device_type> ();
2392 for (
size_t k=0; k < numVecs; ++k) {
2394 view_type vector_k = subview (
view_.d_view, ALL (), this_col);
2396 view_type vector_Ak = subview (A.
view_.d_view, ALL (), A_col);
2397 KokkosBlas::abs (vector_k, vector_Ak);
2403 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2411 using Kokkos::subview;
2412 const char tfecfFuncName[] =
"update: ";
2417 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2419 "this->getLocalLength() = " << lclNumRows <<
" != A.getLocalLength() = " 2421 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2423 "this->getNumVectors() = " << numVecs <<
" != A.getNumVectors() = " 2428 const std::pair<size_t, size_t> rowRng (0, lclNumRows);
2429 const std::pair<size_t, size_t> colRng (0, numVecs);
2431 typedef typename dual_view_type::t_dev dev_view_type;
2432 typedef typename dual_view_type::t_host host_view_type;
2436 const bool oneMemorySpace =
2437 Kokkos::Impl::is_same<
typename dev_view_type::memory_space,
2438 typename host_view_type::memory_space>::value;
2439 if (! oneMemorySpace && A.
view_.modified_host >= A.
view_.modified_device) {
2443 this->
view_.template sync<typename host_view_type::memory_space> ();
2444 this->
view_.template modify<typename host_view_type::memory_space> ();
2445 auto Y_lcl = subview (this->
view_.h_view, rowRng, colRng);
2446 auto X_lcl = subview (A.
view_.h_view, rowRng, colRng);
2449 KokkosBlas::axpby (theAlpha, X_lcl, theBeta, Y_lcl);
2453 for (
size_t k = 0; k < numVecs; ++k) {
2456 auto Y_k = subview (Y_lcl, ALL (), Y_col);
2457 auto X_k = subview (X_lcl, ALL (), X_col);
2459 KokkosBlas::axpby (theAlpha, X_k, theBeta, Y_k);
2466 this->
view_.template sync<typename dev_view_type::memory_space> ();
2467 this->
view_.template modify<typename dev_view_type::memory_space> ();
2468 auto Y_lcl = subview (this->
view_.d_view, rowRng, colRng);
2469 auto X_lcl = subview (A.
view_.d_view, rowRng, colRng);
2472 KokkosBlas::axpby (theAlpha, X_lcl, theBeta, Y_lcl);
2476 for (
size_t k = 0; k < numVecs; ++k) {
2479 auto Y_k = subview (Y_lcl, ALL (), Y_col);
2480 auto X_k = subview (X_lcl, ALL (), X_col);
2482 KokkosBlas::axpby (theAlpha, X_k, theBeta, Y_k);
2488 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2495 const Scalar& gamma)
2498 using Kokkos::subview;
2499 const char tfecfFuncName[] =
"update(alpha,A,beta,B,gamma): ";
2502 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2504 "The input MultiVector A has " << A.
getLocalLength () <<
" local " 2505 "row(s), but this MultiVector has " << lclNumRows <<
" local " 2507 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2509 "The input MultiVector B has " << B.
getLocalLength () <<
" local " 2510 "row(s), but this MultiVector has " << lclNumRows <<
" local " 2513 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2515 "The input MultiVector A has " << A.
getNumVectors () <<
" column(s), " 2516 "but this MultiVector has " << numVecs <<
" column(s).");
2517 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2519 "The input MultiVector B has " << B.
getNumVectors () <<
" column(s), " 2520 "but this MultiVector has " << numVecs <<
" column(s).");
2530 this->
view_.template sync<typename dual_view_type::t_dev::memory_space> ();
2531 A.
view_.template sync<typename dual_view_type::t_dev::memory_space> ();
2532 B.
view_.template sync<typename dual_view_type::t_dev::memory_space> ();
2535 this->
template modify<typename dual_view_type::t_dev::memory_space> ();
2537 const std::pair<size_t, size_t> rowRng (0, lclNumRows);
2538 const std::pair<size_t, size_t> colRng (0, numVecs);
2543 auto C_lcl = subview (this->
view_.d_view, rowRng, colRng);
2544 auto A_lcl = subview (A.
view_.d_view, rowRng, colRng);
2545 auto B_lcl = subview (B.
view_.d_view, rowRng, colRng);
2548 KokkosBlas::update (theAlpha, A_lcl, theBeta, B_lcl, theGamma, C_lcl);
2553 for (
size_t k = 0; k < numVecs; ++k) {
2557 KokkosBlas::update (theAlpha, subview (A_lcl, rowRng, A_col),
2558 theBeta, subview (B_lcl, rowRng, B_col),
2559 theGamma, subview (C_lcl, rowRng, this_col));
2564 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2565 Teuchos::ArrayRCP<const Scalar>
2570 using Kokkos::subview;
2571 typedef typename dual_view_type::host_mirror_space host_type;
2572 typedef typename dual_view_type::t_host host_view_type;
2578 view_.template sync<host_type> ();
2581 host_view_type hostView =
view_.template view<host_type> ();
2583 host_view_type hostView_j;
2586 const std::pair<size_t, size_t> colRng (colStart, colStart+1);
2587 hostView_j = subview (hostView, ALL (), colRng);
2590 Teuchos::ArrayRCP<const impl_scalar_type> dataAsArcp =
2591 Kokkos::Compat::persistingView (hostView_j, 0,
getLocalLength ());
2593 #ifdef HAVE_TPETRA_DEBUG 2594 TEUCHOS_TEST_FOR_EXCEPTION(
2595 static_cast<size_t>(hostView_j.dimension_0 ()) < static_cast<size_t>(dataAsArcp.size ()), std::logic_error,
2596 "Tpetra::MultiVector::getData: hostView_j.dimension_0() = " 2597 << hostView_j.dimension_0 () <<
" < dataAsArcp.size() = " 2598 << dataAsArcp.size () <<
". " 2599 "Please report this bug to the Tpetra developers.");
2600 #endif // HAVE_TPETRA_DEBUG 2602 return Teuchos::arcp_reinterpret_cast<
const Scalar> (dataAsArcp);
2605 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2606 Teuchos::ArrayRCP<Scalar>
2611 using Kokkos::subview;
2612 typedef typename dual_view_type::host_mirror_space host_type;
2613 typedef typename dual_view_type::t_host host_view_type;
2619 view_.template sync<host_type> ();
2622 host_view_type hostView =
view_.template view<host_type> ();
2624 host_view_type hostView_j;
2626 hostView_j = subview (hostView, ALL (), Kokkos::pair<int,int>(j,j+1));
2634 view_.template modify<host_type> ();
2637 Teuchos::ArrayRCP<impl_scalar_type> dataAsArcp =
2638 Kokkos::Compat::persistingView (hostView_j, 0,
getLocalLength ());
2640 #ifdef HAVE_TPETRA_DEBUG 2641 TEUCHOS_TEST_FOR_EXCEPTION(
2642 static_cast<size_t>(hostView_j.dimension_0 ()) < static_cast<size_t>(dataAsArcp.size ()), std::logic_error,
2643 "Tpetra::MultiVector::getDataNonConst: hostView_j.dimension_0() = " 2644 << hostView_j.dimension_0 () <<
" < dataAsArcp.size() = " 2645 << dataAsArcp.size () <<
". " 2646 "Please report this bug to the Tpetra developers.");
2647 #endif // HAVE_TPETRA_DEBUG 2649 return Teuchos::arcp_reinterpret_cast<Scalar> (dataAsArcp);
2652 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2657 if (
this != &source) {
2658 base_type::operator= (source);
2680 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2681 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
2683 subCopy (
const Teuchos::ArrayView<const size_t>& cols)
const 2690 bool contiguous =
true;
2691 const size_t numCopyVecs =
static_cast<size_t> (cols.size ());
2692 for (
size_t j = 1; j < numCopyVecs; ++j) {
2693 if (cols[j] != cols[j-1] + static_cast<size_t> (1)) {
2698 if (contiguous && numCopyVecs > 0) {
2699 return this->
subCopy (Teuchos::Range1D (cols[0], cols[numCopyVecs-1]));
2702 RCP<const MV> X_sub = this->
subView (cols);
2703 RCP<MV> Y (
new MV (this->
getMap (), numCopyVecs,
false));
2709 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2710 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
2717 RCP<const MV> X_sub = this->
subView (colRng);
2718 RCP<MV> Y (
new MV (this->
getMap (), static_cast<size_t> (colRng.size ()),
false));
2723 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2730 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2737 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2738 Teuchos::RCP<const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
2741 const size_t offset)
const 2744 using Kokkos::subview;
2749 const size_t newNumRows = subMap->getNodeNumElements ();
2752 const int myRank = this->
getMap ()->getComm ()->getRank ();
2753 TEUCHOS_TEST_FOR_EXCEPTION(
2754 newNumRows + offset > this->
getLocalLength (), std::runtime_error,
2755 "Tpetra::MultiVector::offsetView(NonConst): Invalid input Map. The " 2756 "input Map owns " << newNumRows <<
" entries on process " << myRank <<
2757 ". offset = " << offset <<
". Yet, the MultiVector contains only " 2758 << this->getOrigNumLocalRows () <<
" rows on this process.");
2761 #ifdef HAVE_TPETRA_DEBUG 2764 static_cast<size_t> (0);
2769 #endif // HAVE_TPETRA_DEBUG 2771 const std::pair<size_t, size_t> rowRng (offset, offset + newNumRows);
2775 dual_view_type newView =
2782 if (newView.dimension_0 () == 0 &&
2783 newView.dimension_1 () !=
view_.dimension_1 ()) {
2784 newView = allocDualView<Scalar,
2790 RCP<const MV> subViewMV;
2792 subViewMV = rcp (
new MV (subMap, newView,
origView_));
2797 #ifdef HAVE_TPETRA_DEBUG 2800 static_cast<size_t> (0);
2806 const size_t strideRet = subViewMV->isConstantStride () ?
2807 subViewMV->getStride () :
2808 static_cast<size_t> (0);
2809 const size_t lclNumRowsRet = subViewMV->getLocalLength ();
2810 const size_t numColsRet = subViewMV->getNumVectors ();
2812 const char prefix[] =
"Tpetra::MultiVector::offsetView: ";
2813 const char suffix[] =
". This should never happen. Please report this " 2814 "bug to the Tpetra developers.";
2816 TEUCHOS_TEST_FOR_EXCEPTION(
2817 ! subMap.is_null () && lclNumRowsRet != subMap->getNodeNumElements (),
2818 std::logic_error, prefix <<
"Returned MultiVector has a number of rows " 2819 "different than the number of local indices in the input Map. " 2820 "lclNumRowsRet: " << lclNumRowsRet <<
", subMap->getNodeNumElements(): " 2821 << subMap->getNodeNumElements () << suffix);
2822 TEUCHOS_TEST_FOR_EXCEPTION(
2823 strideBefore != strideAfter || lclNumRowsBefore != lclNumRowsAfter ||
2824 numColsBefore != numColsAfter || hostPtrBefore != hostPtrAfter,
2825 std::logic_error, prefix <<
"Original MultiVector changed dimensions, " 2826 "stride, or host pointer after taking offset view. strideBefore: " <<
2827 strideBefore <<
", strideAfter: " << strideAfter <<
", lclNumRowsBefore: " 2828 << lclNumRowsBefore <<
", lclNumRowsAfter: " << lclNumRowsAfter <<
2829 ", numColsBefore: " << numColsBefore <<
", numColsAfter: " <<
2830 numColsAfter <<
", hostPtrBefore: " << hostPtrBefore <<
", hostPtrAfter: " 2831 << hostPtrAfter << suffix);
2832 TEUCHOS_TEST_FOR_EXCEPTION(
2833 strideBefore != strideRet, std::logic_error, prefix <<
"Returned " 2834 "MultiVector has different stride than original MultiVector. " 2835 "strideBefore: " << strideBefore <<
", strideRet: " << strideRet <<
2836 ", numColsBefore: " << numColsBefore <<
", numColsRet: " << numColsRet
2838 TEUCHOS_TEST_FOR_EXCEPTION(
2839 numColsBefore != numColsRet, std::logic_error,
2840 prefix <<
"Returned MultiVector has a different number of columns than " 2841 "original MultiVector. numColsBefore: " << numColsBefore <<
", " 2842 "numColsRet: " << numColsRet << suffix);
2843 #endif // HAVE_TPETRA_DEBUG 2849 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2850 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
2853 const size_t offset)
2856 return Teuchos::rcp_const_cast<MV> (this->
offsetView (subMap, offset));
2860 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2861 Teuchos::RCP<const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
2863 subView (
const Teuchos::ArrayView<const size_t>& cols)
const 2865 using Teuchos::Array;
2869 const size_t numViewCols =
static_cast<size_t> (cols.size ());
2870 TEUCHOS_TEST_FOR_EXCEPTION(
2871 numViewCols < 1, std::runtime_error,
"Tpetra::MultiVector::subView" 2872 "(const Teuchos::ArrayView<const size_t>&): The input array cols must " 2873 "contain at least one entry, but cols.size() = " << cols.size ()
2878 bool contiguous =
true;
2879 for (
size_t j = 1; j < numViewCols; ++j) {
2880 if (cols[j] != cols[j-1] + static_cast<size_t> (1)) {
2886 if (numViewCols == 0) {
2888 return rcp (
new MV (this->
getMap (), numViewCols));
2891 return this->
subView (Teuchos::Range1D (cols[0], cols[numViewCols-1]));
2899 Array<size_t> newcols (cols.size ());
2900 for (
size_t j = 0; j < numViewCols; ++j) {
2908 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
2909 Teuchos::RCP<const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
2914 using Kokkos::subview;
2915 using Teuchos::Array;
2919 const char tfecfFuncName[] =
"subView(Range1D): ";
2926 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2927 static_cast<size_t> (colRng.size ()) > numVecs, std::runtime_error,
2928 "colRng.size() = " << colRng.size () <<
" > this->getNumVectors() = " 2930 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2931 numVecs != 0 && colRng.size () != 0 &&
2932 (colRng.lbound () <
static_cast<Teuchos::Ordinal
> (0) ||
2933 static_cast<size_t> (colRng.ubound ()) >= numVecs),
2934 std::invalid_argument,
"Nonempty input range [" << colRng.lbound () <<
2935 "," << colRng.ubound () <<
"] exceeds the valid range of column indices " 2936 "[0, " << numVecs <<
"].");
2938 RCP<const MV> X_ret;
2948 const std::pair<size_t, size_t> rows (0, lclNumRows);
2949 if (colRng.size () == 0) {
2950 const std::pair<size_t, size_t> cols (0, 0);
2951 dual_view_type X_sub = takeSubview (this->
view_, ALL (), cols);
2957 const std::pair<size_t, size_t> cols (colRng.lbound (),
2958 colRng.ubound () + 1);
2959 dual_view_type X_sub = takeSubview (this->
view_, ALL (), cols);
2963 if (static_cast<size_t> (colRng.size ()) == static_cast<size_t> (1)) {
2966 const std::pair<size_t, size_t> col (
whichVectors_[0] + colRng.lbound (),
2968 dual_view_type X_sub = takeSubview (
view_, ALL (), col);
2972 Array<size_t> which (
whichVectors_.begin () + colRng.lbound (),
2979 #ifdef HAVE_TPETRA_DEBUG 2980 using Teuchos::Comm;
2981 using Teuchos::outArg;
2982 using Teuchos::REDUCE_MIN;
2983 using Teuchos::reduceAll;
2985 RCP<const Comm<int> > comm = this->
getMap ().is_null () ? Teuchos::null :
2986 this->
getMap ()->getComm ();
2987 if (! comm.is_null ()) {
2991 if (X_ret.is_null ()) {
2994 reduceAll<int, int> (*comm, REDUCE_MIN, lclSuccess, outArg (gblSuccess));
2995 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
2996 lclSuccess != 1, std::logic_error,
"X_ret (the subview of this " 2997 "MultiVector; the return value of this method) is null on some MPI " 2998 "process in this MultiVector's communicator. This should never " 2999 "happen. Please report this bug to the Tpetra developers.");
3001 if (! X_ret.is_null () &&
3002 X_ret->getNumVectors () !=
static_cast<size_t> (colRng.size ())) {
3005 reduceAll<int, int> (*comm, REDUCE_MIN, lclSuccess, outArg (gblSuccess));
3006 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3007 lclSuccess != 1, std::logic_error,
3008 "X_ret->getNumVectors() != colRng.size(), on at least one MPI process " 3009 "in this MultiVector's communicator. This should never happen. " 3010 "Please report this bug to the Tpetra developers.");
3012 #endif // HAVE_TPETRA_DEBUG 3018 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3019 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
3024 return Teuchos::rcp_const_cast<MV> (this->
subView (cols));
3028 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3029 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
3034 return Teuchos::rcp_const_cast<MV> (this->
subView (colRng));
3038 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3039 Teuchos::RCP<const Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
3044 using Kokkos::subview;
3048 #ifdef HAVE_TPETRA_DEBUG 3049 const char tfecfFuncName[] =
"getVector(NonConst): ";
3050 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3051 this->vectorIndexOutOfRange (j), std::runtime_error,
"Input index j (== " 3052 << j <<
") exceeds valid range [0, " << this->
getNumVectors ()
3054 #endif // HAVE_TPETRA_DEBUG 3056 static_cast<size_t> (j) :
3058 const std::pair<size_t, size_t> rng (jj, jj+1);
3059 return rcp (
new V (this->
getMap (),
3060 takeSubview (this->
view_, ALL (), rng),
3065 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3066 Teuchos::RCP<Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
3071 return Teuchos::rcp_const_cast<V> (this->
getVector (j));
3075 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3078 get1dCopy (
const Teuchos::ArrayView<Scalar>& A,
const size_t LDA)
const 3080 using Kokkos::subview;
3082 typedef MakeUnmanagedView<IST, device_type> view_getter_type;
3083 typedef typename view_getter_type::view_type input_col_type;
3085 typedef typename dual_view_type::t_host host_view_type;
3086 typedef typename dual_view_type::t_dev dev_view_type;
3087 typedef Kokkos::View<IST*,
3088 typename host_view_type::array_layout,
3089 typename host_view_type::memory_space> host_col_type;
3090 typedef Kokkos::View<IST*,
3091 typename dev_view_type::array_layout,
3092 typename dev_view_type::memory_space> dev_col_type;
3093 const char tfecfFuncName[] =
"get1dCopy: ";
3097 const std::pair<size_t, size_t> rowRange (0, numRows);
3098 const std::pair<size_t, size_t> colRange (0, numCols);
3100 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3101 LDA < numRows, std::runtime_error,
3102 "LDA = " << LDA <<
" < numRows = " << numRows <<
".");
3103 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3104 numRows > static_cast<size_t> (0) &&
3105 numCols > static_cast<size_t> (0) &&
3106 static_cast<size_t> (A.size ()) < LDA * (numCols - 1) + numRows,
3108 "A.size() = " << A.size () <<
", but its size must be at least " 3109 << (LDA * (numCols - 1) + numRows) <<
" to hold all the entries.");
3119 for (
size_t j = 0; j < numCols; ++j) {
3120 const size_t srcCol =
3122 const size_t dstCol = j;
3123 IST*
const dstColRaw =
3124 reinterpret_cast<IST*
> (A.getRawPtr () + LDA * dstCol);
3125 input_col_type dstColView (dstColRaw, numRows);
3129 if (
view_.modified_host >=
view_.modified_device) {
3130 host_col_type srcColView =
3131 subview (
view_.h_view, rowRange, srcCol);
3132 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3133 dstColView.dimension_0 () != srcColView.dimension_0 (),
3134 std::logic_error,
": srcColView and dstColView have different " 3135 "dimensions. Please report this bug to the Tpetra developers.");
3139 dev_col_type srcColView =
3140 subview (
view_.d_view, rowRange, srcCol);
3141 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3142 dstColView.dimension_0 () != srcColView.dimension_0 (),
3143 std::logic_error,
": srcColView and dstColView have different " 3144 "dimensions. Please report this bug to the Tpetra developers.");
3151 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3154 get2dCopy (
const Teuchos::ArrayView<
const Teuchos::ArrayView<Scalar> >& ArrayOfPtrs)
const 3157 const char tfecfFuncName[] =
"get2dCopy: ";
3161 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3162 static_cast<size_t> (ArrayOfPtrs.size ()) != numCols,
3163 std::runtime_error,
"Input array of pointers must contain as many " 3164 "entries (arrays) as the MultiVector has columns. ArrayOfPtrs.size() = " 3165 << ArrayOfPtrs.size () <<
" != getNumVectors() = " << numCols <<
".");
3167 if (numRows != 0 && numCols != 0) {
3169 for (
size_t j = 0; j < numCols; ++j) {
3170 const size_t dstLen =
static_cast<size_t> (ArrayOfPtrs[j].size ());
3171 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3172 dstLen < numRows, std::invalid_argument,
"Array j = " << j <<
" of " 3173 "the input array of arrays is not long enough to fit all entries in " 3174 "that column of the MultiVector. ArrayOfPtrs[j].size() = " << dstLen
3175 <<
" < getLocalLength() = " << numRows <<
".");
3179 for (
size_t j = 0; j < numCols; ++j) {
3181 const size_t LDA =
static_cast<size_t> (ArrayOfPtrs[j].size ());
3182 X_j->get1dCopy (ArrayOfPtrs[j], LDA);
3187 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3188 Teuchos::ArrayRCP<const Scalar>
3193 return Teuchos::null;
3195 TEUCHOS_TEST_FOR_EXCEPTION(
3197 "get1dView: This MultiVector does not have constant stride, so it is " 3198 "not possible to view its data as a single array. You may check " 3199 "whether a MultiVector has constant stride by calling " 3200 "isConstantStride().");
3204 typedef typename dual_view_type::host_mirror_space host_type;
3205 view_.template sync<host_type> ();
3208 Teuchos::ArrayRCP<const impl_scalar_type> dataAsArcp =
3209 Kokkos::Compat::persistingView (
view_.template view<host_type> ());
3210 return Teuchos::arcp_reinterpret_cast<
const Scalar> (dataAsArcp);
3214 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3215 Teuchos::ArrayRCP<Scalar>
3220 return Teuchos::null;
3222 TEUCHOS_TEST_FOR_EXCEPTION(
3224 "get1dViewNonConst: This MultiVector does not have constant stride, so " 3225 "it is not possible to view its data as a single array. You may check " 3226 "whether a MultiVector has constant stride by calling " 3227 "isConstantStride().");
3231 typedef typename dual_view_type::host_mirror_space host_type;
3232 view_.template sync<host_type> ();
3235 Teuchos::ArrayRCP<impl_scalar_type> dataAsArcp =
3236 Kokkos::Compat::persistingView (
view_.template view<host_type> ());
3237 return Teuchos::arcp_reinterpret_cast<Scalar> (dataAsArcp);
3241 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3242 Teuchos::ArrayRCP<Teuchos::ArrayRCP<Scalar> >
3246 using Teuchos::ArrayRCP;
3248 typename dual_view_type::array_layout,
device_type> col_dual_view_type;
3251 ArrayRCP<ArrayRCP<Scalar> > views (numCols);
3252 for (
size_t j = 0; j < numCols; ++j) {
3254 col_dual_view_type X_col =
3255 Kokkos::subview (
view_, Kokkos::ALL (), col);
3256 ArrayRCP<impl_scalar_type> X_col_arcp =
3257 Kokkos::Compat::persistingView (X_col.d_view);
3258 views[j] = Teuchos::arcp_reinterpret_cast<Scalar> (X_col_arcp);
3263 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3264 Teuchos::ArrayRCP<Teuchos::ArrayRCP<const Scalar> >
3268 using Teuchos::ArrayRCP;
3270 typename dual_view_type::array_layout,
device_type> col_dual_view_type;
3273 ArrayRCP<ArrayRCP<const Scalar> > views (numCols);
3274 for (
size_t j = 0; j < numCols; ++j) {
3276 col_dual_view_type X_col =
3277 Kokkos::subview (
view_, Kokkos::ALL (), col);
3278 ArrayRCP<const impl_scalar_type> X_col_arcp =
3279 Kokkos::Compat::persistingView (X_col.d_view);
3280 views[j] = Teuchos::arcp_reinterpret_cast<
const Scalar> (X_col_arcp);
3285 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3289 Teuchos::ETransp transB,
3290 const Scalar& alpha,
3295 using Teuchos::CONJ_TRANS;
3296 using Teuchos::NO_TRANS;
3297 using Teuchos::TRANS;
3300 using Teuchos::rcpFromRef;
3301 typedef Kokkos::Details::ArithTraits<impl_scalar_type> ATS;
3302 typedef Teuchos::ScalarTraits<Scalar> STS;
3304 const char errPrefix[] =
"Tpetra::MultiVector::multiply: ";
3332 TEUCHOS_TEST_FOR_EXCEPTION(
3333 ATS::is_complex && (transA == TRANS || transB == TRANS),
3334 std::invalid_argument, errPrefix <<
"Transpose without conjugation " 3335 "(transA == TRANS || transB == TRANS) is not supported for complex Scalar " 3338 transA = (transA == NO_TRANS ? NO_TRANS : CONJ_TRANS);
3339 transB = (transB == NO_TRANS ? NO_TRANS : CONJ_TRANS);
3349 TEUCHOS_TEST_FOR_EXCEPTION(
3351 A_ncols != B_nrows, std::runtime_error, errPrefix <<
"Dimensions of " 3352 "*this, op(A), and op(B) must be consistent. Local part of *this is " 3354 <<
", A is " << A_nrows <<
" x " << A_ncols
3355 <<
", and B is " << B_nrows <<
" x " << B_ncols <<
".");
3361 const bool Case1 = C_is_local && A_is_local && B_is_local;
3363 const bool Case2 = C_is_local && ! A_is_local && ! B_is_local &&
3364 transA == CONJ_TRANS && transB == NO_TRANS;
3366 const bool Case3 = ! C_is_local && ! A_is_local && B_is_local &&
3370 TEUCHOS_TEST_FOR_EXCEPTION(
3371 ! Case1 && ! Case2 && ! Case3, std::runtime_error, errPrefix
3372 <<
"Multiplication of op(A) and op(B) into *this is not a " 3373 "supported use case.");
3375 if (beta != STS::zero () && Case2) {
3381 const int myRank = this->
getMap ()->getComm ()->getRank ();
3383 beta_local = STS::zero ();
3393 C_tmp = rcp (
new MV (*
this, Teuchos::Copy));
3395 C_tmp = rcp (
this,
false);
3398 RCP<const MV> A_tmp;
3400 A_tmp = rcp (
new MV (A, Teuchos::Copy));
3402 A_tmp = rcpFromRef (A);
3405 RCP<const MV> B_tmp;
3407 B_tmp = rcp (
new MV (B, Teuchos::Copy));
3409 B_tmp = rcpFromRef (B);
3412 TEUCHOS_TEST_FOR_EXCEPTION(
3413 ! C_tmp->isConstantStride () || ! B_tmp->isConstantStride () ||
3414 ! A_tmp->isConstantStride (), std::logic_error, errPrefix
3415 <<
"Failed to make temporary constant-stride copies of MultiVectors.");
3419 gemm_type::GEMM (transA, transB, alpha,
3420 A_tmp->getDualView ().d_view, B_tmp->getDualView ().d_view,
3421 beta_local, C_tmp->getDualView ().d_view);
3427 A_tmp = Teuchos::null;
3428 B_tmp = Teuchos::null;
3436 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3445 using Kokkos::subview;
3446 const char tfecfFuncName[] =
"elementWiseMultiply: ";
3449 #ifdef HAVE_TPETRA_DEBUG 3450 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3453 "MultiVectors do not have the same local length.");
3454 #endif // HAVE_TPETRA_DEBUG 3455 TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
3456 numVecs != B.
getNumVectors (), std::runtime_error,
"this->getNumVectors" 3457 "() = " << numVecs <<
" != B.getNumVectors() = " << B.
getNumVectors ()
3466 view_.template sync<device_type> ();
3467 view_.template modify<device_type> ();
3468 A.
view_.template sync<device_type> ();
3469 B.
view_.template sync<device_type> ();
3470 KokkosBlas::mult (scalarThis,
view_.d_view, scalarAB,
3471 subview (A.
view_.d_view, ALL (), 0),
3475 view_.template sync<device_type> ();
3476 view_.template modify<device_type> ();
3477 A.
view_.template sync<device_type> ();
3478 B.
view_.template sync<device_type> ();
3480 for (
size_t j = 0; j < numVecs; ++j) {
3484 KokkosBlas::mult (scalarThis,
3485 subview (
view_.d_view, ALL (), C_col),
3487 subview (A.
view_.d_view, ALL (), 0),
3488 subview (B.
view_.d_view, ALL (), B_col));
3493 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3499 using Kokkos::subview;
3500 using Teuchos::reduceAll;
3501 using Teuchos::REDUCE_SUM;
3502 typedef typename dual_view_type::t_dev device_view_type;
3503 typedef typename dual_view_type::host_mirror_space host_mirror_space;
3505 TEUCHOS_TEST_FOR_EXCEPTION(
3507 "Tpetra::MultiVector::reduce() should only be called with locally " 3508 "replicated or otherwise not distributed MultiVector objects.");
3509 const Teuchos::Comm<int>& comm = * (this->
getMap ()->getComm ());
3510 if (comm.getSize () == 1) {
3522 TEUCHOS_TEST_FOR_EXCEPTION(
3523 numLclRows > static_cast<size_t> (std::numeric_limits<int>::max ()),
3524 std::runtime_error,
"Tpetra::MultiVector::reduce: On Process " <<
3525 comm.getRank () <<
", the number of local rows " << numLclRows <<
3526 " does not fit in int.");
3536 device_view_type srcBuf;
3538 srcBuf =
view_.d_view;
3541 srcBuf = device_view_type (
"srcBuf", numLclRows, numCols);
3550 device_view_type tgtBuf (
"tgtBuf", numLclRows, numCols);
3552 const int reduceCount =
static_cast<int> (numLclRows * numCols);
3553 reduceAll<int, impl_scalar_type> (comm, REDUCE_SUM, reduceCount,
3554 srcBuf.ptr_on_device (),
3555 tgtBuf.ptr_on_device ());
3558 view_.template modify<execution_space> ();
3560 const std::pair<size_t, size_t> lclRowRange (0, numLclRows);
3561 device_view_type d_view =
3562 subview (
view_.d_view, lclRowRange, ALL ());
3568 for (
size_t j = 0; j < numCols; ++j) {
3569 device_view_type d_view_j =
3570 subview (d_view, ALL (), std::pair<int,int>(j,j+1));
3571 device_view_type tgtBuf_j =
3572 subview (tgtBuf, ALL (), std::pair<int,int>(j,j+1));
3584 view_.template sync<host_mirror_space> ();
3588 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3595 #ifdef HAVE_TPETRA_DEBUG 3596 const LocalOrdinal minLocalIndex = this->
getMap()->getMinLocalIndex();
3597 const LocalOrdinal maxLocalIndex = this->
getMap()->getMaxLocalIndex();
3598 TEUCHOS_TEST_FOR_EXCEPTION(
3599 MyRow < minLocalIndex || MyRow > maxLocalIndex,
3601 "Tpetra::MultiVector::replaceLocalValue: row index " << MyRow
3602 <<
" is invalid. The range of valid row indices on this process " 3603 << this->
getMap()->getComm()->getRank() <<
" is [" << minLocalIndex
3604 <<
", " << maxLocalIndex <<
"].");
3605 TEUCHOS_TEST_FOR_EXCEPTION(
3606 vectorIndexOutOfRange(VectorIndex),
3608 "Tpetra::MultiVector::replaceLocalValue: vector index " << VectorIndex
3609 <<
" of the multivector is invalid.");
3613 view_.h_view (MyRow, colInd) = ScalarValue;
3617 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3624 #ifdef HAVE_TPETRA_DEBUG 3625 const LocalOrdinal minLocalIndex = this->
getMap()->getMinLocalIndex();
3626 const LocalOrdinal maxLocalIndex = this->
getMap()->getMaxLocalIndex();
3627 TEUCHOS_TEST_FOR_EXCEPTION(
3628 MyRow < minLocalIndex || MyRow > maxLocalIndex,
3630 "Tpetra::MultiVector::sumIntoLocalValue: row index " << MyRow
3631 <<
" is invalid. The range of valid row indices on this process " 3632 << this->
getMap()->getComm()->getRank() <<
" is [" << minLocalIndex
3633 <<
", " << maxLocalIndex <<
"].");
3634 TEUCHOS_TEST_FOR_EXCEPTION(
3635 vectorIndexOutOfRange(VectorIndex),
3637 "Tpetra::MultiVector::sumIntoLocalValue: vector index " << VectorIndex
3638 <<
" of the multivector is invalid.");
3642 view_.h_view (MyRow, colInd) += ScalarValue;
3646 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3653 const LocalOrdinal MyRow = this->
getMap ()->getLocalElement (GlobalRow);
3654 #ifdef HAVE_TPETRA_DEBUG 3655 TEUCHOS_TEST_FOR_EXCEPTION(
3656 MyRow == Teuchos::OrdinalTraits<LocalOrdinal>::invalid (),
3658 "Tpetra::MultiVector::replaceGlobalValue: Global row index " << GlobalRow
3659 <<
"is not present on this process " 3660 << this->
getMap ()->getComm ()->getRank () <<
".");
3661 TEUCHOS_TEST_FOR_EXCEPTION(
3662 vectorIndexOutOfRange (VectorIndex), std::runtime_error,
3663 "Tpetra::MultiVector::replaceGlobalValue: Vector index " << VectorIndex
3664 <<
" of the multivector is invalid.");
3665 #endif // HAVE_TPETRA_DEBUG 3669 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3676 const LocalOrdinal MyRow = this->
getMap ()->getLocalElement (GlobalRow);
3677 #ifdef HAVE_TEUCHOS_DEBUG 3678 TEUCHOS_TEST_FOR_EXCEPTION(
3679 MyRow == Teuchos::OrdinalTraits<LocalOrdinal>::invalid (),
3681 "Tpetra::MultiVector::sumIntoGlobalValue: Global row index " << GlobalRow
3682 <<
"is not present on this process " 3683 << this->
getMap ()->getComm ()->getRank () <<
".");
3684 TEUCHOS_TEST_FOR_EXCEPTION(
3685 vectorIndexOutOfRange(VectorIndex),
3687 "Tpetra::MultiVector::sumIntoGlobalValue: Vector index " << VectorIndex
3688 <<
" of the multivector is invalid.");
3693 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3695 Teuchos::ArrayRCP<T>
3701 typename dual_view_type::array_layout,
3704 col_dual_view_type X_col =
3705 Kokkos::subview (
view_, Kokkos::ALL (), col);
3706 return Kokkos::Compat::persistingView (X_col.d_view);
3709 template <
class Scalar,
3711 class GlobalOrdinal,
3714 KokkosClassic::MultiVector<Scalar, Node>
3718 using Teuchos::ArrayRCP;
3719 typedef KokkosClassic::MultiVector<Scalar, Node> KMV;
3723 ArrayRCP<Scalar> data;
3725 data = Teuchos::null;
3729 Kokkos::Compat::persistingView (
view_.d_view) :
3731 data = Teuchos::arcp_reinterpret_cast<Scalar> (dataTmp);
3738 KMV kmv (this->
getMap ()->getNode ());
3745 template <
class Scalar,
3747 class GlobalOrdinal,
3756 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3762 std::ostringstream oss;
3763 oss << Teuchos::typeName (*
this) <<
" {" 3764 <<
"label: \"" << this->getObjectLabel () <<
"\"" 3768 if (isConstantStride ()) {
3769 oss <<
", columnStride: " <<
getStride ();
3775 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3779 const Teuchos::EVerbosityLevel verbLevel)
const 3781 using Teuchos::ArrayRCP;
3783 using Teuchos::VERB_DEFAULT;
3784 using Teuchos::VERB_NONE;
3785 using Teuchos::VERB_LOW;
3786 using Teuchos::VERB_MEDIUM;
3787 using Teuchos::VERB_HIGH;
3788 using Teuchos::VERB_EXTREME;
3793 const Teuchos::EVerbosityLevel vl =
3794 (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
3796 RCP<const Teuchos::Comm<int> > comm = this->
getMap()->getComm();
3797 const int myImageID = comm->getRank();
3798 const int numImages = comm->getSize();
3800 if (vl != VERB_NONE) {
3802 Teuchos::OSTab tab0 (out);
3804 if (myImageID == 0) {
3805 out <<
"Tpetra::MultiVector:" << endl;
3806 Teuchos::OSTab tab1 (out);
3807 out <<
"Template parameters:" << endl;
3809 Teuchos::OSTab tab2 (out);
3810 out <<
"Scalar: " << Teuchos::TypeNameTraits<Scalar>::name () << endl
3811 <<
"LocalOrdinal: " << Teuchos::TypeNameTraits<LocalOrdinal>::name () << endl
3812 <<
"GlobalOrdinal: " << Teuchos::TypeNameTraits<GlobalOrdinal>::name () << endl
3813 <<
"Node: " << Teuchos::TypeNameTraits<Node>::name () << endl;
3815 out <<
"label: \"" << this->getObjectLabel () <<
"\"" << endl
3820 out <<
"columnStride: " <<
getStride () << endl;
3823 for (
int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
3824 if (myImageID == imageCtr) {
3825 if (vl != VERB_LOW) {
3827 out <<
"Process " << myImageID <<
":" << endl;
3828 Teuchos::OSTab tab2 (out);
3833 if (vl != VERB_MEDIUM) {
3836 out <<
"columnStride: " <<
getStride() << endl;
3838 if (vl == VERB_EXTREME) {
3840 out <<
"values: " << endl;
3841 typename dual_view_type::t_host X = this->
getDualView ().h_view;
3847 if (j + 1 < getNumVectors ()) {
3851 if (i + 1 < getLocalLength ()) {
3868 #if TPETRA_USE_KOKKOS_DISTOBJECT 3869 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3877 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3885 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3893 #else // NOT TPETRA_USE_KOKKOS_DISTOBJECT 3895 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3901 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3907 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3913 #endif // TPETRA_USE_KOKKOS_DISTOBJECT 3915 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3923 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
3928 using Kokkos::parallel_for;
3929 typedef LocalOrdinal LO;
3931 typedef typename dual_view_type::host_mirror_space::device_type HMDT;
3932 const bool debug =
false;
3934 TEUCHOS_TEST_FOR_EXCEPTION(
3937 "Tpetra::deep_copy: Global dimensions of the two Tpetra::MultiVector " 3938 "objects do not match. src has dimensions [" << src.
getGlobalLength ()
3939 <<
"," << src.
getNumVectors () <<
"], and *this has dimensions [" 3942 TEUCHOS_TEST_FOR_EXCEPTION(
3944 "Tpetra::deep_copy: The local row counts of the two Tpetra::MultiVector " 3945 "objects do not match. src has " << src.
getLocalLength () <<
" row(s) " 3948 if (debug && this->
getMap ()->getComm ()->getRank () == 0) {
3949 std::cout <<
"*** MultiVector::assign: ";
3953 if (debug && this->
getMap ()->getComm ()->getRank () == 0) {
3954 std::cout <<
"Both *this and src have constant stride" << std::endl;
3959 this->
template modify<DT> ();
3961 Details::localDeepCopyConstStride (this->
getDualView ().
template view<DT> (),
3963 this->
template sync<HMDT> ();
3966 this->
template modify<HMDT> ();
3968 Details::localDeepCopyConstStride (this->
getDualView ().
template view<HMDT> (),
3970 this->
template sync<DT> ();
3975 if (debug && this->
getMap ()->getComm ()->getRank () == 0) {
3976 std::cout <<
"Only *this has constant stride";
3979 const LO numWhichVecs =
static_cast<LO
> (src.
whichVectors_.size ());
3980 const std::string whichVecsLabel (
"MV::deep_copy::whichVecs");
3986 if (debug && this->
getMap ()->getComm ()->getRank () == 0) {
3987 std::cout <<
"; Copy from device version of src" << std::endl;
3993 typedef Kokkos::DualView<LO*, DT> whichvecs_type;
3994 whichvecs_type srcWhichVecs (whichVecsLabel, numWhichVecs);
3995 srcWhichVecs.template modify<HMDT> ();
3996 for (LO i = 0; i < numWhichVecs; ++i) {
3997 srcWhichVecs.h_view(i) =
static_cast<LO
> (src.
whichVectors_[i]);
4000 srcWhichVecs.template sync<DT> ();
4003 this->
template modify<DT> ();
4008 Details::localDeepCopy (this->
getDualView ().
template view<DT> (),
4010 true,
false, srcWhichVecs.d_view, srcWhichVecs.d_view);
4013 this->
template sync<HMDT> ();
4016 if (debug && this->
getMap ()->getComm ()->getRank () == 0) {
4017 std::cout <<
"; Copy from host version of src" << std::endl;
4023 typedef Kokkos::View<LO*, HMDT> whichvecs_type;
4024 whichvecs_type srcWhichVecs (whichVecsLabel, numWhichVecs);
4025 for (LO i = 0; i < numWhichVecs; ++i) {
4031 Details::localDeepCopy (this->
getDualView ().
template view<HMDT> (),
4033 true,
false, srcWhichVecs, srcWhichVecs);
4035 this->
template sync<DT> ();
4040 if (debug && this->
getMap ()->getComm ()->getRank () == 0) {
4041 std::cout <<
"Only src has constant stride" << std::endl;
4049 typedef Kokkos::DualView<LO*, DT> whichvecs_type;
4050 const std::string whichVecsLabel (
"MV::deep_copy::whichVecs");
4051 const LO numWhichVecs =
static_cast<LO
> (this->
whichVectors_.size ());
4052 whichvecs_type whichVecs (whichVecsLabel, numWhichVecs);
4053 whichVecs.template modify<HMDT> ();
4054 for (LO i = 0; i < numWhichVecs; ++i) {
4058 whichVecs.template sync<DT> ();
4061 Details::localDeepCopy (this->
getDualView ().
template view<DT> (),
4064 whichVecs.d_view, whichVecs.d_view);
4070 this->
template sync<HMDT> ();
4077 typedef Kokkos::View<LO*, HMDT> whichvecs_type;
4078 const LO numWhichVecs =
static_cast<LO
> (this->
whichVectors_.size ());
4079 whichvecs_type whichVecs (
"MV::deep_copy::whichVecs", numWhichVecs);
4080 for (LO i = 0; i < numWhichVecs; ++i) {
4085 Details::localDeepCopy (this->
getDualView ().
template view<HMDT> (),
4088 whichVecs, whichVecs);
4093 this->
template sync<DT> ();
4097 if (debug && this->
getMap ()->getComm ()->getRank () == 0) {
4098 std::cout <<
"Neither *this nor src has constant stride" << std::endl;
4107 const LO dstNumWhichVecs =
static_cast<LO
> (this->
whichVectors_.size ());
4108 Kokkos::DualView<LO*, DT> whichVecsDst (
"MV::deep_copy::whichVecsDst",
4110 whichVecsDst.template modify<HMDT> ();
4111 for (LO i = 0; i < dstNumWhichVecs; ++i) {
4112 whichVecsDst.h_view(i) =
static_cast<LO
> (this->
whichVectors_[i]);
4115 whichVecsDst.template sync<DT> ();
4121 const LO srcNumWhichVecs =
static_cast<LO
> (src.
whichVectors_.size ());
4122 Kokkos::DualView<LO*, DT> whichVecsSrc (
"MV::deep_copy::whichVecsSrc",
4124 whichVecsSrc.template modify<HMDT> ();
4125 for (LO i = 0; i < srcNumWhichVecs; ++i) {
4126 whichVecsSrc.h_view(i) =
static_cast<LO
> (src.
whichVectors_[i]);
4129 whichVecsSrc.template sync<DT> ();
4133 Details::localDeepCopy (this->
getDualView ().
template view<DT> (),
4136 whichVecsDst.d_view, whichVecsSrc.d_view);
4139 const LO dstNumWhichVecs =
static_cast<LO
> (this->
whichVectors_.size ());
4140 Kokkos::View<LO*, HMDT> whichVectorsDst (
"dstWhichVecs", dstNumWhichVecs);
4141 for (LO i = 0; i < dstNumWhichVecs; ++i) {
4146 const LO srcNumWhichVecs =
static_cast<LO
> (src.
whichVectors_.size ());
4147 Kokkos::View<LO*, HMDT> whichVectorsSrc (
"srcWhichVecs", srcNumWhichVecs);
4148 for (LO i = 0; i < srcNumWhichVecs; ++i) {
4154 Details::localDeepCopy (this->
getDualView ().
template view<HMDT> (),
4157 whichVectorsDst, whichVectorsSrc);
4164 this->
template sync<HMDT> ();
4171 template <
class Scalar,
class LO,
class GO,
class NT, const
bool classic>
4172 Teuchos::RCP<MultiVector<Scalar, LO, GO, NT, classic> >
4177 return Teuchos::rcp (
new MV (map, numVectors));
4180 template <
class ST,
class LO,
class GO,
class NT, const
bool classic>
4198 #define TPETRA_MULTIVECTOR_INSTANT(SCALAR,LO,GO,NODE) \ 4199 template class MultiVector< SCALAR , LO , GO , NODE >; \ 4200 template MultiVector< SCALAR , LO , GO , NODE > createCopy( const MultiVector< SCALAR , LO , GO , NODE >& src); \ 4201 template Teuchos::RCP<MultiVector< SCALAR , LO , GO , NODE > > createMultiVector (const Teuchos::RCP<const Map<LO, GO, NODE> >& map, size_t numVectors); 4203 #endif // TPETRA_MULTIVECTOR_DEF_HPP void scale(const Scalar &alpha)
Scale in place: this = alpha*this.
size_t getLocalLength() const
Local number of rows on the calling process.
void sumIntoLocalValue(LocalOrdinal localRow, size_t col, const impl_scalar_type &value)
Add value to existing value, using local (row) index.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
void get1dCopy(const Teuchos::ArrayView< Scalar > &A, const size_t LDA) const
Fill the given array with a copy of this multivector's local values.
Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > > subViewNonConst(const Teuchos::Range1D &colRng)
Return a MultiVector with views of selected columns.
void update(const Scalar &alpha, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &A, const Scalar &beta)
Update: this = beta*this + alpha*A.
void sumIntoGlobalValue(GlobalOrdinal globalRow, size_t col, const impl_scalar_type &value)
Add value to existing value, using global (row) index.
friend 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.
Teuchos::ArrayRCP< const Scalar > get1dView() const
Const persisting (1-D) view of this multivector's local values.
virtual void removeEmptyProcessesInPlace(const Teuchos::RCP< const map_type > &newMap)
Remove processes owning zero rows from the Map and their communicator.
MultiVector< ST, LO, GO, NT, classic > createCopy(const MultiVector< ST, LO, GO, NT, classic > &src)
Return a deep copy of the given MultiVector.
void replaceLocalValue(LocalOrdinal localRow, size_t col, const impl_scalar_type &value)
Replace value, using local (row) index.
void normInf(const Kokkos::View< mag_type *, device_type > &norms) const
Compute the infinity-norm of each vector (column), storing the result in a device view...
void abs(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &A)
Put element-wise absolute values of input Multi-vector in target: A = abs(this)
Teuchos::Array< size_t > whichVectors_
Indices of columns this multivector is viewing.
One or more distributed dense vectors.
Teuchos::ArrayRCP< Scalar > getDataNonConst(size_t j)
View of the local values in a particular vector of this multivector.
Teuchos::ArrayRCP< T > getSubArrayRCP(Teuchos::ArrayRCP< T > arr, size_t j) const
Persisting view of j-th column in the given ArrayRCP.
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.
void get2dCopy(const Teuchos::ArrayView< const Teuchos::ArrayView< Scalar > > &ArrayOfPtrs) const
Fill the given array with a copy of this multivector's local values.
Node::device_type device_type
The Kokkos device type.
Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > > offsetViewNonConst(const Teuchos::RCP< const map_type > &subMap, const size_t offset)
Return a nonconst view of a subset of rows.
size_t getOrigNumLocalCols() const
"Original" number of columns in the (local) data.
void randomize()
Set all values in the multivector to pseudorandom numbers.
bool isConstantStride() const
Whether this multivector has constant stride between columns.
virtual bool checkSizes(const SrcDistObject &sourceObj)
Whether data redistribution between sourceObj and this object is legal.
dual_view_type view_
The Kokkos::DualView containing the MultiVector's data.
Kokkos::Details::InnerProductSpaceTraits< impl_scalar_type >::dot_type dot_type
Type of an inner ("dot") product result.
void norm1(const Kokkos::View< mag_type *, device_type > &norms) const
Compute the one-norm of each vector (column), storing the result in a device view.
Teuchos::RCP< const Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > > getVector(const size_t j) const
Return a Vector which is a const view of column j.
Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > > createMultiVector(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &map, const size_t numVectors)
Nonmember MultiVector "constructor": Create a MultiVector from a given Map.
void replaceMap(const Teuchos::RCP< const map_type > &map)
Replace the underlying Map in place.
void meanValue(const Teuchos::ArrayView< impl_scalar_type > &means) const
Compute mean (average) value of each column.
void reduce()
Sum values of a locally replicated multivector across all processes.
size_t global_size_t
Global size_t object.
Teuchos::ArrayRCP< Teuchos::ArrayRCP< const Scalar > > get2dView() const
Return const persisting pointers to values.
EWhichNormImpl
Input argument for localNormImpl() (which see).
void replaceGlobalValue(GlobalOrdinal globalRow, size_t col, const impl_scalar_type &value)
Replace value, using global (row) index.
void norm2(const Kokkos::View< mag_type *, device_type > &norms) const
Compute the two-norm of each vector (column), storing the result in a device view.
Insert new values that don't currently exist.
void createViews() const
Hook for creating a const view.
dual_view_type getDualView() const
Get the Kokkos::DualView which implements local storage.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print the object with the given verbosity level to a FancyOStream.
Teuchos::RCP< const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > > offsetView(const Teuchos::RCP< const map_type > &subMap, const size_t offset) const
Return a const view of a subset of rows.
Node::execution_space execution_space
Type of the (new) Kokkos execution space.
void normWeighted(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &weights, const Teuchos::ArrayView< mag_type > &norms) const
void multiply(Teuchos::ETransp transA, Teuchos::ETransp transB, const Scalar &alpha, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &A, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &B, const Scalar &beta)
Matrix-matrix multiplication: this = beta*this + alpha*op(A)*op(B).
Sets up and executes a communication plan for a Tpetra DistObject.
CombineMode
Rule for combining data in an Import or Export.
Sum new values into existing values.
MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > & operator=(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &source)
Assign the contents of source to this multivector (deep copy).
Teuchos::RCP< const map_type > map_
The Map over which this object is distributed.
void createViewsNonConst(KokkosClassic::ReadWriteOption rwo)
Hook for creating a nonconst view.
bool isDistributed() const
Whether this is a globally distributed object.
Teuchos::ArrayRCP< const Scalar > getData(size_t j) const
Const view of the local values in a particular vector of this multivector.
Replace old value with maximum of magnitudes of old and new values.
Abstract base class for objects that can be the source of an Import or Export operation.
Teuchos::ArrayRCP< Scalar > get1dViewNonConst()
Nonconst persisting (1-D) view of this multivector's local values.
Replace existing values with new values.
size_t getStride() const
Stride between columns in the multivector.
void reciprocal(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &A)
Put element-wise reciprocal values of input Multi-vector in target, this(i,j) = 1/A(i,j).
KokkosClassic::MultiVector< Scalar, Node > getLocalMV() const
A view of the underlying KokkosClassic::MultiVector object.
void putScalar(const Scalar &value)
Set all values in the multivector with the given value.
global_size_t getGlobalLength() const
Global number of rows in the multivector.
Kokkos::Details::ArithTraits< Scalar >::val_type impl_scalar_type
The type used internally in place of Scalar.
virtual ~MultiVector()
Destructor (virtual for memory safety of derived classes).
size_t getOrigNumLocalRows() const
"Original" number of rows in the (local) data.
void releaseViews() const
Hook for releasing views.
Kokkos::Details::ArithTraits< impl_scalar_type >::mag_type mag_type
Type of a norm result.
Kokkos::DualView< impl_scalar_type **, Kokkos::LayoutLeft, typename execution_space::execution_space > dual_view_type
Kokkos::DualView specialization used by this class.
Describes a parallel distribution of objects over processes.
Class that provides GEMM for a particular Kokkos Device.
A distributed dense vector.
Stand-alone utility functions and macros.
virtual std::string description() const
A simple one-line description of this object.
void assign(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &src)
Copy the contents of src into *this (deep copy).
size_t getNumVectors() const
Number of columns in the multivector.
MultiVector()
Default constructor: makes a MultiVector with no rows or columns.
Teuchos::ArrayRCP< Teuchos::ArrayRCP< Scalar > > get2dViewNonConst()
Return non-const persisting pointers to values.
EWhichNorm
Input argument for normImpl() (which see).
virtual Teuchos::RCP< const map_type > getMap() const
The Map describing the parallel distribution of this object.
virtual size_t constantNumberOfPackets() const
Number of packets to send per LID.
void dot(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &A, const Teuchos::ArrayView< dot_type > &dots) const
Compute the dot product of each corresponding pair of vectors (columns) in A and B.
Teuchos::RCP< Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > > getVectorNonConst(const size_t j)
Return a Vector which is a nonconst view of column j.
Teuchos::RCP< const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > > subView(const Teuchos::Range1D &colRng) const
Return a const MultiVector with const views of selected columns.
void elementWiseMultiply(Scalar scalarAB, const Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &A, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &B, Scalar scalarThis)
Multiply a Vector A elementwise by a MultiVector B.
Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > > subCopy(const Teuchos::Range1D &colRng) const
Return a MultiVector with copies of selected columns.
void normImpl(const Kokkos::View< mag_type *, device_type > &norms, const EWhichNorm whichNorm) const
Compute the norm of each vector (column), storing the result in a device View.
dual_view_type origView_
The "original view" of the MultiVector's data.