41 #ifndef __Tpetra_MultiVectorFiller_hpp
42 #define __Tpetra_MultiVectorFiller_hpp
43 #include "TpetraCore_config.h"
44 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
45 #include "Tpetra_MultiVector.hpp"
46 #include "Tpetra_Vector.hpp"
47 #include "Teuchos_CommHelpers.hpp"
79 sortAndMergeIn (Teuchos::Array<T>& allEntries,
80 Teuchos::ArrayView<T> currentEntries,
81 Teuchos::ArrayView<T> newEntries)
83 using Teuchos::ArrayView;
85 typedef typename ArrayView<T>::iterator iter_type;
86 typedef typename ArrayView<T>::size_type size_type;
88 std::sort (newEntries.begin(), newEntries.end());
89 iter_type it = std::unique (newEntries.begin(), newEntries.end());
90 const size_type numNew = as<size_type> (it - newEntries.begin());
92 ArrayView<T> newEntriesView = newEntries.view (0, numNew);
94 const size_type numCur = currentEntries.size();
95 if (allEntries.size() < numCur + numNew) {
96 allEntries.resize (numCur + numNew);
98 ArrayView<T> allView = allEntries.view (0, numCur + numNew);
99 ArrayView<T> newView = allEntries.view (numCur, numNew);
101 std::copy (newEntries.begin(), newEntries.end(), newView.begin());
102 std::inplace_merge (allView.begin(), newView.begin(), allView.end());
103 iter_type it2 = std::unique (allView.begin(), allView.end());
104 const size_type numTotal = as<size_type> (it2 - allView.begin());
106 return allEntries.view (0, numTotal);
115 class TPETRA_DEPRECATED MultiVectorFillerData {
117 typedef typename MV::scalar_type scalar_type;
119 typedef typename MV::global_ordinal_type global_ordinal_type;
120 typedef typename MV::node_type
node_type;
122 typedef ::Tpetra::Map<local_ordinal_type, global_ordinal_type, node_type> map_type;
135 MultiVectorFillerData (
const Teuchos::RCP<const map_type>& map) :
156 MultiVectorFillerData (
const Teuchos::RCP<const map_type>& map,
157 const size_t numColumns) :
159 numCols_ (numColumns),
160 sourceIndices_ (numColumns),
161 sourceValues_ (numColumns)
166 setNumColumns (
const size_t newNumColumns)
168 const size_t oldNumColumns = getNumColumns();
169 if (newNumColumns >= oldNumColumns) {
170 for (
size_t j = oldNumColumns; j < newNumColumns; ++j) {
171 sourceIndices_.push_back (Teuchos::Array<global_ordinal_type> ());
172 sourceValues_.push_back (Teuchos::Array<scalar_type> ());
177 sourceIndices_.resize (newNumColumns);
178 sourceValues_.resize (newNumColumns);
180 numCols_ = oldNumColumns;
184 sumIntoGlobalValues (
const Teuchos::ArrayView<const global_ordinal_type>& rows,
186 const Teuchos::ArrayView<const scalar_type>& values)
188 if (column >= getNumColumns()) {
189 for (
size_t j = column; j < getNumColumns(); ++j) {
190 sourceIndices_.push_back (Teuchos::Array<global_ordinal_type> ());
191 sourceValues_.push_back (Teuchos::Array<scalar_type> ());
194 std::copy (rows.begin(), rows.end(), std::back_inserter (sourceIndices_[column]));
195 std::copy (values.begin(), values.end(), std::back_inserter (sourceValues_[column]));
206 sumIntoGlobalValues (
const Teuchos::ArrayView<const global_ordinal_type>& rows,
207 const Teuchos::ArrayView<const scalar_type>& values)
209 typedef global_ordinal_type GO;
210 typedef scalar_type ST;
211 typedef typename Teuchos::ArrayView<const GO>::const_iterator GoIter;
212 typedef typename Teuchos::ArrayView<const ST>::const_iterator StIter;
214 const size_t numColumns = getNumColumns();
215 GoIter rowIter = rows.begin();
216 StIter valIter = values.begin();
217 for (
size_t j = 0; j < numColumns; ++j) {
218 GoIter rowIterNext = rowIter + numColumns;
219 StIter valIterNext = valIter + numColumns;
220 std::copy (rowIter, rowIterNext, std::back_inserter (sourceIndices_[j]));
221 std::copy (valIter, valIterNext, std::back_inserter (sourceValues_[j]));
222 rowIter = rowIterNext;
223 valIter = valIterNext;
251 template<
class BinaryFunction>
253 locallyAssemble (MV& X, BinaryFunction& f)
255 using Teuchos::Array;
256 using Teuchos::ArrayRCP;
257 using Teuchos::ArrayView;
260 typedef global_ordinal_type GO;
261 typedef scalar_type ST;
264 RCP<const ::Tpetra::Map<LO, GO, NT> > map = X.getMap();
265 Array<LO> localIndices;
266 const size_t numColumns = getNumColumns();
267 for (
size_t j = 0; j < numColumns; ++j) {
268 const typename Array<const GO>::size_type numIndices = sourceIndices_[j].size();
273 if (localIndices.size() < numIndices) {
274 localIndices.resize (numIndices);
276 ArrayView<LO> localIndicesView = localIndices.view (0, numIndices);
277 ArrayView<const GO> globalIndicesView = sourceIndices_[j].view (0, numIndices);
278 for (
typename ArrayView<const GO>::size_type i = 0; i < numIndices; ++i) {
279 localIndices[i] = map->getLocalElement (globalIndicesView[i]);
282 ArrayRCP<ST> X_j = X.getDataNonConst (j);
283 ArrayView<const ST> localValues = sourceValues_[j].view (0, numIndices);
284 for (
typename ArrayView<const GO>::size_type i = 0; i < numIndices; ++i) {
285 const LO localInd = localIndices[i];
286 X_j[localInd] = f (X_j[localInd], localValues[i]);
293 locallyAssemble (MV& X)
295 std::plus<scalar_type> f;
296 locallyAssemble<std::plus<scalar_type> > (X, f);
301 Teuchos::Array<Teuchos::Array<global_ordinal_type> > newSourceIndices;
302 Teuchos::Array<Teuchos::Array<scalar_type> > newSourceValues;
304 std::swap (sourceIndices_, newSourceIndices);
305 std::swap (sourceValues_, newSourceValues);
309 Teuchos::Array<global_ordinal_type>
310 getSourceIndices ()
const
312 using Teuchos::Array;
313 using Teuchos::ArrayView;
315 typedef global_ordinal_type GO;
316 typedef typename Array<GO>::size_type size_type;
318 Array<GO> allInds (0);
319 const size_t numCols = getNumColumns();
326 const size_type numNew = sourceIndices_[0].size();
327 allInds.resize (allInds.size() + numNew);
328 std::copy (sourceIndices_[0].begin(), sourceIndices_[0].end(),
330 std::sort (allInds.begin(), allInds.end());
331 typename Array<GO>::iterator it =
332 std::unique (allInds.begin(), allInds.end());
333 const size_type numFinal = as<size_type> (it - allInds.begin());
334 allInds.resize (numFinal);
342 ArrayView<GO> curIndsView = allInds.view (0, 0);
344 for (
size_t j = 0; j < numCols; ++j) {
345 const size_type numNew = sourceIndices_[j].size();
346 if (numNew > newInds.size()) {
347 newInds.resize (numNew);
349 ArrayView<GO> newIndsView = newInds.view (0, numNew);
350 std::copy (sourceIndices_[j].begin(), sourceIndices_[j].end(),
351 newIndsView.begin());
352 curIndsView = sortAndMergeIn<GO> (allInds, curIndsView, newIndsView);
359 Teuchos::RCP<const map_type> map_;
361 Teuchos::Array<Teuchos::Array<global_ordinal_type> > sourceIndices_;
362 Teuchos::Array<Teuchos::Array<scalar_type> > sourceValues_;
364 size_t getNumColumns()
const {
return numCols_; }
374 class TPETRA_DEPRECATED MultiVectorFillerData2 :
public Teuchos::Describable {
376 typedef typename MV::scalar_type scalar_type;
378 typedef typename MV::global_ordinal_type global_ordinal_type;
379 typedef typename MV::node_type
node_type;
381 typedef ::Tpetra::Map<local_ordinal_type, global_ordinal_type, node_type> map_type;
393 MultiVectorFillerData2 (
const Teuchos::RCP<const map_type>& map,
394 const Teuchos::EVerbosityLevel verbLevel=Teuchos::VERB_DEFAULT,
395 const Teuchos::RCP<Teuchos::FancyOStream>& out=Teuchos::null) :
398 verbLevel_ (verbLevel),
419 MultiVectorFillerData2 (
const Teuchos::RCP<const map_type>& map,
420 const size_t numColumns,
421 const Teuchos::EVerbosityLevel verbLevel=Teuchos::VERB_DEFAULT,
422 const Teuchos::RCP<Teuchos::FancyOStream>& out=Teuchos::null) :
424 numCols_ (numColumns),
425 localVec_ (new MV (map, numColumns)),
427 nonlocalIndices_ (numColumns),
428 nonlocalValues_ (numColumns),
430 verbLevel_ (verbLevel),
437 std::ostringstream oss;
438 oss <<
"Tpetra::MultiVectorFillerData2<"
439 << Teuchos::TypeNameTraits<MV>::name () <<
">";
444 describe (Teuchos::FancyOStream& out,
445 const Teuchos::EVerbosityLevel verbLevel =
446 Teuchos::Describable::verbLevel_default)
const
449 using Teuchos::Array;
450 using Teuchos::ArrayRCP;
451 using Teuchos::ArrayView;
453 using Teuchos::VERB_DEFAULT;
454 using Teuchos::VERB_NONE;
455 using Teuchos::VERB_LOW;
456 using Teuchos::VERB_MEDIUM;
457 using Teuchos::VERB_HIGH;
458 using Teuchos::VERB_EXTREME;
461 const Teuchos::EVerbosityLevel vl =
462 (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
464 RCP<const Teuchos::Comm<int> > comm = map_->getComm();
465 const int myImageID = comm->getRank();
466 const int numImages = comm->getSize();
468 if (vl != VERB_NONE) {
470 Teuchos::OSTab tab (out);
472 if (myImageID == 0) {
473 out << this->description() << endl;
475 for (
int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
476 if (myImageID == imageCtr) {
477 if (vl != VERB_LOW) {
479 out <<
"Process " << myImageID <<
":" << endl;
481 Teuchos::OSTab procTab (out);
483 out <<
"local length=" << localVec_->getLocalLength();
484 if (vl != VERB_MEDIUM) {
486 if (localVec_->isConstantStride()) {
487 out <<
", constant stride=" << localVec_->getStride() << endl;
490 out <<
", not constant stride" << endl;
492 if (vl == VERB_EXTREME) {
494 out <<
"Local values:" << endl;
495 ArrayRCP<ArrayRCP<const scalar_type> > X = localVec_->get2dView();
496 for (
size_t i = 0; i < localVec_->getLocalLength(); ++i) {
497 for (
size_t j = 0; j < localVec_->getNumVectors(); ++j) {
499 if (j < localVec_->getNumVectors() - 1) {
507 out <<
"Nonlocal indices and values:" << endl;
508 for (
size_t j = 0; j < (size_t)nonlocalIndices_.size(); ++j) {
509 ArrayView<const global_ordinal_type> inds = nonlocalIndices_[j]();
510 ArrayView<const scalar_type> vals = nonlocalValues_[j]();
511 for (
typename ArrayView<const global_ordinal_type>::size_type k = 0;
512 k < inds.size(); ++k) {
513 out <<
"X(" << inds[k] <<
"," << j <<
") = " << vals[k] << endl;
529 Teuchos::Array<global_ordinal_type>
530 getSourceIndices (
const Teuchos::Comm<int>& comm,
531 const Teuchos::RCP<Teuchos::FancyOStream>& out = Teuchos::null,
532 const bool debug =
false)
const
534 using Teuchos::Array;
535 using Teuchos::ArrayView;
539 typedef global_ordinal_type GO;
540 const char prefix[] =
"Tpetra::MultiVectorFiller::getSourceIndices: ";
542 if (debug && ! out.is_null ()) {
543 std::ostringstream os;
544 os <<
"Proc " << comm.getRank () <<
": getSourceIndices" << std::endl;
550 Array<GO> nonlocalIndices = getSortedUniqueNonlocalIndices (comm, out, debug);
553 ArrayView<const GO> localIndices = getLocalIndices ();
559 Array<GO> indices (localIndices.size () + nonlocalIndices.size ());
560 ArrayView<GO> localIndView = indices.view (0, localIndices.size ());
561 TEUCHOS_TEST_FOR_EXCEPTION
562 (localIndView.size () > indices.size (), std::logic_error,
563 prefix <<
"localIndView.size() = " << localIndView.size ()
564 <<
" > indices.size() = " << indices.size () <<
".");
565 TEUCHOS_TEST_FOR_EXCEPTION
566 (localIndView.size () != localIndices.size (), std::logic_error,
567 prefix <<
"localIndView.size() = " << localIndView.size ()
568 <<
" != localIndices.size() = " << localIndices.size () <<
".");
570 std::copy (localIndices.begin (), localIndices.end (), localIndView.begin ());
571 std::sort (localIndView.begin (), localIndView.end ());
573 if (debug && ! out.is_null ()) {
574 std::ostringstream os;
575 os <<
"Proc " << comm.getRank () <<
": Right after copying and sorting" << std::endl;
580 if (nonlocalIndices.size () > 0) {
581 ArrayView<GO> nonlclIndView =
582 indices.view (localIndices.size (), nonlocalIndices.size ());
590 ArrayView<GO> indView = indices.view (0, indices.size ());
591 if (debug && ! out.is_null ()) {
592 std::ostringstream os;
593 os <<
"Right before std::copy" << std::endl;
596 std::copy (nonlocalIndices.begin (),
597 nonlocalIndices.end (),
598 nonlclIndView.begin ());
599 if (debug && ! out.is_null ()) {
600 std::ostringstream os;
601 os <<
"Proc " << comm.getRank () <<
": Right before std::inplace_merge"
605 std::inplace_merge (indView.begin (),
606 indView.begin () + localIndices.size (),
610 if (debug && ! out.is_null ()) {
611 std::ostringstream os;
612 os <<
"Proc " << comm.getRank () <<
": Done with getSourceIndices"
629 setNumColumns (
const size_t newNumColumns)
631 using Teuchos::Array;
632 using Teuchos::Range1D;
635 const size_t oldNumColumns = numCols_;
636 if (newNumColumns == oldNumColumns) {
641 if (newNumColumns > oldNumColumns) {
642 newLclVec = rcp (
new MV (map_, newNumColumns));
646 RCP<MV> newLclVecView =
647 newLclVec->subViewNonConst (Range1D (0, oldNumColumns-1));
648 *newLclVecView = *localVec_;
651 if (newNumColumns == 0) {
654 newLclVec = Teuchos::null;
657 newLclVec = localVec_->subViewNonConst (Range1D (0, newNumColumns-1));
662 localVec_ = newLclVec;
663 numCols_ = newNumColumns;
672 sumIntoGlobalValues (
const Teuchos::ArrayView<const global_ordinal_type>& rows,
673 const size_t columnIndex,
674 const Teuchos::ArrayView<const scalar_type>& values)
676 using Teuchos::ArrayView;
678 typedef global_ordinal_type GO;
679 typedef scalar_type ST;
680 typedef decltype (rows.size ()) size_type;
681 const char prefix[] =
"Tpetra::MultiVectorFiller::sumIntoGlobalValues: ";
683 if (map_.is_null ()) {
686 const size_type numEnt = rows.size ();
687 TEUCHOS_TEST_FOR_EXCEPTION
688 (numEnt != values.size (), std::invalid_argument, prefix
689 <<
"rows.size() = " << numEnt <<
" != values.size() = "
690 << values.size () <<
".");
693 if (columnIndex >= getNumColumns()) {
696 setNumColumns (columnIndex + 1);
701 auto X_j = localVec_->getVector (columnIndex);
702 auto X_j_2d = X_j->template getLocalView<typename MV::dual_view_type::t_host::memory_space> ();
703 auto X_j_1d = Kokkos::subview (X_j_2d, Kokkos::ALL (), 0);
705 const map_type& theMap = *map_;
706 for (size_type k = 0; k < numEnt; ++k) {
707 const ST val = values[k];
708 const GO gblRowInd = rows[k];
709 const LO lclRowInd = theMap.getLocalElement (gblRowInd);
710 if (lclRowInd == Teuchos::OrdinalTraits<LO>::invalid ()) {
714 auto& innerMap = nonlocals_[columnIndex];
715 auto innerIter = innerMap.find (gblRowInd);
716 if (innerIter == innerMap.end ()) {
717 innerMap.insert (std::make_pair (gblRowInd, values[k]));
719 innerIter->second += val;
726 X_j_1d[lclRowInd] += val;
741 sumIntoGlobalValues (
const Teuchos::ArrayView<const global_ordinal_type>& rows,
742 const Teuchos::ArrayView<const scalar_type>& values)
744 using Teuchos::ArrayView;
745 typedef typename ArrayView<const global_ordinal_type>::size_type size_type;
747 const size_t numCols = getNumColumns();
748 for (
size_t j = 0; j < numCols; ++j) {
749 const size_type offset = numCols*j;
750 const size_type len = numCols;
751 this->sumIntoGlobalValues (rows.view (offset, len), j, values.view (offset, len));
779 template<
class BinaryFunction>
781 locallyAssemble (MV& X, BinaryFunction& f)
783 typedef scalar_type ST;
785 typedef global_ordinal_type GO;
786 typedef typename MV::dual_view_type::t_host::memory_space host_memory_space;
788 if (X.getMap ().is_null ()) {
791 const map_type& srcMap = * (X.getMap ());
795 for (
size_t j = 0; j < X.getNumVectors (); ++j) {
796 auto X_j = X.getVector (j);
797 auto X_j_2d = X_j->template getLocalView<host_memory_space> ();
798 auto X_j_1d = Kokkos::subview (X_j_2d, Kokkos::ALL (), 0);
801 if (! localVec_.is_null () && ! localVec_->getMap ().is_null ()
802 && j < localVec_->getNumVectors ()) {
803 auto lcl_j = localVec_->getVector (j);
804 auto lcl_j_2d = lcl_j->template getLocalView<host_memory_space> ();
805 auto lcl_j_1d = Kokkos::subview (lcl_j_2d, Kokkos::ALL (), 0);
810 const map_type& lclMap = * (localVec_->getMap ());
811 const LO lclNumRows =
static_cast<LO
> (lcl_j->getLocalLength ());
812 for (LO i_lcl = 0; i_lcl < lclNumRows; ++i_lcl) {
813 const GO i_gbl = lclMap.getGlobalElement (i_lcl);
814 const LO i_X = srcMap.getLocalElement (i_gbl);
815 X_j_1d(i_X) = f (X_j_1d(i_X), lcl_j_1d(i_lcl));
820 auto outerIter = nonlocals_.find (j);
821 if (outerIter != nonlocals_.end ()) {
822 auto beg = outerIter->second.begin ();
823 auto end = outerIter->second.end ();
824 for (
auto innerIter = beg; innerIter != end; ++innerIter) {
825 const GO gblRowInd = innerIter->first;
826 const LO lclRowInd = srcMap.getLocalElement (gblRowInd);
828 if (lclRowInd != Teuchos::OrdinalTraits<LO>::invalid ()) {
829 const ST val = innerIter->second;
830 X_j_1d(lclRowInd) = f (X_j_1d(lclRowInd), val);
843 locallyAssemble (MV& X)
845 std::plus<scalar_type> f;
846 locallyAssemble<std::plus<scalar_type> > (X, f);
856 std::map<size_t, std::map<global_ordinal_type, scalar_type> > newNonlcls;
860 std::swap (nonlocals_, newNonlcls);
865 if (! localVec_.is_null ()) {
866 localVec_->putScalar (Teuchos::ScalarTraits<scalar_type>::zero());
872 Teuchos::RCP<const map_type> map_;
878 Teuchos::RCP<MV> localVec_;
881 std::map<size_t, std::map<global_ordinal_type, scalar_type> > nonlocals_;
884 Teuchos::EVerbosityLevel verbLevel_;
887 Teuchos::RCP<Teuchos::FancyOStream> out_;
890 size_t getNumColumns()
const {
return numCols_; }
893 Teuchos::ArrayView<const global_ordinal_type>
894 getLocalIndices()
const
896 return map_->getNodeElementList ();
900 Teuchos::Array<global_ordinal_type>
901 getSortedUniqueNonlocalIndices (
const Teuchos::Comm<int>& comm,
902 const Teuchos::RCP<Teuchos::FancyOStream>& out = Teuchos::null,
903 const bool debug =
false)
const
905 using Teuchos::Array;
906 using Teuchos::ArrayView;
908 typedef global_ordinal_type GO;
910 if (debug && ! out.is_null ()) {
911 std::ostringstream os;
912 os <<
"Proc " << comm.getRank () <<
": getSortedUniqueNonlocalIndices"
920 std::set<GO> indsOut;
921 const size_t numCols = getNumColumns ();
922 for (
size_t j = 0; j < numCols; ++j) {
923 auto outerIter = nonlocals_.find (j);
924 if (outerIter != nonlocals_.end ()) {
925 auto beg = outerIter->second.begin ();
926 auto end = outerIter->second.end ();
927 for (
auto innerIter = beg; innerIter != end; ++innerIter) {
929 indsOut.insert (innerIter->first);
934 if (debug && ! out.is_null ()) {
935 std::ostringstream os;
936 os <<
"Proc " << comm.getRank () <<
": Made nonlocals set" << std::endl;
940 Array<GO> allNonlocals (indsOut.begin (), indsOut.end ());
941 if (debug && ! out.is_null ()) {
942 std::ostringstream os;
943 os <<
"Proc " << comm.getRank () <<
": Done with "
944 "getSortedUniqueNonlocalIndices" << std::endl;
980 class TPETRA_DEPRECATED MultiVectorFiller {
982 typedef typename MV::scalar_type scalar_type;
984 typedef typename MV::global_ordinal_type global_ordinal_type;
985 typedef typename MV::node_type
node_type;
986 typedef ::Tpetra::Map<local_ordinal_type, global_ordinal_type, node_type> map_type;
1017 MultiVectorFiller (
const Teuchos::RCP<const map_type>& map,
1018 const size_t numCols);
1040 globalAssemble (MV& X_out,
const bool forceReuseMap =
false);
1048 describe (Teuchos::FancyOStream& out,
1049 const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default)
const
1051 data_.describe (out, verbLevel);
1065 sumIntoGlobalValues (Teuchos::ArrayView<const global_ordinal_type> rows,
1067 Teuchos::ArrayView<const scalar_type> values)
1069 data_.sumIntoGlobalValues (rows, column, values);
1088 sumIntoGlobalValues (Teuchos::ArrayView<const global_ordinal_type> rows,
1089 Teuchos::ArrayView<const scalar_type> values)
1091 data_.sumIntoGlobalValues (rows, values);
1096 Teuchos::RCP<const map_type> ctorMap_;
1102 Teuchos::RCP<const map_type> sourceMap_;
1109 Teuchos::RCP<const map_type> targetMap_;
1123 Teuchos::RCP<MV> sourceVec_;
1129 Tpetra::Details::MultiVectorFillerData2<MV> data_;
1132 Teuchos::RCP<export_type> exporter_;
1139 void locallyAssemble (MV& X_in) {
1140 data_.locallyAssemble (X_in);
1144 Teuchos::Array<global_ordinal_type>
1145 getSourceIndices (
const Teuchos::Comm<int>& comm,
1146 const Teuchos::RCP<Teuchos::FancyOStream>& out = Teuchos::null,
1147 const bool debug =
false)
const
1149 return data_.getSourceIndices (comm, out, debug);
1160 Teuchos::RCP<const map_type>
1161 computeSourceMap (
const global_ordinal_type indexBase,
1162 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
1163 const Teuchos::RCP<Teuchos::FancyOStream>& out = Teuchos::null,
1164 const bool debug =
false);
1168 MultiVectorFiller<MV>::MultiVectorFiller (
const Teuchos::RCP<
const typename MultiVectorFiller<MV>::map_type>& map,
const size_t numCols)
1170 sourceMap_ (Teuchos::null),
1171 targetMap_ (Teuchos::null),
1172 data_ (map, numCols),
1173 exporter_ (Teuchos::null)
1177 Teuchos::RCP<const typename MultiVectorFiller<MV>::map_type>
1178 MultiVectorFiller<MV>::
1179 computeSourceMap (
const global_ordinal_type indexBase,
1180 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
1181 const Teuchos::RCP<Teuchos::FancyOStream>& out,
1184 using Teuchos::Array;
1185 using Teuchos::ArrayView;
1187 typedef global_ordinal_type GO;
1189 if (debug && ! out.is_null ()) {
1191 std::ostringstream os;
1192 const int myRank = comm->getRank ();
1193 os <<
"Proc " << myRank <<
": computeSourceMap" << std::endl;
1197 Array<GO> indices = getSourceIndices (*comm, out, debug);
1199 if (debug && ! out.is_null ()) {
1200 std::ostringstream os;
1201 const int myRank = comm->getRank ();
1202 os <<
"Proc " << myRank <<
": computeSourceMap: About to create Map"
1212 const GST INV = Teuchos::OrdinalTraits<GST>::invalid ();
1213 return rcp (
new map_type (INV, indices, indexBase, comm));
1218 MultiVectorFiller<MV>::
1219 globalAssemble (MV& X_out,
const bool forceReuseMap)
1221 using Teuchos::ArrayView;
1222 using Teuchos::Array;
1223 using Teuchos::Range1D;
1226 RCP<Teuchos::FancyOStream> outPtr;
1227 const bool debug =
false;
1230 outPtr = Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr));
1234 const size_t numVecs = X_out.getNumVectors ();
1248 RCP<const map_type> targetMap;
1249 bool assumeSameTargetMap =
false;
1250 if (targetMap_.is_null()) {
1251 targetMap_ = X_out.getMap();
1252 targetMap = targetMap_;
1253 assumeSameTargetMap =
false;
1256 if (forceReuseMap) {
1257 targetMap = targetMap_;
1258 assumeSameTargetMap =
true;
1266 if (targetMap_->isSameAs (*(X_out.getMap()))) {
1267 assumeSameTargetMap =
true;
1268 targetMap = targetMap_;
1273 if (debug && ! outPtr.is_null ()) {
1274 std::ostringstream os;
1275 const Teuchos::Comm<int>& comm = * (X_out.getMap ()->getComm ());
1276 const int myRank = comm.getRank ();
1277 os <<
"Proc " << myRank <<
": Right before getting source Map" << std::endl;
1278 *outPtr << os.str ();
1286 RCP<const map_type> sourceMap;
1287 bool computedSourceMap =
false;
1289 if (forceReuseMap && ! sourceMap_.is_null()) {
1290 sourceMap = sourceMap_;
1293 sourceMap = computeSourceMap (ctorMap_->getIndexBase (),
1294 ctorMap_->getComm (),
1296 computedSourceMap =
true;
1299 if (computedSourceMap) {
1300 sourceMap_ = sourceMap;
1303 if (debug && ! outPtr.is_null ()) {
1304 std::ostringstream os;
1305 const Teuchos::Comm<int>& comm = * (X_out.getMap ()->getComm ());
1306 const int myRank = comm.getRank ();
1307 os <<
"Proc " << myRank <<
": Right before computing Export" << std::endl;
1308 *outPtr << os.str ();
1315 const bool mustComputeExport =
1316 (exporter_.is_null() || (assumeSameTargetMap && ! computedSourceMap));
1317 if (mustComputeExport) {
1318 exporter_ = rcp (
new export_type (sourceMap_, targetMap_));
1321 if (debug && ! outPtr.is_null ()) {
1322 std::ostringstream os;
1323 const Teuchos::Comm<int>& comm = * (X_out.getMap ()->getComm ());
1324 const int myRank = comm.getRank ();
1325 os <<
"Proc " << myRank <<
": Right after computing Export" << std::endl;
1326 *outPtr << os.str ();
1331 const bool mustReallocateVec = sourceVec_.is_null() ||
1332 sourceVec_->getNumVectors() < numVecs || ! assumeSameTargetMap;
1334 if (mustReallocateVec) {
1336 sourceVec_ = rcp (
new MV (sourceMap_, numVecs));
1339 if (sourceVec_->getNumVectors() == numVecs) {
1342 X_in = sourceVec_->subViewNonConst (Range1D (0, numVecs-1));
1346 if (debug && ! outPtr.is_null ()) {
1347 std::ostringstream os;
1348 const Teuchos::Comm<int>& comm = * (X_out.getMap ()->getComm ());
1349 const int myRank = comm.getRank ();
1350 os <<
"Proc " << myRank <<
": Right before locallyAssemble" << std::endl;
1351 *outPtr << os.str ();
1356 locallyAssemble (*X_in);
1358 if (debug && ! outPtr.is_null ()) {
1359 std::ostringstream os;
1360 const Teuchos::Comm<int>& comm = * (X_out.getMap ()->getComm ());
1361 const int myRank = comm.getRank ();
1362 os <<
"Proc " << myRank <<
": Right after locallyAssemble" << std::endl;
1363 *outPtr << os.str ();
1368 X_out.doExport (*X_in, *exporter_, combineMode);
1370 if (debug && ! outPtr.is_null ()) {
1371 std::ostringstream os;
1372 const Teuchos::Comm<int>& comm = * (X_out.getMap ()->getComm ());
1373 const int myRank = comm.getRank ();
1374 os <<
"Proc " << myRank <<
": Right after Export" << std::endl;
1375 *outPtr << os.str ();
1379 X_in->putScalar (Teuchos::ScalarTraits<scalar_type>::zero ());
1384 if (debug && ! outPtr.is_null ()) {
1385 std::ostringstream os;
1386 const Teuchos::Comm<int>& comm = * (X_out.getMap ()->getComm ());
1387 const int myRank = comm.getRank ();
1388 os <<
"Proc " << myRank <<
": Done with globalAssemble" << std::endl;
1389 *outPtr << os.str ();
1402 class TPETRA_DEPRECATED MultiVectorFillerTester {
1404 typedef typename MV::scalar_type scalar_type;
1406 typedef typename MV::global_ordinal_type global_ordinal_type;
1407 typedef typename MV::node_type
node_type;
1408 typedef ::Tpetra::Map<local_ordinal_type, global_ordinal_type, node_type> map_type;
1419 testSameMap (
const Teuchos::RCP<const map_type>& targetMap,
1420 const global_ordinal_type eltSize,
1421 const size_t numCols,
1422 const Teuchos::RCP<Teuchos::FancyOStream>& outStream=Teuchos::null,
1423 const Teuchos::EVerbosityLevel verbosityLevel=Teuchos::VERB_DEFAULT)
1425 using Teuchos::Array;
1426 using Teuchos::ArrayRCP;
1427 using Teuchos::ArrayView;
1429 using Teuchos::Comm;
1430 using Teuchos::FancyOStream;
1431 using Teuchos::getFancyOStream;
1432 using Teuchos::oblackholestream;
1436 using Teuchos::rcpFromRef;
1437 using Teuchos::REDUCE_SUM;
1438 using Teuchos::reduceAll;
1443 typedef global_ordinal_type GO;
1444 typedef scalar_type ST;
1445 typedef Teuchos::ScalarTraits<ST> STS;
1447 TEUCHOS_TEST_FOR_EXCEPTION(eltSize % 2 == 0, std::invalid_argument,
1448 "Element size (eltSize) argument must be odd.");
1449 TEUCHOS_TEST_FOR_EXCEPTION(numCols == 0, std::invalid_argument,
1450 "Number of columns (numCols) argument must be nonzero.");
1452 RCP<FancyOStream> out = outStream.is_null() ?
1453 getFancyOStream (rcp (
new oblackholestream)) : outStream;
1454 const Teuchos::EVerbosityLevel verbLevel =
1455 (verbosityLevel == Teuchos::VERB_DEFAULT) ?
1456 Teuchos::VERB_NONE : verbosityLevel;
1460 const GO indexBase = targetMap->getIndexBase();
1461 Array<GO> rows (eltSize);
1462 Array<ST> values (eltSize);
1463 std::fill (values.begin(), values.end(), STS::one());
1467 RCP<MultiVectorFiller<MV> > filler =
1468 rcp (
new MultiVectorFiller<MV> (targetMap, numCols));
1470 TEUCHOS_TEST_FOR_EXCEPTION(! targetMap->isContiguous(),
1471 std::invalid_argument,
"MultiVectorFiller test currently only works "
1472 "for contiguous Maps.");
1474 const GO minGlobalIndex = targetMap->getMinGlobalIndex();
1475 const GO maxGlobalIndex = targetMap->getMaxGlobalIndex();
1476 const GO minAllGlobalIndex = targetMap->getMinAllGlobalIndex();
1477 const GO maxAllGlobalIndex = targetMap->getMaxAllGlobalIndex();
1478 for (
size_t j = 0; j < numCols; ++j) {
1479 for (GO i = minGlobalIndex; i <= maxGlobalIndex; ++i) {
1481 const GO start = std::max (i - eltSize/2, minAllGlobalIndex);
1482 const GO end = std::min (i + eltSize/2, maxAllGlobalIndex);
1483 const GO len = end - start + 1;
1485 TEUCHOS_TEST_FOR_EXCEPTION(len > eltSize, std::logic_error,
1486 "At start,end = " << start <<
"," << end <<
", len = " << len
1487 <<
" > eltSize = " << eltSize <<
".");
1489 for (GO k = 0; k < len; ++k) {
1490 rows[k] = start + k;
1492 if (verbLevel == Teuchos::VERB_EXTREME) {
1493 *out <<
"Inserting: "
1494 << Teuchos::toString (rows.view(0,len)) <<
", "
1495 << Teuchos::toString (values.view(0, len)) << std::endl;
1497 filler->sumIntoGlobalValues (rows.view(0, len), j, values.view(0, len));
1501 if (verbLevel == Teuchos::VERB_EXTREME) {
1502 *out <<
"Filler:" << std::endl;
1503 filler->describe (*out, verbLevel);
1507 MV X_out (targetMap, numCols);
1508 filler->globalAssemble (X_out);
1509 filler = Teuchos::null;
1511 if (verbLevel == Teuchos::VERB_EXTREME) {
1512 *out <<
"X_out:" << std::endl;
1513 X_out.describe (*out, verbLevel);
1518 MV X_expected (targetMap, numCols);
1519 const scalar_type two = STS::one() + STS::one();
1520 for (
size_t j = 0; j < numCols; ++j) {
1521 ArrayRCP<ST> X_j = X_expected.getDataNonConst (j);
1526 for (GO i = minGlobalIndex; i <= maxGlobalIndex; ++i) {
1527 const LO localIndex = targetMap->getLocalElement (i);
1528 TEUCHOS_TEST_FOR_EXCEPTION(i == Teuchos::OrdinalTraits<LO>::invalid(),
1529 std::logic_error,
"Global index " << i <<
" is not in the "
1530 "multivector's Map.");
1532 if (i <= minAllGlobalIndex + eltSize/2) {
1533 X_j[localIndex] = two + as<ST>(i) - as<ST>(indexBase);
1535 else if (i >= maxAllGlobalIndex - eltSize/2) {
1536 X_j[localIndex] = two + as<ST>(maxAllGlobalIndex) - as<ST>(i);
1539 X_j[localIndex] = as<ST>(eltSize);
1544 if (verbLevel == Teuchos::VERB_EXTREME) {
1545 *out <<
"X_expected:" << std::endl;
1546 X_expected.describe (*out, verbLevel);
1550 Array<GO> errorLocations;
1551 for (
size_t j = 0; j < numCols; ++j) {
1552 ArrayRCP<const ST> X_out_j = X_out.getData (j);
1553 ArrayRCP<const ST> X_expected_j = X_expected.getData (j);
1558 for (GO i = minGlobalIndex; i <= maxGlobalIndex; ++i) {
1559 const LO localIndex = targetMap->getLocalElement (i);
1560 TEUCHOS_TEST_FOR_EXCEPTION(i == Teuchos::OrdinalTraits<LO>::invalid(),
1561 std::logic_error,
"Global index " << i <<
" is not in the "
1562 "multivector's Map.");
1566 if (X_out_j[localIndex] != X_expected_j[localIndex]) {
1567 errorLocations.push_back (i);
1571 const typename Array<GO>::size_type localNumErrors = errorLocations.size();
1572 typename Array<GO>::size_type globalNumErrors = 0;
1573 RCP<const Comm<int> > comm = targetMap->getComm();
1574 reduceAll (*comm, REDUCE_SUM, localNumErrors, ptr (&globalNumErrors));
1576 if (globalNumErrors != 0) {
1577 std::ostringstream os;
1578 os <<
"Proc " << comm->getRank() <<
": " << localNumErrors
1579 <<
" incorrect value" << (localNumErrors != 1 ?
"s" :
"")
1580 <<
". Error locations: [ ";
1581 std::copy (errorLocations.begin(), errorLocations.end(),
1582 std::ostream_iterator<GO> (os,
" "));
1586 for (
int p = 0; p < comm->getSize(); ++p) {
1587 if (p == comm->getRank()) {
1588 cerr << os.str() << endl;
1595 TEUCHOS_TEST_FOR_EXCEPTION(globalNumErrors != 0, std::logic_error,
1596 "Over all procs: " << globalNumErrors <<
" total error"
1597 << (globalNumErrors != 1 ?
"s" :
"") <<
".");
1604 template<
class ScalarType,
1605 class LocalOrdinalType,
1606 class GlobalOrdinalType,
1609 testMultiVectorFiller (
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
1610 const size_t unknownsPerNode,
1611 const GlobalOrdinalType unknownsPerElt,
1612 const size_t numCols,
1613 const Teuchos::RCP<Teuchos::FancyOStream>& outStream,
1614 const Teuchos::EVerbosityLevel verbLevel)
1616 using Teuchos::FancyOStream;
1617 using Teuchos::getFancyOStream;
1618 using Teuchos::oblackholestream;
1619 using Teuchos::ParameterList;
1625 typedef ScalarType ST;
1626 typedef LocalOrdinalType LO;
1627 typedef GlobalOrdinalType GO;
1628 typedef NodeType NT;
1629 typedef ::Tpetra::Map<LO, GO, NT> map_type;
1633 RCP<FancyOStream> out = outStream.is_null() ?
1634 getFancyOStream (rcp (
new oblackholestream)) : outStream;
1635 const GST INV = Teuchos::OrdinalTraits<GST>::invalid ();
1636 const GO indexBase = 0;
1637 RCP<const map_type> targetMap =
1638 rcp (
new map_type (INV, unknownsPerNode, indexBase, comm));
1640 std::ostringstream os;
1642 MultiVectorFillerTester<MV>::testSameMap (targetMap, unknownsPerElt, numCols, out, verbLevel);
1643 }
catch (std::exception& e) {
1647 for (
int p = 0; p < comm->getSize(); ++p) {
1648 if (p == comm->getRank()) {
1649 *out <<
"On process " << comm->getRank() <<
": " << os.str() << endl;
1663 testSortAndMergeIn ();
1668 #error "Compile Error: The header Tpetra_MultiVectorFiller.hpp is DEPRECATED and you have compiled with Tpetra_ENABLE_DEPRECATED_CODE off"
1670 #endif// TPETRA_ENABLE_DEPRECATED_CODE
1672 #endif // __Tpetra_MultiVectorFiller_hpp
One or more distributed dense vectors.
int local_ordinal_type
Default value of Scalar template parameter.
size_t global_size_t
Global size_t object.
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
CombineMode
Rule for combining data in an Import or Export.
Sum new values into existing values.
::Kokkos::Compat::KokkosDeviceWrapperNode< execution_space > node_type
Default value of Node template parameter.