11#ifndef TPETRA_MULTIVECTOR_DEF_HPP
12#define TPETRA_MULTIVECTOR_DEF_HPP
24#include "Tpetra_Vector.hpp"
36#include "Tpetra_Details_Random.hpp"
37#ifdef HAVE_TPETRACORE_TEUCHOSNUMERICS
38# include "Teuchos_SerialDenseMatrix.hpp"
40#include "Tpetra_KokkosRefactor_Details_MultiVectorDistObjectKernels.hpp"
41#include "KokkosCompat_View.hpp"
42#include "KokkosBlas.hpp"
43#include "KokkosKernels_Utils.hpp"
44#include "Kokkos_Random.hpp"
45#include "Kokkos_ArithTraits.hpp"
49#ifdef HAVE_TPETRA_INST_FLOAT128
52 template<
class Generator>
53 struct rand<Generator, __float128> {
54 static KOKKOS_INLINE_FUNCTION __float128 max ()
56 return static_cast<__float128
> (1.0);
58 static KOKKOS_INLINE_FUNCTION __float128
63 const __float128 scalingFactor =
64 static_cast<__float128
> (std::numeric_limits<double>::min ()) /
65 static_cast<__float128
> (2.0);
66 const __float128 higherOrderTerm =
static_cast<__float128
> (gen.drand ());
67 const __float128 lowerOrderTerm =
68 static_cast<__float128
> (gen.drand ()) * scalingFactor;
69 return higherOrderTerm + lowerOrderTerm;
71 static KOKKOS_INLINE_FUNCTION __float128
72 draw (Generator& gen,
const __float128& range)
75 const __float128 scalingFactor =
76 static_cast<__float128
> (std::numeric_limits<double>::min ()) /
77 static_cast<__float128
> (2.0);
78 const __float128 higherOrderTerm =
79 static_cast<__float128
> (gen.drand (range));
80 const __float128 lowerOrderTerm =
81 static_cast<__float128
> (gen.drand (range)) * scalingFactor;
82 return higherOrderTerm + lowerOrderTerm;
84 static KOKKOS_INLINE_FUNCTION __float128
85 draw (Generator& gen,
const __float128& start,
const __float128& end)
88 const __float128 scalingFactor =
89 static_cast<__float128
> (std::numeric_limits<double>::min ()) /
90 static_cast<__float128
> (2.0);
91 const __float128 higherOrderTerm =
92 static_cast<__float128
> (gen.drand (start, end));
93 const __float128 lowerOrderTerm =
94 static_cast<__float128
> (gen.drand (start, end)) * scalingFactor;
95 return higherOrderTerm + lowerOrderTerm;
117 template<
class ST,
class LO,
class GO,
class NT>
119 allocDualView (
const size_t lclNumRows,
120 const size_t numCols,
121 const bool zeroOut =
true,
122 const bool allowPadding =
false)
124 using ::Tpetra::Details::Behavior;
125 using Kokkos::AllowPadding;
126 using Kokkos::view_alloc;
127 using Kokkos::WithoutInitializing;
130 typedef typename dual_view_type::t_dev dev_view_type;
136 const std::string label (
"MV::DualView");
137 const bool debug = Behavior::debug ();
147 dev_view_type d_view;
150 d_view = dev_view_type (view_alloc (label, AllowPadding),
151 lclNumRows, numCols);
154 d_view = dev_view_type (view_alloc (label),
155 lclNumRows, numCols);
160 d_view = dev_view_type (view_alloc (label,
163 lclNumRows, numCols);
166 d_view = dev_view_type (view_alloc (label, WithoutInitializing),
167 lclNumRows, numCols);
178 const ST nan = Kokkos::ArithTraits<ST>::nan ();
179 KokkosBlas::fill (d_view, nan);
183 TEUCHOS_TEST_FOR_EXCEPTION
184 (
static_cast<size_t> (d_view.extent (0)) != lclNumRows ||
185 static_cast<size_t> (d_view.extent (1)) != numCols, std::logic_error,
186 "allocDualView: d_view's dimensions actual dimensions do not match "
187 "requested dimensions. d_view is " << d_view.extent (0) <<
" x " <<
188 d_view.extent (1) <<
"; requested " << lclNumRows <<
" x " << numCols
189 <<
". Please report this bug to the Tpetra developers.");
192 return wrapped_dual_view_type(d_view);
199 template<
class T,
class ExecSpace>
200 struct MakeUnmanagedView {
210 typedef typename std::conditional<
211 Kokkos::SpaceAccessibility<
212 typename ExecSpace::memory_space,
213 Kokkos::HostSpace>::accessible,
214 typename ExecSpace::device_type,
215 typename Kokkos::DualView<T*, ExecSpace>::host_mirror_space>::type host_exec_space;
216 typedef Kokkos::LayoutLeft array_layout;
217 typedef Kokkos::View<T*, array_layout, host_exec_space,
218 Kokkos::MemoryUnmanaged> view_type;
220 static view_type getView (
const Teuchos::ArrayView<T>& x_in)
222 const size_t numEnt =
static_cast<size_t> (x_in.size ());
226 return view_type (x_in.getRawPtr (), numEnt);
232 template<
class WrappedDualViewType>
234 takeSubview (
const WrappedDualViewType& X,
235 const std::pair<size_t, size_t>& rowRng,
236 const Kokkos::ALL_t& colRng)
240 return WrappedDualViewType(X,rowRng,colRng);
243 template<
class WrappedDualViewType>
245 takeSubview (
const WrappedDualViewType& X,
246 const Kokkos::ALL_t& rowRng,
247 const std::pair<size_t, size_t>& colRng)
249 using DualViewType =
typename WrappedDualViewType::DVT;
252 if (X.extent (0) == 0 && X.extent (1) != 0) {
253 return WrappedDualViewType(DualViewType (
"MV::DualView", 0, colRng.second - colRng.first));
256 return WrappedDualViewType(X,rowRng,colRng);
260 template<
class WrappedDualViewType>
262 takeSubview (
const WrappedDualViewType& X,
263 const std::pair<size_t, size_t>& rowRng,
264 const std::pair<size_t, size_t>& colRng)
266 using DualViewType =
typename WrappedDualViewType::DVT;
276 if (X.extent (0) == 0 && X.extent (1) != 0) {
277 return WrappedDualViewType(DualViewType (
"MV::DualView", 0, colRng.second - colRng.first));
280 return WrappedDualViewType(X,rowRng,colRng);
284 template<
class WrappedOrNotDualViewType>
286 getDualViewStride (
const WrappedOrNotDualViewType& dv)
292 size_t strides[WrappedOrNotDualViewType::t_dev::rank+1];
294 const size_t LDA = strides[1];
295 const size_t numRows = dv.extent (0);
298 return (numRows == 0) ? size_t (1) : numRows;
305 template<
class ViewType>
307 getViewStride (
const ViewType& view)
309 const size_t LDA = view.stride (1);
310 const size_t numRows = view.extent (0);
313 return (numRows == 0) ? size_t (1) : numRows;
320 template <
class impl_scalar_type,
class buffer_device_type>
323 Kokkos::DualView<impl_scalar_type*, buffer_device_type> imports
326 if (! imports.need_sync_device ()) {
331 size_t localLengthThreshold =
333 return imports.extent(0) <= localLengthThreshold;
338 template <
class SC,
class LO,
class GO,
class NT>
340 runKernelOnHost (const ::Tpetra::MultiVector<SC, LO, GO, NT>& X)
342 if (! X.need_sync_device ()) {
347 size_t localLengthThreshold =
349 return X.getLocalLength () <= localLengthThreshold;
353 template <
class SC,
class LO,
class GO,
class NT>
355 multiVectorNormImpl (typename ::Tpetra::MultiVector<SC, LO, GO, NT>::mag_type norms[],
357 const ::Tpetra::Details::EWhichNorm whichNorm)
360 using ::Tpetra::Details::normImpl;
362 using val_type =
typename MV::impl_scalar_type;
363 using mag_type =
typename MV::mag_type;
364 using dual_view_type =
typename MV::dual_view_type;
366 auto map =
X.getMap ();
367 auto comm =
map.is_null () ?
nullptr :
map->getComm ().getRawPtr ();
368 auto whichVecs = getMultiVectorWhichVectors (
X);
369 const bool isConstantStride =
X.isConstantStride ();
370 const bool isDistributed =
X.isDistributed ();
374 using view_type =
typename dual_view_type::t_host;
375 using array_layout =
typename view_type::array_layout;
376 using device_type =
typename view_type::device_type;
378 auto X_lcl =
X.getLocalViewHost(Access::ReadOnly);
379 normImpl<val_type, array_layout, device_type,
381 isConstantStride, isDistributed, comm);
384 using view_type =
typename dual_view_type::t_dev;
385 using array_layout =
typename view_type::array_layout;
386 using device_type =
typename view_type::device_type;
388 auto X_lcl =
X.getLocalViewDevice(Access::ReadOnly);
389 normImpl<val_type, array_layout, device_type,
391 isConstantStride, isDistributed, comm);
400 template <
typename DstView,
typename SrcView>
401 struct AddAssignFunctor {
414 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
421 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
427 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
440 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
446 whichVectors_ (
source.whichVectors_)
449 const char tfecfFuncName[] =
"MultiVector(const MultiVector&, "
450 "const Teuchos::DataAccess): ";
458 this->
view_ = cpy.view_;
465 true, std::invalid_argument,
"Second argument 'copyOrView' has an "
466 "invalid value " <<
copyOrView <<
". Valid values include "
467 "Teuchos::Copy = " << Teuchos::Copy <<
" and Teuchos::View = "
468 << Teuchos::View <<
".");
472 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
481 map->getLocalNumElements ();
487 std::invalid_argument,
"Kokkos::DualView does not match Map. "
490 <<
", and getStride() = " <<
LDA <<
".");
492 using ::Tpetra::Details::Behavior;
493 const bool debug = Behavior::debug ();
495 using ::Tpetra::Details::checkGlobalDualViewValidity;
497 const bool verbose = Behavior::verbose ();
498 const auto comm =
map.is_null () ? Teuchos::null :
map->getComm ();
500 checkGlobalDualViewValidity (&
gblErrStrm, view, verbose,
508 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
517 map->getLocalNumElements ();
523 std::invalid_argument,
"Kokkos::DualView does not match Map. "
526 <<
", and getStride() = " <<
LDA <<
".");
528 using ::Tpetra::Details::Behavior;
529 const bool debug = Behavior::debug ();
531 using ::Tpetra::Details::checkGlobalWrappedDualViewValidity;
533 const bool verbose = Behavior::verbose ();
534 const auto comm =
map.is_null () ? Teuchos::null :
map->getComm ();
536 checkGlobalWrappedDualViewValidity (&
gblErrStrm, view, verbose,
545 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
548 const typename dual_view_type::t_dev&
d_view) :
551 using Teuchos::ArrayRCP;
560 (
LDA <
lclNumRows, std::invalid_argument,
"Map does not match "
561 "Kokkos::View. map->getLocalNumElements() = " <<
lclNumRows
562 <<
", View's column stride = " <<
LDA
563 <<
", and View's extent(0) = " <<
d_view.extent (0) <<
".");
569 using ::Tpetra::Details::Behavior;
570 const bool debug = Behavior::debug ();
572 using ::Tpetra::Details::checkGlobalWrappedDualViewValidity;
574 const bool verbose = Behavior::verbose ();
575 const auto comm =
map.is_null () ? Teuchos::null :
map->getComm ();
588 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
596 const char tfecfFuncName[] =
"MultiVector(map,view,origView): ";
601 LDA <
lclNumRows, std::invalid_argument,
"The input Kokkos::DualView's "
602 "column stride LDA = " <<
LDA <<
" < getLocalLength() = " <<
lclNumRows
603 <<
". This may also mean that the input origView's first dimension (number "
604 "of rows = " <<
origView.extent (0) <<
") does not not match the number "
605 "of entries in the Map on the calling process.");
607 using ::Tpetra::Details::Behavior;
608 const bool debug = Behavior::debug ();
610 using ::Tpetra::Details::checkGlobalDualViewValidity;
612 const bool verbose = Behavior::verbose ();
613 const auto comm =
map.is_null () ? Teuchos::null :
map->getComm ();
615 checkGlobalDualViewValidity (&
gblErrStrm, view, verbose,
627 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
637 using Kokkos::subview;
638 const char tfecfFuncName[] =
"MultiVector(map,view,whichVectors): ";
640 using ::Tpetra::Details::Behavior;
641 const bool debug = Behavior::debug ();
643 using ::Tpetra::Details::checkGlobalDualViewValidity;
645 const bool verbose = Behavior::verbose ();
646 const auto comm =
map.is_null () ? Teuchos::null :
map->getComm ();
648 checkGlobalDualViewValidity (&
gblErrStrm, view, verbose,
655 map->getLocalNumElements ();
663 view.extent (1) != 0 &&
static_cast<size_t> (view.extent (0)) <
lclNumRows,
664 std::invalid_argument,
"view.extent(0) = " << view.extent (0)
665 <<
" < map->getLocalNumElements() = " <<
lclNumRows <<
".");
668 view.extent (1) != 0 && view.extent (1) == 0,
669 std::invalid_argument,
"view.extent(1) = 0, but whichVectors.size()"
672 typedef Teuchos::ArrayView<const size_t>::size_type size_type;
675 whichVectors[
k] == Teuchos::OrdinalTraits<size_t>::invalid (),
676 std::invalid_argument,
"whichVectors[" <<
k <<
"] = "
677 "Teuchos::OrdinalTraits<size_t>::invalid().");
681 view.extent (1) != 0 &&
static_cast<size_t> (view.extent (1)) <=
maxColInd,
682 std::invalid_argument,
"view.extent(1) = " << view.extent (1)
683 <<
" <= max(whichVectors) = " <<
maxColInd <<
".");
691 "LDA = " <<
LDA <<
" < this->getLocalLength() = " <<
lclNumRows <<
".");
707 whichVectors_.clear ();
711 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
721 using Kokkos::subview;
722 const char tfecfFuncName[] =
"MultiVector(map,view,whichVectors): ";
724 using ::Tpetra::Details::Behavior;
725 const bool debug = Behavior::debug ();
727 using ::Tpetra::Details::checkGlobalWrappedDualViewValidity;
729 const bool verbose = Behavior::verbose ();
730 const auto comm =
map.is_null () ? Teuchos::null :
map->getComm ();
732 checkGlobalWrappedDualViewValidity (&
gblErrStrm, view, verbose,
739 map->getLocalNumElements ();
747 view.extent (1) != 0 &&
static_cast<size_t> (view.extent (0)) <
lclNumRows,
748 std::invalid_argument,
"view.extent(0) = " << view.extent (0)
749 <<
" < map->getLocalNumElements() = " <<
lclNumRows <<
".");
752 view.extent (1) != 0 && view.extent (1) == 0,
753 std::invalid_argument,
"view.extent(1) = 0, but whichVectors.size()"
756 typedef Teuchos::ArrayView<const size_t>::size_type size_type;
759 whichVectors[
k] == Teuchos::OrdinalTraits<size_t>::invalid (),
760 std::invalid_argument,
"whichVectors[" <<
k <<
"] = "
761 "Teuchos::OrdinalTraits<size_t>::invalid().");
765 view.extent (1) != 0 &&
static_cast<size_t> (view.extent (1)) <=
maxColInd,
766 std::invalid_argument,
"view.extent(1) = " << view.extent (1)
767 <<
" <= max(whichVectors) = " <<
maxColInd <<
".");
775 "LDA = " <<
LDA <<
" < this->getLocalLength() = " <<
lclNumRows <<
".");
796 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
807 using Kokkos::subview;
808 const char tfecfFuncName[] =
"MultiVector(map,view,origView,whichVectors): ";
810 using ::Tpetra::Details::Behavior;
811 const bool debug = Behavior::debug ();
813 using ::Tpetra::Details::checkGlobalDualViewValidity;
815 const bool verbose = Behavior::verbose ();
816 const auto comm =
map.is_null () ? Teuchos::null :
map->getComm ();
818 checkGlobalDualViewValidity (&
gblErrStrm, view, verbose,
828 const size_t lclNumRows = this->getLocalLength ();
836 view.extent (1) != 0 &&
static_cast<size_t> (view.extent (0)) <
lclNumRows,
837 std::invalid_argument,
"view.extent(0) = " << view.extent (0)
838 <<
" < map->getLocalNumElements() = " <<
lclNumRows <<
".");
841 view.extent (1) != 0 && view.extent (1) == 0,
842 std::invalid_argument,
"view.extent(1) = 0, but whichVectors.size()"
845 typedef Teuchos::ArrayView<const size_t>::size_type size_type;
848 whichVectors[
k] == Teuchos::OrdinalTraits<size_t>::invalid (),
849 std::invalid_argument,
"whichVectors[" <<
k <<
"] = "
850 "Teuchos::OrdinalTraits<size_t>::invalid().");
854 view.extent (1) != 0 &&
static_cast<size_t> (view.extent (1)) <=
maxColInd,
855 std::invalid_argument,
"view.extent(1) = " << view.extent (1)
856 <<
" <= max(whichVectors) = " <<
maxColInd <<
".");
863 (
LDA <
lclNumRows, std::invalid_argument,
"Map and DualView origView "
864 "do not match. LDA = " <<
LDA <<
" < this->getLocalLength() = " <<
866 <<
", origView.stride(1) = " <<
origView.view_device().stride(1) <<
".");
882 whichVectors_.clear ();
886 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
889 const Teuchos::ArrayView<const Scalar>&
data,
896 const char tfecfFuncName[] =
"MultiVector(map,data,LDA,numVecs): ";
903 map.is_null () ?
size_t (0) :
map->getLocalNumElements ();
906 "map->getLocalNumElements() = " <<
lclNumRows <<
".");
911 std::invalid_argument,
"Input Teuchos::ArrayView does not have enough "
912 "entries, given the input Map and number of vectors in the MultiVector."
913 " data.size() = " <<
data.size () <<
" < (LDA*(numVecs-1)) + "
945 typedef decltype (Kokkos::subview (
X_out, Kokkos::ALL (), 0))
947 typedef decltype (Kokkos::subview (
X_in, Kokkos::ALL (), 0))
958 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
961 const Teuchos::ArrayView<
const Teuchos::ArrayView<const Scalar> >&
ArrayOfPtrs,
968 const char tfecfFuncName[] =
"MultiVector(map,ArrayOfPtrs,numVecs): ";
972 map.is_null () ?
size_t (0) :
map->getLocalNumElements ();
975 std::runtime_error,
"Either numVecs (= " <<
numVecs <<
") < 1, or "
976 "ArrayOfPtrs.size() (= " <<
ArrayOfPtrs.size () <<
") != numVecs.");
981 std::invalid_argument,
"ArrayOfPtrs[" <<
j <<
"].size() = "
991 using array_layout =
typename decltype (
X_out)::array_layout;
995 Kokkos::MemoryUnmanaged>;
999 Teuchos::ArrayView<const IST>
X_j_av =
1000 Teuchos::av_reinterpret_cast<const IST> (
ArrayOfPtrs[
j]);
1008 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1011 return whichVectors_.empty ();
1014 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1019 if (this->getMap ().
is_null ()) {
1020 return static_cast<size_t> (0);
1022 return this->getMap ()->getLocalNumElements ();
1026 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1031 if (this->getMap ().
is_null ()) {
1032 return static_cast<size_t> (0);
1034 return this->getMap ()->getGlobalNumElements ();
1038 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1046 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1052 auto thisData = view_.getDualView().view_host().data();
1054 size_t thisSpan = view_.getDualView().view_host().span();
1060 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1069 const MV* src =
dynamic_cast<const MV*
> (&
sourceObj);
1070 if (src ==
nullptr) {
1080 return src->getNumVectors () == this->getNumVectors ();
1084 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1088 return this->getNumVectors ();
1091 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1096 const size_t numSameIDs,
1097 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>&
permuteToLIDs,
1098 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>&
permuteFromLIDs,
1102 using ::Tpetra::Details::Behavior;
1103 using ::Tpetra::Details::getDualViewCopyFromArrayView;
1104 using ::Tpetra::Details::ProfilingRegion;
1106 using KokkosRefactor::Details::permute_array_multi_column;
1107 using KokkosRefactor::Details::permute_array_multi_column_variable_stride;
1108 using Kokkos::Compat::create_const_view;
1114 const char longFuncNameHost[] =
"Tpetra::MultiVector::copyAndPermute[Host]";
1119 const bool verbose = Behavior::verbose ();
1120 std::unique_ptr<std::string>
prefix;
1122 auto map = this->getMap ();
1123 auto comm =
map.is_null () ? Teuchos::null :
map->getComm ();
1124 const int myRank = comm.is_null () ? -1 : comm->getRank ();
1125 std::ostringstream
os;
1126 os <<
"Proc " <<
myRank <<
": MV::copyAndPermute: ";
1127 prefix = std::unique_ptr<std::string> (
new std::string (
os.str ()));
1129 std::cerr <<
os.str ();
1134 std::logic_error,
"permuteToLIDs.extent(0) = "
1137 const size_t numCols = this->getNumVectors ();
1143 std::logic_error,
"Input MultiVector needs sync to both host "
1146 std::ostringstream
os;
1148 std::cerr <<
os.str ();
1152 std::ostringstream
os;
1154 std::cerr <<
os.str ();
1179 if (numSameIDs > 0) {
1180 const std::pair<size_t, size_t>
rows (0, numSameIDs);
1182 auto tgt_h = this->getLocalViewHost(Access::ReadWrite);
1185 for (
size_t j = 0;
j < numCols; ++
j) {
1186 const size_t tgtCol = isConstantStride () ?
j : whichVectors_[
j];
1195 Kokkos::RangePolicy<execution_space, size_t>;
1197 Tpetra::Details::AddAssignFunctor<
decltype(
tgt_j),
decltype(
src_j)>
1199 Kokkos::parallel_for(
rp,
aaf);
1210 auto tgt_d = this->getLocalViewDevice(Access::ReadWrite);
1213 for (
size_t j = 0;
j < numCols; ++
j) {
1214 const size_t tgtCol = isConstantStride () ?
j : whichVectors_[
j];
1223 Kokkos::RangePolicy<execution_space, size_t>;
1225 Tpetra::Details::AddAssignFunctor<
decltype(
tgt_j),
decltype(
src_j)>
1227 Kokkos::parallel_for(
rp,
aaf);
1253 std::ostringstream
os;
1255 std::cerr <<
os.str ();
1261 std::ostringstream
os;
1263 std::cerr <<
os.str ();
1269 ! this->isConstantStride () || !
sourceMV.isConstantStride ();
1272 std::ostringstream
os;
1275 std::cerr <<
os.str ();
1282 Kokkos::DualView<const size_t*, device_type>
srcWhichVecs;
1283 Kokkos::DualView<const size_t*, device_type>
tgtWhichVecs;
1285 if (this->whichVectors_.size () == 0) {
1286 Kokkos::DualView<size_t*, device_type>
tmpTgt (
"tgtWhichVecs", numCols);
1288 for (
size_t j = 0;
j < numCols; ++
j) {
1297 Teuchos::ArrayView<const size_t>
tgtWhichVecsT = this->whichVectors_ ();
1305 this->getNumVectors (),
1306 std::logic_error,
"tgtWhichVecs.extent(0) = " <<
1307 tgtWhichVecs.extent (0) <<
" != this->getNumVectors() = " <<
1308 this->getNumVectors () <<
".");
1310 if (
sourceMV.whichVectors_.size () == 0) {
1311 Kokkos::DualView<size_t*, device_type>
tmpSrc (
"srcWhichVecs", numCols);
1313 for (
size_t j = 0;
j < numCols; ++
j) {
1331 sourceMV.getNumVectors (), std::logic_error,
1333 <<
" != sourceMV.getNumVectors() = " <<
sourceMV.getNumVectors ()
1339 std::ostringstream
os;
1340 os << *
prefix <<
"Get permute LIDs on host" << std::endl;
1341 std::cerr <<
os.str ();
1343 auto tgt_h = this->getLocalViewHost(Access::ReadWrite);
1353 std::ostringstream
os;
1355 std::cerr <<
os.str ();
1365 using op_type = KokkosRefactor::Details::AddOp;
1366 permute_array_multi_column_variable_stride (
tgt_h,
src_h,
1374 using op_type = KokkosRefactor::Details::InsertOp;
1375 permute_array_multi_column_variable_stride (
tgt_h,
src_h,
1385 using op_type = KokkosRefactor::Details::AddOp;
1390 using op_type = KokkosRefactor::Details::InsertOp;
1398 std::ostringstream
os;
1400 std::cerr <<
os.str ();
1402 auto tgt_d = this->getLocalViewDevice(Access::ReadWrite);
1412 std::ostringstream
os;
1414 std::cerr <<
os.str ();
1422 using op_type = KokkosRefactor::Details::AddOp;
1431 using op_type = KokkosRefactor::Details::InsertOp;
1432 permute_array_multi_column_variable_stride (space,
tgt_d,
src_d,
1442 using op_type = KokkosRefactor::Details::AddOp;
1447 using op_type = KokkosRefactor::Details::InsertOp;
1455 std::ostringstream
os;
1457 std::cerr <<
os.str ();
1462template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1465 const Kokkos::DualView<const local_ordinal_type *, buffer_device_type>
1467 const Kokkos::DualView<const local_ordinal_type *, buffer_device_type>
1475 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1480 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>&
exportLIDs,
1481 Kokkos::DualView<impl_scalar_type*, buffer_device_type>& exports,
1482 Kokkos::DualView<size_t*, buffer_device_type> ,
1484 const execution_space &space)
1486 using ::Tpetra::Details::Behavior;
1487 using ::Tpetra::Details::ProfilingRegion;
1488 using ::Tpetra::Details::reallocDualViewIfNeeded;
1489 using Kokkos::Compat::create_const_view;
1490 using Kokkos::Compat::getKokkosViewDeepCopy;
1498 const char longFuncNameHost[] =
"Tpetra::MultiVector::packAndPrepare[Host]";
1516 std::unique_ptr<std::string>
prefix;
1518 auto map = this->getMap ();
1519 auto comm =
map.is_null () ? Teuchos::null :
map->getComm ();
1520 const int myRank = comm.is_null () ? -1 : comm->getRank ();
1521 std::ostringstream
os;
1522 os <<
"Proc " <<
myRank <<
": MV::packAndPrepare: ";
1523 prefix = std::unique_ptr<std::string> (
new std::string (
os.str ()));
1525 std::cerr <<
os.str ();
1529 const size_t numCols =
sourceMV.getNumVectors ();
1540 std::ostringstream
os;
1541 os << *
prefix <<
"No exports on this proc, DONE" << std::endl;
1542 std::cerr <<
os.str ();
1565 std::ostringstream
os;
1568 <<
", exports.extent(0): " << exports.extent (0)
1570 std::cerr <<
os.str ();
1578 std::logic_error,
"Input MultiVector needs sync to both host "
1581 std::ostringstream
os;
1583 std::cerr <<
os.str ();
1595 exports.clear_sync_state ();
1596 exports.modify_host ();
1604 exports.clear_sync_state ();
1605 exports.modify_device ();
1621 if (
sourceMV.isConstantStride ()) {
1622 using KokkosRefactor::Details::pack_array_single_column;
1624 std::ostringstream
os;
1625 os << *
prefix <<
"Pack numCols=1 const stride" <<
endl;
1626 std::cerr <<
os.str ();
1630 pack_array_single_column (exports.view_host (),
1638 pack_array_single_column (exports.view_device (),
1647 using KokkosRefactor::Details::pack_array_single_column;
1649 std::ostringstream
os;
1650 os << *
prefix <<
"Pack numCols=1 nonconst stride" <<
endl;
1651 std::cerr <<
os.str ();
1655 pack_array_single_column (exports.view_host (),
1663 pack_array_single_column (exports.view_device (),
1673 if (
sourceMV.isConstantStride ()) {
1674 using KokkosRefactor::Details::pack_array_multi_column;
1676 std::ostringstream
os;
1677 os << *
prefix <<
"Pack numCols=" << numCols <<
" const stride" <<
endl;
1678 std::cerr <<
os.str ();
1682 pack_array_multi_column (exports.view_host (),
1690 pack_array_multi_column (exports.view_device (),
1699 using KokkosRefactor::Details::pack_array_multi_column_variable_stride;
1701 std::ostringstream
os;
1702 os << *
prefix <<
"Pack numCols=" << numCols <<
" nonconst stride"
1709 using IST = impl_scalar_type;
1710 using DV = Kokkos::DualView<IST*, device_type>;
1711 using HES =
typename DV::t_host::execution_space;
1712 using DES =
typename DV::t_dev::execution_space;
1716 pack_array_multi_column_variable_stride
1717 (exports.view_host (),
1726 pack_array_multi_column_variable_stride
1727 (exports.view_device (),
1738 std::ostringstream
os;
1740 std::cerr <<
os.str ();
1746 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1751 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>&
exportLIDs,
1752 Kokkos::DualView<impl_scalar_type*, buffer_device_type>& exports,
1759 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1761 typename std::enable_if<std::is_same<typename Tpetra::Details::DefaultTypes::CommBufferMemorySpace<typename NO::execution_space>::type,
1762 typename NO::device_type::memory_space>::value,
1767 const std::string*
prefix,
1768 const bool areRemoteLIDsContiguous,
1777 std::ostringstream
os;
1778 os << *
prefix <<
"Realloc (if needed) imports_ from "
1779 << this->imports_.extent (0) <<
" to " <<
newSize << std::endl;
1780 std::cerr <<
os.str ();
1785 using IST = impl_scalar_type;
1786 using DV = Kokkos::DualView<IST*, Kokkos::LayoutLeft, buffer_device_type>;
1798 if ((std::is_same_v<typename dual_view_type::t_dev::device_type, typename dual_view_type::t_host::device_type> ||
1801 areRemoteLIDsContiguous &&
1803 (getNumVectors() == 1) &&
1807 reallocated = this->imports_.view_device().data() != view_.getDualView().view_device().data() +
offset;
1809 typedef std::pair<size_t, size_t> range_type;
1810 this->imports_ =
DV(view_.getDualView(),
1811 range_type (
offset, getLocalLength () ),
1815 std::ostringstream
os;
1816 os << *
prefix <<
"Aliased imports_ to MV.view_" << std::endl;
1817 std::cerr <<
os.str ();
1823 using ::Tpetra::Details::reallocDualViewIfNeeded;
1827 std::ostringstream
os;
1828 os << *
prefix <<
"Finished realloc'ing unaliased_imports_" << std::endl;
1829 std::cerr <<
os.str ();
1831 this->imports_ = this->unaliased_imports_;
1836 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1838 typename std::enable_if<!std::is_same<typename Tpetra::Details::DefaultTypes::CommBufferMemorySpace<typename NO::execution_space>::type,
1839 typename NO::device_type::memory_space>::value,
1844 const std::string*
prefix,
1845 const bool areRemoteLIDsContiguous,
1851 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1856 const std::string*
prefix,
1857 const bool areRemoteLIDsContiguous,
1863 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1867 return (this->imports_.view_device().data() +
this->imports_.view_device().extent(0) ==
1868 view_.getDualView().view_device().data() + view_.getDualView().view_device().extent(0));
1872 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1876 (
const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>&
importLIDs,
1877 Kokkos::DualView<impl_scalar_type*, buffer_device_type> imports,
1878 Kokkos::DualView<size_t*, buffer_device_type> ,
1881 const execution_space &space)
1883 using ::Tpetra::Details::Behavior;
1884 using ::Tpetra::Details::ProfilingRegion;
1885 using KokkosRefactor::Details::unpack_array_multi_column;
1886 using KokkosRefactor::Details::unpack_array_multi_column_variable_stride;
1887 using Kokkos::Compat::getKokkosViewDeepCopy;
1892 const char longFuncNameHost[] =
"Tpetra::MultiVector::unpackAndCombine[Host]";
1907 std::unique_ptr<std::string>
prefix;
1909 auto map = this->getMap ();
1910 auto comm =
map.is_null () ? Teuchos::null :
map->getComm ();
1911 const int myRank = comm.is_null () ? -1 : comm->getRank ();
1912 std::ostringstream
os;
1914 prefix = std::unique_ptr<std::string> (
new std::string (
os.str ()));
1916 std::cerr <<
os.str ();
1922 std::ostringstream
os;
1924 std::cerr <<
os.str ();
1930 if (importsAreAliased()) {
1932 std::ostringstream
os;
1933 os << *
prefix <<
"Skipping unpack, since imports_ is aliased to MV.view_. Done!" <<
endl;
1934 std::cerr <<
os.str ();
1940 const size_t numVecs = getNumVectors ();
1943 (
static_cast<size_t> (imports.extent (0)) !=
1946 "imports.extent(0) = " << imports.extent (0)
1947 <<
" != getNumVectors() * importLIDs.extent(0) = " <<
numVecs
1953 "constantNumPackets input argument must be nonzero.");
1956 (
static_cast<size_t> (
numVecs) !=
1958 std::runtime_error,
"constantNumPackets must equal numVecs.");
1967 if (this->imports_.need_sync_host()) this->imports_.sync_host();
1970 if (this->imports_.need_sync_device()) this->imports_.sync_device();
1974 std::ostringstream
os;
1977 std::cerr <<
os.str ();
1982 auto imports_d = imports.view_device ();
1988 if (! isConstantStride ()) {
1989 Kokkos::View<
const size_t*, Kokkos::HostSpace,
1990 Kokkos::MemoryUnmanaged>
whichVecsIn (whichVectors_.getRawPtr (),
2016 using dev_exec_space =
typename dual_view_type::t_dev::execution_space;
2017 using host_exec_space =
typename dual_view_type::t_host::execution_space;
2021 host_exec_space().concurrency () != 1 :
2025 std::ostringstream
os;
2027 std::cerr <<
os.str ();
2034 using op_type = KokkosRefactor::Details::InsertOp;
2035 if (isConstantStride ()) {
2037 auto X_h = this->getLocalViewHost(Access::ReadWrite);
2038 unpack_array_multi_column (host_exec_space (),
2046 auto X_d = this->getLocalViewDevice(Access::ReadWrite);
2047 unpack_array_multi_column (space,
2056 auto X_h = this->getLocalViewHost(Access::ReadWrite);
2057 unpack_array_multi_column_variable_stride (host_exec_space (),
2067 auto X_d = this->getLocalViewDevice(Access::ReadWrite);
2068 unpack_array_multi_column_variable_stride (space,
2080 using op_type = KokkosRefactor::Details::AddOp;
2081 if (isConstantStride ()) {
2083 auto X_h = this->getLocalViewHost(Access::ReadWrite);
2084 unpack_array_multi_column (host_exec_space (),
2091 auto X_d = this->getLocalViewDevice(Access::ReadWrite);
2092 unpack_array_multi_column (space,
2101 auto X_h = this->getLocalViewHost(Access::ReadWrite);
2102 unpack_array_multi_column_variable_stride (host_exec_space (),
2112 auto X_d = this->getLocalViewDevice(Access::ReadWrite);
2113 unpack_array_multi_column_variable_stride (space,
2125 using op_type = KokkosRefactor::Details::AbsMaxOp;
2126 if (isConstantStride ()) {
2128 auto X_h = this->getLocalViewHost(Access::ReadWrite);
2129 unpack_array_multi_column (host_exec_space (),
2136 auto X_d = this->getLocalViewDevice(Access::ReadWrite);
2137 unpack_array_multi_column (space,
2146 auto X_h = this->getLocalViewHost(Access::ReadWrite);
2147 unpack_array_multi_column_variable_stride (host_exec_space (),
2157 auto X_d = this->getLocalViewDevice(Access::ReadWrite);
2158 unpack_array_multi_column_variable_stride (space,
2171 (
true, std::logic_error,
"Invalid CombineMode");
2176 std::ostringstream
os;
2178 std::cerr <<
os.str ();
2183 std::ostringstream
os;
2185 std::cerr <<
os.str ();
2190 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2194 (
const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>&
importLIDs,
2195 Kokkos::DualView<impl_scalar_type*, buffer_device_type> imports,
2203 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2208 if (isConstantStride ()) {
2209 return static_cast<size_t> (view_.extent (1));
2211 return static_cast<size_t> (whichVectors_.size ());
2220 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
2223 using Teuchos::REDUCE_MAX;
2224 using Teuchos::REDUCE_SUM;
2225 using Teuchos::reduceAll;
2226 typedef typename RV::non_const_value_type dot_type;
2246 const int nv =
static_cast<int> (
numVecs);
2253 typename RV::non_const_type
lclDots (Kokkos::ViewAllocateWithoutInitializing (
"tmp"),
numVecs);
2268 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2272 const Kokkos::View<dot_type*, Kokkos::HostSpace>&
dots)
const
2274 using ::Tpetra::Details::Behavior;
2275 using Kokkos::subview;
2276 using Teuchos::Comm;
2277 using Teuchos::null;
2280 typedef Kokkos::View<dot_type*, Kokkos::HostSpace>
RV;
2281 typedef typename dual_view_type::t_dev_const
XMV;
2286 const size_t numVecs = this->getNumVectors ();
2290 const size_t lclNumRows = this->getLocalLength ();
2291 const size_t numDots =
static_cast<size_t> (
dots.extent (0));
2292 const bool debug = Behavior::debug ();
2295 const bool compat = this->getMap ()->isCompatible (* (
A.getMap ()));
2297 (!
compat, std::invalid_argument,
"'*this' MultiVector is not "
2298 "compatible with the input MultiVector A. We only test for this "
2310 lclNumRows !=
A.getLocalLength (), std::runtime_error,
2311 "MultiVectors do not have the same local length. "
2312 "this->getLocalLength() = " <<
lclNumRows <<
" != "
2313 "A.getLocalLength() = " <<
A.getLocalLength () <<
".");
2315 numVecs !=
A.getNumVectors (), std::runtime_error,
2316 "MultiVectors must have the same number of columns (vectors). "
2317 "this->getNumVectors() = " <<
numVecs <<
" != "
2318 "A.getNumVectors() = " <<
A.getNumVectors () <<
".");
2321 "The output array 'dots' must have the same number of entries as the "
2322 "number of columns (vectors) in *this and A. dots.extent(0) = " <<
2328 this->getMap ()->getComm ();
2330 auto thisView = this->getLocalViewDevice(Access::ReadOnly);
2331 auto A_view =
A.getLocalViewDevice(Access::ReadOnly);
2334 this->whichVectors_.getRawPtr (),
2335 A.whichVectors_.getRawPtr (),
2336 this->isConstantStride (),
A.isConstantStride ());
2351 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2356 using ::Tpetra::Details::ProfilingRegion;
2358 using dot_type =
typename MV::dot_type;
2359 ProfilingRegion
region (
"Tpetra::multiVectorSingleColumnDot");
2361 auto map =
x.getMap ();
2362 Teuchos::RCP<const Teuchos::Comm<int> > comm =
2363 map.is_null () ? Teuchos::null :
map->getComm ();
2364 if (comm.is_null ()) {
2365 return Kokkos::ArithTraits<dot_type>::zero ();
2372 const LO
lclNumRows =
static_cast<LO
> (std::min (
x.getLocalLength (),
2373 y.getLocalLength ()));
2375 dot_type lclDot = Kokkos::ArithTraits<dot_type>::zero ();
2376 dot_type
gblDot = Kokkos::ArithTraits<dot_type>::zero ();
2382 auto x_2d =
x.getLocalViewDevice(Access::ReadOnly);
2384 auto y_2d =
y.getLocalViewDevice(Access::ReadOnly);
2386 lclDot = KokkosBlas::dot (
x_1d,
y_1d);
2388 if (
x.isDistributed ()) {
2389 using Teuchos::outArg;
2390 using Teuchos::REDUCE_SUM;
2391 using Teuchos::reduceAll;
2404 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2408 const Teuchos::ArrayView<dot_type>&
dots)
const
2413 const size_t numVecs = this->getNumVectors ();
2414 const size_t lclNumRows = this->getLocalLength ();
2426 (
lclNumRows !=
A.getLocalLength (), std::runtime_error,
2427 "MultiVectors do not have the same local length. "
2428 "this->getLocalLength() = " <<
lclNumRows <<
" != "
2429 "A.getLocalLength() = " <<
A.getLocalLength () <<
".");
2431 (
numVecs !=
A.getNumVectors (), std::runtime_error,
2432 "MultiVectors must have the same number of columns (vectors). "
2433 "this->getNumVectors() = " <<
numVecs <<
" != "
2434 "A.getNumVectors() = " <<
A.getNumVectors () <<
".");
2437 "The output array 'dots' must have the same number of entries as the "
2438 "number of columns (vectors) in *this and A. dots.extent(0) = " <<
2441 if (
numVecs == 1 && this->isConstantStride () &&
A.isConstantStride ()) {
2446 this->dot (
A, Kokkos::View<dot_type*, Kokkos::HostSpace>(
dots.getRawPtr (),
numDots));
2450 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2453 norm2 (
const Teuchos::ArrayView<mag_type>&
norms)
const
2456 using ::Tpetra::Details::NORM_TWO;
2457 using ::Tpetra::Details::ProfilingRegion;
2458 ProfilingRegion
region (
"Tpetra::MV::norm2 (host output)");
2461 MV&
X =
const_cast<MV&
> (*this);
2465 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2468 norm2 (
const Kokkos::View<mag_type*, Kokkos::HostSpace>&
norms)
const
2475 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2478 norm1 (
const Teuchos::ArrayView<mag_type>&
norms)
const
2481 using ::Tpetra::Details::NORM_ONE;
2482 using ::Tpetra::Details::ProfilingRegion;
2483 ProfilingRegion
region (
"Tpetra::MV::norm1 (host output)");
2486 MV&
X =
const_cast<MV&
> (*this);
2490 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2493 norm1 (
const Kokkos::View<mag_type*, Kokkos::HostSpace>&
norms)
const
2499 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2502 normInf (
const Teuchos::ArrayView<mag_type>&
norms)
const
2505 using ::Tpetra::Details::NORM_INF;
2506 using ::Tpetra::Details::ProfilingRegion;
2507 ProfilingRegion
region (
"Tpetra::MV::normInf (host output)");
2510 MV&
X =
const_cast<MV&
> (*this);
2514 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2517 normInf (
const Kokkos::View<mag_type*, Kokkos::HostSpace>&
norms)
const
2523 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2526 meanValue (
const Teuchos::ArrayView<impl_scalar_type>&
means)
const
2530 using Kokkos::subview;
2531 using Teuchos::Comm;
2533 using Teuchos::reduceAll;
2534 using Teuchos::REDUCE_SUM;
2535 typedef Kokkos::ArithTraits<impl_scalar_type>
ATS;
2537 const size_t lclNumRows = this->getLocalLength ();
2538 const size_t numVecs = this->getNumVectors ();
2539 const size_t numMeans =
static_cast<size_t> (
means.size ());
2543 "Tpetra::MultiVector::meanValue: means.size() = " <<
numMeans
2544 <<
" != this->getNumVectors() = " <<
numVecs <<
".");
2554 typename local_view_type::HostMirror::array_layout,
2560 this->getMap ()->getComm ();
2566 auto X_lcl =
subview (getLocalViewHost(Access::ReadOnly),
2569 Kokkos::View<impl_scalar_type*, Kokkos::HostSpace>
lclSums (
"MV::meanValue tmp",
numVecs);
2570 if (isConstantStride ()) {
2575 const size_t col = whichVectors_[
j];
2583 if (! comm.is_null () &&
this->isDistributed ()) {
2594 auto X_lcl =
subview (this->getLocalViewDevice(Access::ReadOnly),
2598 Kokkos::View<impl_scalar_type*, Kokkos::HostSpace>
lclSums (
"MV::meanValue tmp",
numVecs);
2599 if (isConstantStride ()) {
2604 const size_t col = whichVectors_[
j];
2621 if (! comm.is_null () &&
this->isDistributed ()) {
2635 ATS::one () /
static_cast<mag_type> (this->getGlobalLength ());
2642 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2648 typedef Kokkos::ArithTraits<IST>
ATS;
2649 typedef Kokkos::Random_XorShift64_Pool<typename device_type::execution_space>
pool_type;
2652 const IST
max = Kokkos::rand<generator_type, IST>::max ();
2653 const IST
min = ATS::is_signed ? IST (-
max) : ATS::zero ();
2659 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2665 typedef Tpetra::Details::Static_Random_XorShift64_Pool<typename device_type::execution_space>
tpetra_pool_type;
2666 typedef Kokkos::Random_XorShift64_Pool<typename device_type::execution_space>
pool_type;
2669 if(!tpetra_pool_type::isSet())
2670 tpetra_pool_type::resetPool(this->getMap()->getComm()->getRank());
2673 const IST
max =
static_cast<IST
> (maxVal);
2674 const IST
min =
static_cast<IST
> (minVal);
2676 auto thisView = this->getLocalViewDevice(Access::OverwriteAll);
2678 if (isConstantStride ()) {
2682 const size_t numVecs = getNumVectors ();
2684 const size_t col = whichVectors_[
k];
2685 auto X_k = Kokkos::subview (
thisView, Kokkos::ALL (), col);
2691 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2696 using ::Tpetra::Details::ProfilingRegion;
2697 using ::Tpetra::Details::Blas::fill;
2698 using DES =
typename dual_view_type::t_dev::execution_space;
2699 using HES =
typename dual_view_type::t_host::execution_space;
2701 ProfilingRegion
region (
"Tpetra::MultiVector::putScalar");
2706 const LO
lclNumRows =
static_cast<LO
> (this->getLocalLength ());
2707 const LO
numVecs =
static_cast<LO
> (this->getNumVectors ());
2715 auto X = this->getLocalViewDevice(Access::OverwriteAll);
2716 if (this->isConstantStride ()) {
2721 this->whichVectors_.getRawPtr ());
2725 auto X = this->getLocalViewHost(Access::OverwriteAll);
2726 if (this->isConstantStride ()) {
2731 this->whichVectors_.getRawPtr ());
2737 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2742 using Teuchos::ArrayRCP;
2743 using Teuchos::Comm;
2754 ! this->isConstantStride (), std::logic_error,
2755 "Tpetra::MultiVector::replaceMap: This method does not currently work "
2756 "if the MultiVector is a column view of another MultiVector (that is, if "
2757 "isConstantStride() == false).");
2787 if (this->getMap ().
is_null ()) {
2793 newMap.is_null (), std::invalid_argument,
2794 "Tpetra::MultiVector::replaceMap: both current and new Maps are null. "
2795 "This probably means that the input Map is incorrect.");
2801 const size_t numCols = this->getNumVectors ();
2807 else if (
newMap.is_null ()) {
2810 const size_t newNumRows =
static_cast<size_t> (0);
2811 const size_t numCols = this->getNumVectors ();
2818 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2827 if (
theAlpha == Kokkos::ArithTraits<IST>::one ()) {
2831 const size_t numVecs = getNumVectors ();
2843 auto Y_lcl = Kokkos::subview (getLocalViewHost(Access::ReadWrite),
rowRng,
ALL ());
2844 if (isConstantStride ()) {
2849 const size_t Y_col = whichVectors_[
k];
2856 auto Y_lcl = Kokkos::subview (getLocalViewDevice(Access::ReadWrite),
rowRng,
ALL ());
2857 if (isConstantStride ()) {
2862 const size_t Y_col = isConstantStride () ?
k : whichVectors_[
k];
2871 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2874 scale (
const Teuchos::ArrayView<const Scalar>&
alphas)
2876 const size_t numVecs = this->getNumVectors ();
2880 "scale: alphas.size() = " <<
numAlphas <<
" != this->getNumVectors() = "
2884 using k_alphas_type = Kokkos::DualView<impl_scalar_type*, device_type>;
2892 this->scale (
k_alphas.view_device ());
2895 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2898 scale (
const Kokkos::View<const impl_scalar_type*, device_type>&
alphas)
2901 using Kokkos::subview;
2903 const size_t lclNumRows = this->getLocalLength ();
2904 const size_t numVecs = this->getNumVectors ();
2907 std::invalid_argument,
"Tpetra::MultiVector::scale(alphas): "
2908 "alphas.extent(0) = " <<
alphas.extent (0)
2909 <<
" != this->getNumVectors () = " <<
numVecs <<
".");
2930 if (isConstantStride ()) {
2935 const size_t Y_col = this->isConstantStride () ?
k :
2936 this->whichVectors_[
k];
2946 if (isConstantStride ()) {
2959 const size_t Y_col = this->isConstantStride () ?
k :
2960 this->whichVectors_[
k];
2968 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2975 using Kokkos::subview;
2979 const size_t numVecs = getNumVectors ();
2982 lclNumRows !=
A.getLocalLength (), std::invalid_argument,
2983 "this->getLocalLength() = " <<
lclNumRows <<
" != A.getLocalLength() = "
2984 <<
A.getLocalLength () <<
".");
2986 numVecs !=
A.getNumVectors (), std::invalid_argument,
2987 "this->getNumVectors() = " <<
numVecs <<
" != A.getNumVectors() = "
2988 <<
A.getNumVectors () <<
".");
2994 auto Y_lcl_orig = this->getLocalViewDevice(Access::ReadWrite);
2995 auto X_lcl_orig =
A.getLocalViewDevice(Access::ReadOnly);
2999 if (isConstantStride () &&
A.isConstantStride ()) {
3005 const size_t Y_col = this->isConstantStride () ?
k : this->whichVectors_[
k];
3006 const size_t X_col =
A.isConstantStride () ?
k :
A.whichVectors_[
k];
3017 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3025 getLocalLength () !=
A.getLocalLength (), std::runtime_error,
3026 "MultiVectors do not have the same local length. "
3027 "this->getLocalLength() = " << getLocalLength ()
3028 <<
" != A.getLocalLength() = " <<
A.getLocalLength () <<
".");
3030 A.getNumVectors () !=
this->getNumVectors (), std::runtime_error,
3031 ": MultiVectors do not have the same number of columns (vectors). "
3032 "this->getNumVectors() = " << getNumVectors ()
3033 <<
" != A.getNumVectors() = " <<
A.getNumVectors () <<
".");
3035 const size_t numVecs = getNumVectors ();
3037 auto this_view_dev = this->getLocalViewDevice(Access::ReadWrite);
3038 auto A_view_dev =
A.getLocalViewDevice(Access::ReadOnly);
3040 if (isConstantStride () &&
A.isConstantStride ()) {
3045 using Kokkos::subview;
3047 const size_t this_col = isConstantStride () ?
k : whichVectors_[
k];
3049 const size_t A_col = isConstantStride () ?
k :
A.whichVectors_[
k];
3056 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3064 getLocalLength () !=
A.getLocalLength (), std::runtime_error,
3065 ": MultiVectors do not have the same local length. "
3066 "this->getLocalLength() = " << getLocalLength ()
3067 <<
" != A.getLocalLength() = " <<
A.getLocalLength () <<
".");
3069 A.getNumVectors () !=
this->getNumVectors (), std::runtime_error,
3070 ": MultiVectors do not have the same number of columns (vectors). "
3071 "this->getNumVectors() = " << getNumVectors ()
3072 <<
" != A.getNumVectors() = " <<
A.getNumVectors () <<
".");
3073 const size_t numVecs = getNumVectors ();
3075 auto this_view_dev = this->getLocalViewDevice(Access::ReadWrite);
3076 auto A_view_dev =
A.getLocalViewDevice(Access::ReadOnly);
3078 if (isConstantStride () &&
A.isConstantStride ()) {
3083 using Kokkos::subview;
3086 const size_t this_col = isConstantStride () ?
k : whichVectors_[
k];
3088 const size_t A_col = isConstantStride () ?
k :
A.whichVectors_[
k];
3095 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3103 using Kokkos::subview;
3109 const size_t numVecs = getNumVectors ();
3113 lclNumRows !=
A.getLocalLength (), std::invalid_argument,
3114 "this->getLocalLength() = " <<
lclNumRows <<
" != A.getLocalLength() = "
3115 <<
A.getLocalLength () <<
".");
3117 numVecs !=
A.getNumVectors (), std::invalid_argument,
3118 "this->getNumVectors() = " <<
numVecs <<
" != A.getNumVectors() = "
3119 <<
A.getNumVectors () <<
".");
3127 auto Y_lcl_orig = this->getLocalViewDevice(Access::ReadWrite);
3129 auto X_lcl_orig =
A.getLocalViewDevice(Access::ReadOnly);
3133 if (isConstantStride () &&
A.isConstantStride ()) {
3139 const size_t Y_col = this->isConstantStride () ?
k : this->whichVectors_[
k];
3140 const size_t X_col =
A.isConstantStride () ?
k :
A.whichVectors_[
k];
3149 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3159 using Kokkos::subview;
3161 const char tfecfFuncName[] =
"update(alpha,A,beta,B,gamma): ";
3165 const size_t lclNumRows = this->getLocalLength ();
3166 const size_t numVecs = getNumVectors ();
3170 lclNumRows !=
A.getLocalLength (), std::invalid_argument,
3171 "The input MultiVector A has " <<
A.getLocalLength () <<
" local "
3172 "row(s), but this MultiVector has " <<
lclNumRows <<
" local "
3175 lclNumRows !=
B.getLocalLength (), std::invalid_argument,
3176 "The input MultiVector B has " <<
B.getLocalLength () <<
" local "
3177 "row(s), but this MultiVector has " <<
lclNumRows <<
" local "
3180 A.getNumVectors () !=
numVecs, std::invalid_argument,
3181 "The input MultiVector A has " <<
A.getNumVectors () <<
" column(s), "
3182 "but this MultiVector has " <<
numVecs <<
" column(s).");
3184 B.getNumVectors () !=
numVecs, std::invalid_argument,
3185 "The input MultiVector B has " <<
B.getNumVectors () <<
" column(s), "
3186 "but this MultiVector has " <<
numVecs <<
" column(s).");
3203 if (isConstantStride () &&
A.isConstantStride () &&
B.isConstantStride ()) {
3210 const size_t this_col = isConstantStride () ?
k : whichVectors_[
k];
3211 const size_t A_col =
A.isConstantStride () ?
k :
A.whichVectors_[
k];
3212 const size_t B_col =
B.isConstantStride () ?
k :
B.whichVectors_[
k];
3220 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3221 Teuchos::ArrayRCP<const Scalar>
3234 auto hostView = getLocalViewHost(Access::ReadOnly);
3235 const size_t col = isConstantStride () ?
j : whichVectors_[
j];
3238 Kokkos::Compat::persistingView (
hostView_j, 0, getLocalLength ());
3241 (
static_cast<size_t> (
hostView_j.extent (0)) <
3242 static_cast<size_t> (
dataAsArcp.size ()), std::logic_error,
3243 "hostView_j.extent(0) = " <<
hostView_j.extent (0)
3244 <<
" < dataAsArcp.size() = " <<
dataAsArcp.size () <<
". "
3245 "Please report this bug to the Tpetra developers.");
3247 return Teuchos::arcp_reinterpret_cast<const Scalar> (
dataAsArcp);
3250 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3251 Teuchos::ArrayRCP<Scalar>
3256 using Kokkos::subview;
3260 auto hostView = getLocalViewHost(Access::ReadWrite);
3261 const size_t col = isConstantStride () ?
j : whichVectors_[
j];
3264 Kokkos::Compat::persistingView (
hostView_j, 0, getLocalLength ());
3267 (
static_cast<size_t> (
hostView_j.extent (0)) <
3268 static_cast<size_t> (
dataAsArcp.size ()), std::logic_error,
3269 "hostView_j.extent(0) = " <<
hostView_j.extent (0)
3270 <<
" < dataAsArcp.size() = " <<
dataAsArcp.size () <<
". "
3271 "Please report this bug to the Tpetra developers.");
3273 return Teuchos::arcp_reinterpret_cast<Scalar> (
dataAsArcp);
3276 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3277 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
3279 subCopy (
const Teuchos::ArrayView<const size_t>&
cols)
const
3289 if (
cols[
j] !=
cols[
j-1] +
static_cast<size_t> (1)) {
3305 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3306 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
3314 RCP<MV> Y (
new MV (this->getMap (),
static_cast<size_t> (
colRng.size ()),
false));
3319 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3323 return view_.origExtent(0);
3326 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3330 return view_.origExtent(1);
3333 template <
class Scalar,
class LO,
class GO,
class Node>
3336 const Teuchos::RCP<const map_type>&
subMap,
3341 using Kokkos::subview;
3342 using Teuchos::outArg;
3345 using Teuchos::reduceAll;
3346 using Teuchos::REDUCE_MIN;
3349 const char prefix[] =
"Tpetra::MultiVector constructor (offsetView): ";
3350 const char suffix[] =
"Please report this bug to the Tpetra developers.";
3353 std::unique_ptr<std::ostringstream>
errStrm;
3360 const auto comm =
subMap->getComm ();
3362 const int myRank = comm->getRank ();
3365 const LO numCols =
static_cast<LO
> (
X.getNumVectors ());
3368 std::ostringstream
os;
3371 <<
", origLclNumRows: " <<
X.getOrigNumLocalRows ()
3372 <<
", numCols: " << numCols <<
"}, "
3374 std::cerr <<
os.str ();
3382 errStrm = std::unique_ptr<std::ostringstream> (
new std::ostringstream);
3383 *
errStrm <<
" Proc " <<
myRank <<
": subMap->getLocalNumElements() (="
3385 <<
") > X.getOrigNumLocalRows() (=" <<
X.getOrigNumLocalRows ()
3401 (
true, std::invalid_argument,
gblErrStrm.str ());
3405 using range_type = std::pair<LO, LO>;
3407 (
rowOffset,
static_cast<LO
> (
X.view_.origExtent (0)));
3418 if (
newView.extent (0) == 0 &&
3419 newView.extent (1) !=
X.view_.extent (1)) {
3433 if (
errStrm.get () ==
nullptr) {
3434 errStrm = std::unique_ptr<std::ostringstream> (
new std::ostringstream);
3437 ": subMap.getLocalNumElements(): " <<
newNumRows <<
3439 ", X.getNumVectors(): " << numCols <<
3447 "dimensions on one or more processes:" <<
endl;
3454 (
true, std::invalid_argument,
gblErrStrm.str ());
3459 std::ostringstream
os;
3461 std::cerr <<
os.str ();
3467 std::ostringstream
os;
3469 std::cerr <<
os.str ();
3473 template <
class Scalar,
class LO,
class GO,
class Node>
3482 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3483 Teuchos::RCP<const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
3486 const size_t offset)
const
3492 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3493 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
3502 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3503 Teuchos::RCP<const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
3505 subView (
const Teuchos::ArrayView<const size_t>&
cols)
const
3507 using Teuchos::Array;
3513 numViewCols < 1, std::runtime_error,
"Tpetra::MultiVector::subView"
3514 "(const Teuchos::ArrayView<const size_t>&): The input array cols must "
3515 "contain at least one entry, but cols.size() = " <<
cols.size ()
3522 if (
cols[
j] !=
cols[
j-1] +
static_cast<size_t> (1)) {
3537 if (isConstantStride ()) {
3538 return rcp (
new MV (this->getMap (), view_,
cols));
3545 return rcp (
new MV (this->getMap (), view_,
newcols ()));
3550 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3551 Teuchos::RCP<const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
3555 using ::Tpetra::Details::Behavior;
3557 using Kokkos::subview;
3558 using Teuchos::Array;
3564 const size_t lclNumRows = this->getLocalLength ();
3565 const size_t numVecs = this->getNumVectors ();
3570 static_cast<size_t> (
colRng.size ()) >
numVecs, std::runtime_error,
3571 "colRng.size() = " <<
colRng.size () <<
" > this->getNumVectors() = "
3575 (
colRng.lbound () <
static_cast<Teuchos::Ordinal
> (0) ||
3577 std::invalid_argument,
"Nonempty input range [" <<
colRng.lbound () <<
3578 "," <<
colRng.ubound () <<
"] exceeds the valid range of column indices "
3592 if (
colRng.size () == 0) {
3593 const std::pair<size_t, size_t>
cols (0, 0);
3599 if (isConstantStride ()) {
3600 const std::pair<size_t, size_t>
cols (
colRng.lbound (),
3606 if (
static_cast<size_t> (
colRng.size ()) ==
static_cast<size_t> (1)) {
3609 const std::pair<size_t, size_t> col (whichVectors_[0] +
colRng.lbound (),
3610 whichVectors_[0] +
colRng.ubound () + 1);
3616 whichVectors_.begin () +
colRng.ubound () + 1);
3622 const bool debug = Behavior::debug ();
3624 using Teuchos::Comm;
3625 using Teuchos::outArg;
3626 using Teuchos::REDUCE_MIN;
3627 using Teuchos::reduceAll;
3630 Teuchos::null : this->getMap ()->getComm ();
3631 if (! comm.is_null ()) {
3635 if (
X_ret.is_null ()) {
3640 (
lclSuccess != 1, std::logic_error,
"X_ret (the subview of this "
3641 "MultiVector; the return value of this method) is null on some MPI "
3642 "process in this MultiVector's communicator. This should never "
3643 "happen. Please report this bug to the Tpetra developers.");
3644 if (!
X_ret.is_null () &&
3645 X_ret->getNumVectors () !=
static_cast<size_t> (
colRng.size ())) {
3651 (
lclSuccess != 1, std::logic_error,
"X_ret->getNumVectors() != "
3652 "colRng.size(), on at least one MPI process in this MultiVector's "
3653 "communicator. This should never happen. "
3654 "Please report this bug to the Tpetra developers.");
3661 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3662 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
3667 return Teuchos::rcp_const_cast<MV> (this->subView (
cols));
3671 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3672 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
3677 return Teuchos::rcp_const_cast<MV> (this->subView (
colRng));
3681 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3687 using Kokkos::subview;
3688 typedef std::pair<size_t, size_t> range_type;
3689 const char tfecfFuncName[] =
"MultiVector(const MultiVector&, const size_t): ";
3691 const size_t numCols =
X.getNumVectors ();
3693 (
j >= numCols, std::invalid_argument,
"Input index j (== " <<
j
3694 <<
") exceeds valid column index range [0, " << numCols <<
" - 1].");
3695 const size_t jj =
X.isConstantStride () ?
3696 static_cast<size_t> (
j) :
3697 static_cast<size_t> (
X.whichVectors_[
j]);
3709 const size_t newSize =
X.imports_.extent (0) / numCols;
3718 const size_t newSize =
X.exports_.extent (0) / numCols;
3734 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3735 Teuchos::RCP<const Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
3740 return Teuchos::rcp (
new V (*
this,
j));
3744 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3745 Teuchos::RCP<Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
3750 return Teuchos::rcp (
new V (*
this,
j));
3754 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3757 get1dCopy (
const Teuchos::ArrayView<Scalar>&
A,
const size_t LDA)
const
3760 using input_view_type = Kokkos::View<IST**, Kokkos::LayoutLeft,
3762 Kokkos::MemoryUnmanaged>;
3765 const size_t numRows = this->getLocalLength ();
3766 const size_t numCols = this->getNumVectors ();
3770 "LDA = " <<
LDA <<
" < numRows = " <<
numRows <<
".");
3772 (
numRows >
size_t (0) && numCols >
size_t (0) &&
3773 size_t (
A.size ()) <
LDA * (numCols - 1) +
numRows,
3775 "A.size() = " <<
A.size () <<
", but its size must be at least "
3776 << (
LDA * (numCols - 1) +
numRows) <<
" to hold all the entries.");
3779 const std::pair<size_t, size_t>
colRange (0, numCols);
3781 input_view_type
A_view_orig (
reinterpret_cast<IST*
> (
A.getRawPtr ()),
3796 if (this->need_sync_host() && this->need_sync_device()) {
3799 throw std::runtime_error(
"Tpetra::MultiVector: A non-const view is alive outside and we cannot give a copy where host or device view can be modified outside");
3802 const bool useHostView = view_.host_view_use_count() >= view_.device_view_use_count();
3803 if (this->isConstantStride ()) {
3805 auto srcView_host = this->getLocalViewHost(Access::ReadOnly);
3809 auto srcView_device = this->getLocalViewDevice(Access::ReadOnly);
3815 for (
size_t j = 0;
j < numCols; ++
j) {
3816 const size_t srcCol = this->whichVectors_[
j];
3820 auto srcView_host = this->getLocalViewHost(Access::ReadOnly);
3825 auto srcView_device = this->getLocalViewDevice(Access::ReadOnly);
3836 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3843 const size_t numRows = this->getLocalLength ();
3844 const size_t numCols = this->getNumVectors ();
3847 static_cast<size_t> (
ArrayOfPtrs.size ()) != numCols,
3848 std::runtime_error,
"Input array of pointers must contain as many "
3849 "entries (arrays) as the MultiVector has columns. ArrayOfPtrs.size() = "
3850 <<
ArrayOfPtrs.size () <<
" != getNumVectors() = " << numCols <<
".");
3852 if (
numRows != 0 && numCols != 0) {
3854 for (
size_t j = 0;
j < numCols; ++
j) {
3857 dstLen <
numRows, std::invalid_argument,
"Array j = " <<
j <<
" of "
3858 "the input array of arrays is not long enough to fit all entries in "
3859 "that column of the MultiVector. ArrayOfPtrs[j].size() = " <<
dstLen
3860 <<
" < getLocalLength() = " <<
numRows <<
".");
3864 for (
size_t j = 0;
j < numCols; ++
j) {
3865 Teuchos::RCP<const V>
X_j = this->getVector (
j);
3873 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3874 Teuchos::ArrayRCP<const Scalar>
3878 if (getLocalLength () == 0 || getNumVectors () == 0) {
3879 return Teuchos::null;
3882 ! isConstantStride (), std::runtime_error,
"Tpetra::MultiVector::"
3883 "get1dView: This MultiVector does not have constant stride, so it is "
3884 "not possible to view its data as a single array. You may check "
3885 "whether a MultiVector has constant stride by calling "
3886 "isConstantStride().");
3890 auto X_lcl = getLocalViewHost(Access::ReadOnly);
3891 Teuchos::ArrayRCP<const impl_scalar_type>
dataAsArcp =
3892 Kokkos::Compat::persistingView (
X_lcl);
3893 return Teuchos::arcp_reinterpret_cast<const Scalar> (
dataAsArcp);
3897 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3898 Teuchos::ArrayRCP<Scalar>
3902 if (this->getLocalLength () == 0 || this->getNumVectors () == 0) {
3903 return Teuchos::null;
3907 (! isConstantStride (), std::runtime_error,
"Tpetra::MultiVector::"
3908 "get1dViewNonConst: This MultiVector does not have constant stride, "
3909 "so it is not possible to view its data as a single array. You may "
3910 "check whether a MultiVector has constant stride by calling "
3911 "isConstantStride().");
3912 auto X_lcl = getLocalViewHost(Access::ReadWrite);
3913 Teuchos::ArrayRCP<impl_scalar_type>
dataAsArcp =
3914 Kokkos::Compat::persistingView (
X_lcl);
3915 return Teuchos::arcp_reinterpret_cast<Scalar> (
dataAsArcp);
3919 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3920 Teuchos::ArrayRCP<Teuchos::ArrayRCP<Scalar> >
3924 auto X_lcl = getLocalViewHost(Access::ReadWrite);
3930 const size_t myNumRows = this->getLocalLength ();
3931 const size_t numCols = this->getNumVectors ();
3934 Teuchos::ArrayRCP<Teuchos::ArrayRCP<Scalar> >
views (numCols);
3935 for (
size_t j = 0;
j < numCols; ++
j) {
3936 const size_t col = this->isConstantStride () ?
j : this->whichVectors_[
j];
3939 Kokkos::Compat::persistingView (
X_lcl_j);
3945 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3950 return view_.getHostView(
s);
3953 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3958 return view_.getHostView(
s);
3961 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3966 return view_.getHostView(
s);
3969 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3974 return view_.getDeviceView(
s);
3977 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3982 return view_.getDeviceView(
s);
3985 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3990 return view_.getDeviceView(
s);
3993 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4000 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4001 Teuchos::ArrayRCP<Teuchos::ArrayRCP<const Scalar> >
4008 auto X_lcl = getLocalViewHost(Access::ReadOnly);
4014 const size_t myNumRows = this->getLocalLength ();
4015 const size_t numCols = this->getNumVectors ();
4018 Teuchos::ArrayRCP<Teuchos::ArrayRCP<const Scalar> >
views (numCols);
4019 for (
size_t j = 0;
j < numCols; ++
j) {
4020 const size_t col = this->isConstantStride () ?
j : this->whichVectors_[
j];
4022 Teuchos::ArrayRCP<const impl_scalar_type>
X_lcl_j_arcp =
4023 Kokkos::Compat::persistingView (
X_lcl_j);
4029 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4039 using ::Tpetra::Details::ProfilingRegion;
4040 using Teuchos::CONJ_TRANS;
4041 using Teuchos::NO_TRANS;
4042 using Teuchos::TRANS;
4045 using Teuchos::rcpFromRef;
4047 using ATS = Kokkos::ArithTraits<impl_scalar_type>;
4049 using STS = Teuchos::ScalarTraits<Scalar>;
4052 ProfilingRegion
region (
"Tpetra::MV::multiply");
4084 const bool C_is_local = ! this->isDistributed ();
4094 auto myMap = this->getMap ();
4095 if (!
myMap.is_null () && !
myMap->getComm ().is_null ()) {
4096 using Teuchos::REDUCE_MIN;
4097 using Teuchos::reduceAll;
4098 using Teuchos::outArg;
4100 auto comm =
myMap->getComm ();
4113 const int myRank = comm->getRank ();
4115 if (this->getLocalLength () !=
A_nrows) {
4117 << this->getLocalLength () <<
" != A_nrows=" <<
A_nrows
4118 <<
"." << std::endl;
4120 if (this->getNumVectors () !=
B_ncols) {
4122 << this->getNumVectors () <<
" != B_ncols=" <<
B_ncols
4123 <<
"." << std::endl;
4128 <<
"." << std::endl;
4135 std::ostringstream
os;
4139 (
true, std::runtime_error,
"Inconsistent local dimensions on at "
4140 "least one process in this object's communicator." << std::endl
4142 <<
"C(" << (
C_is_local ?
"local" :
"distr") <<
") = "
4144 << (
transA == Teuchos::TRANS ?
"^T" :
4145 (
transA == Teuchos::CONJ_TRANS ?
"^H" :
""))
4146 <<
"(" << (
A_is_local ?
"local" :
"distr") <<
") * "
4148 << (
transA == Teuchos::TRANS ?
"^T" :
4149 (
transA == Teuchos::CONJ_TRANS ?
"^H" :
""))
4150 <<
"(" << (
B_is_local ?
"local" :
"distr") <<
")." << std::endl
4151 <<
"Global dimensions: C(" << this->getGlobalLength () <<
", "
4152 << this->getNumVectors () <<
"), A(" <<
A.getGlobalLength ()
4153 <<
", " <<
A.getNumVectors () <<
"), B(" <<
B.getGlobalLength ()
4154 <<
", " <<
B.getNumVectors () <<
")." << std::endl
4173 "Multiplication of op(A) and op(B) into *this is not a "
4174 "supported use case.");
4182 const int myRank = this->getMap ()->getComm ()->getRank ();
4193 if (! isConstantStride ()) {
4194 C_tmp =
rcp (
new MV (*
this, Teuchos::Copy));
4200 if (!
A.isConstantStride ()) {
4201 A_tmp =
rcp (
new MV (
A, Teuchos::Copy));
4207 if (!
B.isConstantStride ()) {
4208 B_tmp =
rcp (
new MV (
B, Teuchos::Copy));
4214 (!
C_tmp->isConstantStride () || !
B_tmp->isConstantStride () ||
4215 !
A_tmp->isConstantStride (), std::logic_error,
4216 "Failed to make temporary constant-stride copies of MultiVectors.");
4221 auto A_lcl =
A_tmp->getLocalViewDevice(Access::ReadOnly);
4222 auto A_sub = Kokkos::subview (A_lcl,
4229 auto B_lcl =
B_tmp->getLocalViewDevice(Access::ReadOnly);
4230 auto B_sub = Kokkos::subview (B_lcl,
4237 auto C_lcl =
C_tmp->getLocalViewDevice(Access::ReadWrite);
4242 (
transA == Teuchos::TRANS ?
'T' :
'C'));
4244 (
transB == Teuchos::TRANS ?
'T' :
'C'));
4247 ProfilingRegion
regionGemm (
"Tpetra::MV::multiply-call-gemm");
4253 if (! isConstantStride ()) {
4258 A_tmp = Teuchos::null;
4259 B_tmp = Teuchos::null;
4267 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4276 using Kokkos::subview;
4279 const size_t lclNumRows = this->getLocalLength ();
4280 const size_t numVecs = this->getNumVectors ();
4284 std::runtime_error,
"MultiVectors do not have the same local length.");
4286 numVecs !=
B.getNumVectors (), std::runtime_error,
"this->getNumVectors"
4287 "() = " <<
numVecs <<
" != B.getNumVectors() = " <<
B.getNumVectors ()
4290 auto this_view = this->getLocalViewDevice(Access::ReadWrite);
4291 auto A_view =
A.getLocalViewDevice(Access::ReadOnly);
4292 auto B_view =
B.getLocalViewDevice(Access::ReadOnly);
4294 if (isConstantStride () &&
B.isConstantStride ()) {
4308 const size_t C_col = isConstantStride () ?
j : whichVectors_[
j];
4309 const size_t B_col =
B.isConstantStride () ?
j :
B.whichVectors_[
j];
4319 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4324 using ::Tpetra::Details::allReduceView;
4325 using ::Tpetra::Details::ProfilingRegion;
4326 ProfilingRegion
region (
"Tpetra::MV::reduce");
4328 const auto map = this->getMap ();
4329 if (
map.get () ==
nullptr) {
4332 const auto comm =
map->getComm ();
4333 if (comm.get () ==
nullptr) {
4344 Kokkos::fence(
"MultiVector::reduce");
4345 auto X_lcl = this->getLocalViewDevice(Access::ReadWrite);
4349 auto X_lcl = this->getLocalViewHost(Access::ReadWrite);
4354 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4367 "Tpetra::MultiVector::replaceLocalValue: row index " <<
lclRow
4368 <<
" is invalid. The range of valid row indices on this process "
4369 << this->getMap()->getComm()->getRank() <<
" is [" <<
minLocalIndex
4372 vectorIndexOutOfRange(col),
4374 "Tpetra::MultiVector::replaceLocalValue: vector index " << col
4375 <<
" of the multivector is invalid.");
4378 auto view = this->getLocalViewHost(Access::ReadWrite);
4379 const size_t colInd = isConstantStride () ? col : whichVectors_[col];
4384 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4398 "Tpetra::MultiVector::sumIntoLocalValue: row index " <<
lclRow
4399 <<
" is invalid. The range of valid row indices on this process "
4400 << this->getMap()->getComm()->getRank() <<
" is [" <<
minLocalIndex
4403 vectorIndexOutOfRange(col),
4405 "Tpetra::MultiVector::sumIntoLocalValue: vector index " << col
4406 <<
" of the multivector is invalid.");
4409 const size_t colInd = isConstantStride () ? col : whichVectors_[col];
4411 auto view = this->getLocalViewHost(Access::ReadWrite);
4421 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4435 (
lclRow == Teuchos::OrdinalTraits<LocalOrdinal>::invalid (),
4437 "Global row index " <<
gblRow <<
" is not present on this process "
4438 << this->getMap ()->getComm ()->getRank () <<
".");
4440 (this->vectorIndexOutOfRange (col), std::runtime_error,
4441 "Vector index " << col <<
" of the MultiVector is invalid.");
4447 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4461 lclRow == Teuchos::OrdinalTraits<LocalOrdinal>::invalid (),
4463 "Tpetra::MultiVector::sumIntoGlobalValue: Global row index " <<
globalRow
4464 <<
" is not present on this process "
4465 << this->getMap ()->getComm ()->getRank () <<
".");
4467 vectorIndexOutOfRange(col),
4469 "Tpetra::MultiVector::sumIntoGlobalValue: Vector index " << col
4470 <<
" of the multivector is invalid.");
4473 this->sumIntoLocalValue (
lclRow, col, value, atomic);
4476 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4478 Teuchos::ArrayRCP<T>
4484 typename dual_view_type::array_layout,
4486 const size_t col = isConstantStride () ?
j : whichVectors_[
j];
4488 Kokkos::subview (view_, Kokkos::ALL (), col);
4489 return Kokkos::Compat::persistingView (
X_col.view_device());
4492 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4496 return view_.need_sync_host ();
4499 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4503 return view_.need_sync_device ();
4506 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4511 using Teuchos::TypeNameTraits;
4513 std::ostringstream
out;
4518 <<
", Node" << Node::name ()
4523 out <<
", numRows: " << this->getGlobalLength ();
4525 out <<
", numCols: " << this->getNumVectors ()
4526 <<
", isConstantStride: " << this->isConstantStride ();
4528 if (this->isConstantStride ()) {
4529 out <<
", columnStride: " << this->getStride ();
4536 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4541 return this->descriptionImpl (
"Tpetra::MultiVector");
4546 template<
typename ViewType>
4547 void print_vector(Teuchos::FancyOStream &
out,
const char*
prefix,
const ViewType&
v)
4550 static_assert(Kokkos::SpaceAccessibility<Kokkos::HostSpace, typename ViewType::memory_space>::accessible,
4551 "Tpetra::MultiVector::localDescribeToString: Details::print_vector should be given a host-accessible view.");
4552 static_assert(ViewType::rank == 2,
4553 "Tpetra::MultiVector::localDescribeToString: Details::print_vector should be given a rank-2 view.");
4556 out <<
"Values("<<
prefix<<
"): " << std::endl
4558 const size_t numRows =
v.extent(0);
4559 const size_t numCols =
v.extent(1);
4570 for (
size_t j = 0;
j < numCols; ++
j) {
4572 if (
j + 1 < numCols) {
4585 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4593 if (
vl <= Teuchos::VERB_LOW) {
4594 return std::string ();
4596 auto map = this->getMap ();
4597 if (
map.is_null ()) {
4598 return std::string ();
4600 auto outStringP = Teuchos::rcp (
new std::ostringstream ());
4602 Teuchos::FancyOStream&
out = *
outp;
4603 auto comm =
map->getComm ();
4604 const int myRank = comm->getRank ();
4605 const int numProcs = comm->getSize ();
4611 const LO
lclNumRows =
static_cast<LO
> (this->getLocalLength ());
4614 if (
vl > Teuchos::VERB_MEDIUM) {
4617 if (this->getNumVectors () !=
static_cast<size_t> (1)) {
4618 out <<
"isConstantStride: " << this->isConstantStride () <<
endl;
4620 if (this->isConstantStride ()) {
4621 out <<
"Column stride: " << this->getStride () <<
endl;
4632 auto X_dev = view_.getDeviceCopy();
4633 auto X_host = view_.getHostCopy();
4637 Details::print_vector(
out,
"unified",
X_host);
4640 Details::print_vector(
out,
"host",
X_host);
4641 Details::print_vector(
out,
"dev",
X_dev);
4649 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4654 const Teuchos::EVerbosityLevel
verbLevel)
const
4656 using Teuchos::TypeNameTraits;
4657 using Teuchos::VERB_DEFAULT;
4658 using Teuchos::VERB_NONE;
4659 using Teuchos::VERB_LOW;
4661 const Teuchos::EVerbosityLevel
vl =
4671 auto map = this->getMap ();
4672 if (
map.is_null ()) {
4675 auto comm =
map->getComm ();
4676 if (comm.is_null ()) {
4680 const int myRank = comm->getRank ();
4689 Teuchos::RCP<Teuchos::OSTab>
tab0,
tab1;
4693 tab0 = Teuchos::rcp (
new Teuchos::OSTab (
out));
4695 tab1 = Teuchos::rcp (
new Teuchos::OSTab (
out));
4697 out <<
"Template parameters:" <<
endl;
4702 <<
"Node: " << Node::name () <<
endl;
4707 out <<
"Global number of rows: " << this->getGlobalLength () <<
endl;
4709 out <<
"Number of columns: " << this->getNumVectors () <<
endl;
4717 const std::string
lclStr = this->localDescribeToString (
vl);
4722 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4726 const Teuchos::EVerbosityLevel
verbLevel)
const
4728 this->describeImpl (
out,
"Tpetra::MultiVector",
verbLevel);
4731 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4739 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4744 using ::Tpetra::Details::localDeepCopy;
4745 const char prefix[] =
"Tpetra::MultiVector::assign: ";
4748 (this->getGlobalLength () != src.getGlobalLength () ||
4749 this->getNumVectors () != src.getNumVectors (), std::invalid_argument,
4750 prefix <<
"Global dimensions of the two Tpetra::MultiVector "
4751 "objects do not match. src has dimensions [" << src.getGlobalLength ()
4752 <<
"," << src.getNumVectors () <<
"], and *this has dimensions ["
4753 <<
this->getGlobalLength () <<
"," <<
this->getNumVectors () <<
"].");
4756 (this->getLocalLength () != src.getLocalLength (), std::invalid_argument,
4757 prefix <<
"The local row counts of the two Tpetra::MultiVector "
4758 "objects do not match. src has " << src.getLocalLength () <<
" row(s) "
4759 <<
" and *this has " <<
this->getLocalLength () <<
" row(s).");
4775 localDeepCopy (this->getLocalViewHost(Access::ReadWrite),
4776 src.getLocalViewHost(Access::ReadOnly),
4777 this->isConstantStride (),
4778 src.isConstantStride (),
4779 this->whichVectors_ (),
4780 src.whichVectors_ ());
4783 localDeepCopy (this->getLocalViewDevice(Access::ReadWrite),
4784 src.getLocalViewDevice(Access::ReadOnly),
4785 this->isConstantStride (),
4786 src.isConstantStride (),
4787 this->whichVectors_ (),
4788 src.whichVectors_ ());
4792 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4794 Teuchos::RCP<MultiVector<T, LocalOrdinal, GlobalOrdinal, Node> >
4801 this->getNumVectors(),
4807 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4812 using ::Tpetra::Details::PackTraits;
4814 const size_t l1 = this->getLocalLength();
4815 const size_t l2 =
vec.getLocalLength();
4816 if ((
l1!=
l2) || (this->getNumVectors() !=
vec.getNumVectors())) {
4823 template <
class ST,
class LO,
class GO,
class NT>
4826 std::swap(
mv.map_,
this->map_);
4827 std::swap(
mv.view_,
this->view_);
4828 std::swap(
mv.whichVectors_,
this->whichVectors_);
4831#ifdef HAVE_TPETRACORE_TEUCHOSNUMERICS
4832 template <
class ST,
class LO,
class GO,
class NT>
4835 const Teuchos::SerialDenseMatrix<int, ST>& src)
4837 using ::Tpetra::Details::localDeepCopy;
4839 using IST =
typename MV::impl_scalar_type;
4840 using input_view_type =
4841 Kokkos::View<
const IST**, Kokkos::LayoutLeft,
4842 Kokkos::HostSpace, Kokkos::MemoryUnmanaged>;
4843 using pair_type = std::pair<LO, LO>;
4845 const LO
numRows =
static_cast<LO
> (src.numRows ());
4846 const LO numCols =
static_cast<LO
> (src.numCols ());
4849 (
numRows !=
static_cast<LO
> (dst.getLocalLength ()) ||
4850 numCols !=
static_cast<LO
> (dst.getNumVectors ()),
4851 std::invalid_argument,
"Tpetra::deep_copy: On Process "
4852 << dst.getMap ()->getComm ()->getRank () <<
", dst is "
4853 << dst.getLocalLength () <<
" x " << dst.getNumVectors ()
4854 <<
", but src is " <<
numRows <<
" x " << numCols <<
".");
4856 const IST*
src_raw =
reinterpret_cast<const IST*
> (src.values ());
4863 localDeepCopy (dst.getLocalViewHost(Access::ReadWrite),
4865 dst.isConstantStride (),
4867 getMultiVectorWhichVectors (dst),
4871 template <
class ST,
class LO,
class GO,
class NT>
4873 deep_copy (Teuchos::SerialDenseMatrix<int, ST>& dst,
4876 using ::Tpetra::Details::localDeepCopy;
4878 using IST =
typename MV::impl_scalar_type;
4879 using output_view_type =
4880 Kokkos::View<IST**, Kokkos::LayoutLeft,
4881 Kokkos::HostSpace, Kokkos::MemoryUnmanaged>;
4882 using pair_type = std::pair<LO, LO>;
4884 const LO
numRows =
static_cast<LO
> (dst.numRows ());
4885 const LO numCols =
static_cast<LO
> (dst.numCols ());
4890 std::invalid_argument,
"Tpetra::deep_copy: On Process "
4891 << src.
getMap ()->getComm ()->getRank () <<
", src is "
4893 <<
", but dst is " <<
numRows <<
" x " << numCols <<
".");
4895 IST*
dst_raw =
reinterpret_cast<IST*
> (dst.values ());
4909 getMultiVectorWhichVectors (src));
4913 template <
class Scalar,
class LO,
class GO,
class NT>
4914 Teuchos::RCP<MultiVector<Scalar, LO, GO, NT> >
4922 template <
class ST,
class LO,
class GO,
class NT>
4927 MV
cpy (src.getMap (), src.getNumVectors (),
false);
4940#ifdef HAVE_TPETRACORE_TEUCHOSNUMERICS
4941# define TPETRA_MULTIVECTOR_INSTANT(SCALAR,LO,GO,NODE) \
4942 template class MultiVector< SCALAR , LO , GO , NODE >; \
4943 template MultiVector< SCALAR , LO , GO , NODE > createCopy( const MultiVector< SCALAR , LO , GO , NODE >& src); \
4944 template Teuchos::RCP<MultiVector< SCALAR , LO , GO , NODE > > createMultiVector (const Teuchos::RCP<const Map<LO, GO, NODE> >& map, size_t numVectors); \
4945 template void deep_copy (MultiVector<SCALAR, LO, GO, NODE>& dst, const Teuchos::SerialDenseMatrix<int, SCALAR>& src); \
4946 template void deep_copy (Teuchos::SerialDenseMatrix<int, SCALAR>& dst, const MultiVector<SCALAR, LO, GO, NODE>& src);
4949# define TPETRA_MULTIVECTOR_INSTANT(SCALAR,LO,GO,NODE) \
4950 template class MultiVector< SCALAR , LO , GO , NODE >; \
4951 template MultiVector< SCALAR , LO , GO , NODE > createCopy( const MultiVector< SCALAR , LO , GO , NODE >& src);
4956#define TPETRA_MULTIVECTOR_CONVERT_INSTANT(SO,SI,LO,GO,NODE) \
4958 template Teuchos::RCP< MultiVector< SO , LO , GO , NODE > > \
4959 MultiVector< SI , LO , GO , NODE >::convert< SO > () const;
Functions for initializing and finalizing Tpetra.
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.
Declaration and generic definition of traits class that tells Tpetra::CrsMatrix how to pack and unpac...
Declaration of Tpetra::Details::Profiling, a scope guard for Kokkos Profiling.
All-reduce a 1-D or 2-D Kokkos::View.
Declaration of functions for checking whether a given pointer is accessible from a given Kokkos execu...
Declaration and definition of Tpetra::Details::Blas::fill, an implementation detail of Tpetra::MultiV...
Declaration of a function that prints strings from each process.
Declaration of Tpetra::Details::isInterComm.
Declaration and definition of Tpetra::Details::lclDot, an implementation detail of Tpetra::MultiVecto...
Declaration and definition of Tpetra::Details::normImpl, which is an implementation detail of Tpetra:...
Declaration and definition of Tpetra::Details::reallocDualViewIfNeeded, an implementation detail of T...
Stand-alone utility functions and macros.
Struct that holds views of the contents of a CrsMatrix.
static bool assumeMpiIsGPUAware()
Whether to assume that MPI is CUDA aware.
static bool debug()
Whether Tpetra is in debug mode.
static bool verbose()
Whether Tpetra is in verbose mode.
static size_t multivectorKernelLocationThreshold()
the threshold for transitioning from device to host
virtual bool reallocImportsIfNeeded(const size_t newSize, const bool verbose, const std::string *prefix, const bool remoteLIDsContiguous=false, const CombineMode CM=INSERT)
Reallocate imports_ if needed.
Kokkos::DualView< size_t *, buffer_device_type > numImportPacketsPerLID_
Number of packets to receive for each receive operation.
Kokkos::DualView< packet_type *, buffer_device_type > exports_
Buffer from which packed data are exported (sent to other processes).
Kokkos::DualView< packet_type *, buffer_device_type > imports_
Buffer into which packed data are imported (received from other processes).
Kokkos::DualView< size_t *, buffer_device_type > numExportPacketsPerLID_
Number of packets to send for each send operation.
virtual Teuchos::RCP< const map_type > getMap() const
The Map describing the parallel distribution of this object.
A parallel distribution of indices over processes.
One or more distributed dense vectors.
void reciprocal(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A)
Put element-wise reciprocal values of input Multi-vector in target, this(i,j) = 1/A(i,...
void normInf(const Kokkos::View< mag_type *, Kokkos::HostSpace > &norms) const
Compute the infinity-norm of each vector (column), storing the result in a host View.
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.
size_t getStride() const
Stride between columns in the multivector.
MultiVector< ST, LO, GO, NT > createCopy(const MultiVector< ST, LO, GO, NT > &src)
Return a deep copy of the given MultiVector.
virtual bool reallocImportsIfNeeded(const size_t newSize, const bool verbose, const std::string *prefix, const bool areRemoteLIDsContiguous=false, const CombineMode CM=INSERT) override
Reallocate imports_ if needed.
void reduce()
Sum values of a locally replicated multivector across all processes.
virtual bool checkSizes(const SrcDistObject &sourceObj) override
Whether data redistribution between sourceObj and this object is legal.
void randomize()
Set all values in the multivector to pseudorandom numbers.
typename map_type::local_ordinal_type local_ordinal_type
The type of local indices that this class uses.
void scale(const Scalar &alpha)
Scale in place: this = alpha*this.
Teuchos::RCP< const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > subView(const Teuchos::Range1D &colRng) const
Return a const MultiVector with const views of selected columns.
void dot(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const Teuchos::ArrayView< dot_type > &dots) const
Compute the dot product of each corresponding pair of vectors (columns) in A and B.
void describeImpl(Teuchos::FancyOStream &out, const std::string &className, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Implementation of describe() for this class, and its subclass Vector.
Teuchos::RCP< const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > offsetView(const Teuchos::RCP< const map_type > &subMap, const size_t offset) const
Return a const view of a subset of rows.
virtual void removeEmptyProcessesInPlace(const Teuchos::RCP< const map_type > &newMap) override
Remove processes owning zero rows from the Map and their communicator.
Teuchos::ArrayRCP< Scalar > get1dViewNonConst()
Nonconst persisting (1-D) view of this multivector's local values.
void assign(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &src)
Copy the contents of src into *this (deep copy).
Teuchos::RCP< Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getVectorNonConst(const size_t j)
Return a Vector which is a nonconst view of column j.
void meanValue(const Teuchos::ArrayView< impl_scalar_type > &means) const
Compute mean (average) value of each column.
std::string descriptionImpl(const std::string &className) const
Implementation of description() for this class, and its subclass Vector.
void multiply(Teuchos::ETransp transA, Teuchos::ETransp transB, const Scalar &alpha, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &B, const Scalar &beta)
Matrix-matrix multiplication: this = beta*this + alpha*op(A)*op(B).
bool need_sync_device() const
Whether this MultiVector needs synchronization to the device.
wrapped_dual_view_type view_
The Kokkos::DualView containing the MultiVector's data.
void replaceLocalValue(const LocalOrdinal lclRow, const size_t col, const impl_scalar_type &value)
Replace value in host memory, using local (row) index.
void swap(MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &mv)
Swap contents of mv with contents of *this.
size_t getLocalLength() const
Local number of rows on the calling process.
Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > subCopy(const Teuchos::Range1D &colRng) const
Return a MultiVector with copies of selected columns.
typename Kokkos::Details::InnerProductSpaceTraits< impl_scalar_type >::dot_type dot_type
Type of an inner ("dot") product result.
Teuchos::ArrayRCP< const Scalar > getData(size_t j) const
Const view of the local values in a particular vector of this multivector.
bool need_sync_host() const
Whether this MultiVector needs synchronization to the host.
Teuchos::RCP< const Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getVector(const size_t j) const
Return a Vector which is a const view of column j.
virtual void copyAndPermute(const SrcDistObject &sourceObj, const size_t numSameIDs, const Kokkos::DualView< const local_ordinal_type *, buffer_device_type > &permuteToLIDs, const Kokkos::DualView< const local_ordinal_type *, buffer_device_type > &permuteFromLIDs, const CombineMode CM, const execution_space &space) override
Same as copyAndPermute, but do operations in space.
void norm2(const Kokkos::View< mag_type *, Kokkos::HostSpace > &norms) const
Compute the two-norm of each vector (column), storing the result in a host View.
global_size_t getGlobalLength() const
Global number of rows in the multivector.
Teuchos::ArrayRCP< const Scalar > get1dView() const
Const persisting (1-D) view of this multivector's local values.
Teuchos::ArrayRCP< T > getSubArrayRCP(Teuchos::ArrayRCP< T > arr, size_t j) const
Persisting view of j-th column in the given ArrayRCP.
void replaceGlobalValue(const GlobalOrdinal gblRow, const size_t col, const impl_scalar_type &value)
Replace value in host memory, using global row index.
Kokkos::DualView< impl_scalar_type **, Kokkos::LayoutLeft, device_type > dual_view_type
Kokkos::DualView specialization used by this class.
void elementWiseMultiply(Scalar scalarAB, const Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &B, Scalar scalarThis)
Multiply a Vector A elementwise by a MultiVector B.
size_t getNumVectors() const
Number of columns in the multivector.
typename Kokkos::ArithTraits< Scalar >::val_type impl_scalar_type
The type used internally in place of Scalar.
virtual size_t constantNumberOfPackets() const override
Number of packets to send per LID.
wrapped_dual_view_type getWrappedDualView() const
Return the wrapped dual view holding this MultiVector's local data.
void sumIntoLocalValue(const LocalOrdinal lclRow, const size_t col, const impl_scalar_type &val, const bool atomic=useAtomicUpdatesByDefault)
Update (+=) a value in host memory, using local row index.
void replaceMap(const Teuchos::RCP< const map_type > &map)
Replace the underlying Map in place.
Teuchos::RCP< MultiVector< T, LocalOrdinal, GlobalOrdinal, Node > > convert() const
Return another MultiVector with the same entries, but converted to a different Scalar type T.
MultiVector()
Default constructor: makes a MultiVector with no rows or columns.
dual_view_type::t_dev::const_type getLocalViewDevice(Access::ReadOnlyStruct) const
Return a read-only, up-to-date view of this MultiVector's local data on device. This requires that th...
typename device_type::execution_space execution_space
Type of the (new) Kokkos execution space.
void abs(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A)
Put element-wise absolute values of input Multi-vector in target: A = abs(this)
void norm1(const Kokkos::View< mag_type *, Kokkos::HostSpace > &norms) const
Compute the one-norm of each vector (column), storing the result in a host view.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const override
Print the object with the given verbosity level to a FancyOStream.
void get2dCopy(const Teuchos::ArrayView< const Teuchos::ArrayView< Scalar > > &ArrayOfPtrs) const
Fill the given array with a copy of this multivector's local values.
void sumIntoGlobalValue(const GlobalOrdinal gblRow, const size_t col, const impl_scalar_type &value, const bool atomic=useAtomicUpdatesByDefault)
Update (+=) a value in host memory, using global row index.
bool aliases(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &other) const
Whether this multivector's memory might alias other. This is conservative: if either this or other is...
dual_view_type::t_host::const_type getLocalViewHost(Access::ReadOnlyStruct) const
Return a read-only, up-to-date view of this MultiVector's local data on host. This requires that ther...
Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > subViewNonConst(const Teuchos::Range1D &colRng)
Return a MultiVector with views of selected columns.
Teuchos::Array< size_t > whichVectors_
Indices of columns this multivector is viewing.
Teuchos::ArrayRCP< Scalar > getDataNonConst(size_t j)
View of the local values in a particular vector of this multivector.
bool isConstantStride() const
Whether this multivector has constant stride between columns.
typename Kokkos::ArithTraits< impl_scalar_type >::mag_type mag_type
Type of a norm result.
size_t getOrigNumLocalCols() const
"Original" number of columns in the (local) data.
Teuchos::ArrayRCP< Teuchos::ArrayRCP< Scalar > > get2dViewNonConst()
Return non-const persisting pointers to values.
virtual std::string description() const override
A simple one-line description of this object.
Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > offsetViewNonConst(const Teuchos::RCP< const map_type > &subMap, const size_t offset)
Return a nonconst view of a subset of rows.
std::string localDescribeToString(const Teuchos::EVerbosityLevel vl) const
Print the calling process' verbose describe() information to the returned string.
bool isSameSize(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &vec) const
size_t getOrigNumLocalRows() const
"Original" number of rows in the (local) data.
Teuchos::ArrayRCP< Teuchos::ArrayRCP< const Scalar > > get2dView() const
Return const persisting pointers to values.
void putScalar(const Scalar &value)
Set all values in the multivector with the given value.
void update(const Scalar &alpha, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const Scalar &beta)
Update: this = beta*this + alpha*A.
Abstract base class for objects that can be the source of an Import or Export operation.
Implementation details of Tpetra.
int local_ordinal_type
Default value of Scalar template parameter.
void normImpl(MagnitudeType norms[], const Kokkos::View< const ValueType **, ArrayLayout, DeviceType > &X, const EWhichNorm whichNorm, const Teuchos::ArrayView< const size_t > &whichVecs, const bool isConstantStride, const bool isDistributed, const Teuchos::Comm< int > *comm)
Implementation of MultiVector norms.
bool isInterComm(const Teuchos::Comm< int > &)
Return true if and only if the input communicator wraps an MPI intercommunicator.
bool reallocDualViewIfNeeded(Kokkos::DualView< ValueType *, DeviceType > &dv, const size_t newSize, const char newLabel[], const size_t tooBigFactor=2, const bool needFenceBeforeRealloc=true)
Reallocate the DualView in/out argument, if needed.
void gathervPrint(std::ostream &out, const std::string &s, const Teuchos::Comm< int > &comm)
On Process 0 in the given communicator, print strings from each process in that communicator,...
Namespace Tpetra contains the class and methods constituting the Tpetra library.
void deep_copy(MultiVector< DS, DL, DG, DN > &dst, const MultiVector< SS, SL, SG, SN > &src)
Copy the contents of the MultiVector src into dst.
Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > createMultiVector(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &map, const size_t numVectors)
Nonmember MultiVector "constructor": Create a MultiVector from a given Map.
size_t global_size_t
Global size_t object.
std::string combineModeToString(const CombineMode combineMode)
Human-readable string representation of the given CombineMode.
MultiVector< ST, LO, GO, NT > createCopy(const MultiVector< ST, LO, GO, NT > &src)
Return a deep copy of the given MultiVector.
CombineMode
Rule for combining data in an Import or Export.
@ REPLACE
Replace existing values with new values.
@ ABSMAX
Replace old value with maximum of magnitudes of old and new values.
@ ADD_ASSIGN
Accumulate new values into existing values (may not be supported in all classes)
@ INSERT
Insert new values that don't currently exist.