41 #ifndef TPETRA_DISTOBJECT_DEF_HPP
42 #define TPETRA_DISTOBJECT_DEF_HPP
52 #include "Tpetra_Distributor.hpp"
55 #include "Tpetra_Details_checkGlobalError.hpp"
58 #include "Teuchos_CommHelpers.hpp"
59 #include "Teuchos_TypeNameTraits.hpp"
67 template<
class DeviceType,
class IndexType =
size_t>
69 SumFunctor (
const Kokkos::View<const size_t*, DeviceType>& viewToSum) :
70 viewToSum_ (viewToSum) {}
71 KOKKOS_INLINE_FUNCTION
void operator() (
const IndexType i,
size_t& lclSum)
const {
72 lclSum += viewToSum_(i);
74 Kokkos::View<const size_t*, DeviceType> viewToSum_;
77 template<
class DeviceType,
class IndexType =
size_t>
79 countTotalImportPackets (
const Kokkos::View<const size_t*, DeviceType>& numImportPacketsPerLID)
81 using Kokkos::parallel_reduce;
82 typedef DeviceType DT;
83 typedef typename DT::execution_space DES;
84 typedef Kokkos::RangePolicy<DES, IndexType> range_type;
86 const IndexType numOut = numImportPacketsPerLID.extent (0);
87 size_t totalImportPackets = 0;
88 parallel_reduce (
"Count import packets",
89 range_type (0, numOut),
90 SumFunctor<DeviceType, IndexType> (numImportPacketsPerLID),
92 return totalImportPackets;
97 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
102 #ifdef HAVE_TPETRA_TRANSFER_TIMERS
105 using Teuchos::TimeMonitor;
107 RCP<Time> doXferTimer =
108 TimeMonitor::lookupCounter (
"Tpetra::DistObject::doTransfer");
109 if (doXferTimer.is_null ()) {
111 TimeMonitor::getNewCounter (
"Tpetra::DistObject::doTransfer");
113 doXferTimer_ = doXferTimer;
115 RCP<Time> copyAndPermuteTimer =
116 TimeMonitor::lookupCounter (
"Tpetra::DistObject::copyAndPermute");
117 if (copyAndPermuteTimer.is_null ()) {
118 copyAndPermuteTimer =
119 TimeMonitor::getNewCounter (
"Tpetra::DistObject::copyAndPermute");
121 copyAndPermuteTimer_ = copyAndPermuteTimer;
123 RCP<Time> packAndPrepareTimer =
124 TimeMonitor::lookupCounter (
"Tpetra::DistObject::packAndPrepare");
125 if (packAndPrepareTimer.is_null ()) {
126 packAndPrepareTimer =
127 TimeMonitor::getNewCounter (
"Tpetra::DistObject::packAndPrepare");
129 packAndPrepareTimer_ = packAndPrepareTimer;
131 RCP<Time> doPostsAndWaitsTimer =
132 TimeMonitor::lookupCounter (
"Tpetra::DistObject::doPostsAndWaits");
133 if (doPostsAndWaitsTimer.is_null ()) {
134 doPostsAndWaitsTimer =
135 TimeMonitor::getNewCounter (
"Tpetra::DistObject::doPostsAndWaits");
137 doPostsAndWaitsTimer_ = doPostsAndWaitsTimer;
139 RCP<Time> unpackAndCombineTimer =
140 TimeMonitor::lookupCounter (
"Tpetra::DistObject::unpackAndCombine");
141 if (unpackAndCombineTimer.is_null ()) {
142 unpackAndCombineTimer =
143 TimeMonitor::getNewCounter (
"Tpetra::DistObject::unpackAndCombine");
145 unpackAndCombineTimer_ = unpackAndCombineTimer;
146 #endif // HAVE_TPETRA_TRANSFER_TIMERS
149 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
154 using Teuchos::TypeNameTraits;
156 std::ostringstream os;
157 os <<
"\"Tpetra::DistObject\": {"
158 <<
"Packet: " << TypeNameTraits<packet_type>::name ()
159 <<
", LocalOrdinal: " << TypeNameTraits<local_ordinal_type>::name ()
160 <<
", GlobalOrdinal: " << TypeNameTraits<global_ordinal_type>::name ()
161 <<
", Node: " << TypeNameTraits<Node>::name ();
162 if (this->getObjectLabel () !=
"") {
163 os <<
"Label: \"" << this->getObjectLabel () <<
"\"";
169 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
173 const Teuchos::EVerbosityLevel verbLevel)
const
175 using Teuchos::rcpFromRef;
176 using Teuchos::TypeNameTraits;
178 const Teuchos::EVerbosityLevel vl = (verbLevel == Teuchos::VERB_DEFAULT) ?
179 Teuchos::VERB_LOW : verbLevel;
180 Teuchos::RCP<const Teuchos::Comm<int> > comm = this->getMap ()->getComm ();
181 const int myRank = comm.is_null () ? 0 : comm->getRank ();
182 const int numProcs = comm.is_null () ? 1 : comm->getSize ();
184 if (vl != Teuchos::VERB_NONE) {
185 Teuchos::OSTab tab0 (out);
187 out <<
"\"Tpetra::DistObject\":" << endl;
189 Teuchos::OSTab tab1 (out);
191 out <<
"Template parameters:" << endl;
193 Teuchos::OSTab tab2 (out);
194 out <<
"Packet: " << TypeNameTraits<packet_type>::name () << endl
195 <<
"LocalOrdinal: " << TypeNameTraits<local_ordinal_type>::name () << endl
196 <<
"GlobalOrdinal: " << TypeNameTraits<global_ordinal_type>::name () << endl
197 <<
"Node: " << TypeNameTraits<node_type>::name () << endl;
199 if (this->getObjectLabel () !=
"") {
200 out <<
"Label: \"" << this->getObjectLabel () <<
"\"" << endl;
207 out <<
"Map:" << endl;
209 Teuchos::OSTab tab2 (out);
210 map_->describe (out, vl);
214 if (vl > Teuchos::VERB_LOW) {
215 for (
int p = 0; p < numProcs; ++p) {
217 out <<
"Process " << myRank <<
":" << endl;
218 Teuchos::OSTab tab2 (out);
219 out <<
"Export buffer size (in packets): "
220 << exports_.extent (0)
222 <<
"Import buffer size (in packets): "
223 << imports_.extent (0)
226 if (! comm.is_null ()) {
236 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
241 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
242 "Tpetra::DistObject::removeEmptyProcessesInPlace: Not implemented");
274 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
280 const bool restrictedMode)
284 const char modeString[] =
"doImport (forward mode)";
289 const bool verbose = Behavior::verbose(
"DistObject");
290 std::unique_ptr<std::string> prefix;
292 prefix = this->createPrefix(
"DistObject", modeString);
293 std::ostringstream os;
294 os << *prefix <<
"Start" << endl;
295 std::cerr << os.str ();
297 this->beginImport(source, importer, CM, restrictedMode);
298 this->endImport(source, importer, CM, restrictedMode);
300 std::ostringstream os;
301 os << *prefix <<
"Done" << endl;
302 std::cerr << os.str ();
306 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
312 const bool restrictedMode)
316 const char modeString[] =
"doExport (forward mode)";
321 const bool verbose = Behavior::verbose(
"DistObject");
322 std::unique_ptr<std::string> prefix;
324 prefix = this->createPrefix(
"DistObject", modeString);
325 std::ostringstream os;
326 os << *prefix <<
"Start" << endl;
327 std::cerr << os.str ();
329 this->beginExport(source, exporter, CM, restrictedMode);
330 this->endExport(source, exporter, CM, restrictedMode);
332 std::ostringstream os;
333 os << *prefix <<
"Done" << endl;
334 std::cerr << os.str ();
338 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
344 const bool restrictedMode)
348 const char modeString[] =
"doImport (reverse mode)";
353 const bool verbose = Behavior::verbose(
"DistObject");
354 std::unique_ptr<std::string> prefix;
356 prefix = this->createPrefix(
"DistObject", modeString);
357 std::ostringstream os;
358 os << *prefix <<
"Start" << endl;
359 std::cerr << os.str ();
361 this->beginImport(source, exporter, CM, restrictedMode);
362 this->endImport(source, exporter, CM, restrictedMode);
364 std::ostringstream os;
365 os << *prefix <<
"Done" << endl;
366 std::cerr << os.str ();
370 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
376 const bool restrictedMode)
380 const char modeString[] =
"doExport (reverse mode)";
385 const bool verbose = Behavior::verbose(
"DistObject");
386 std::unique_ptr<std::string> prefix;
388 prefix = this->createPrefix(
"DistObject", modeString);
389 std::ostringstream os;
390 os << *prefix <<
"Start" << endl;
391 std::cerr << os.str ();
393 this->beginExport(source, importer, CM, restrictedMode);
394 this->endExport(source, importer, CM, restrictedMode);
396 std::ostringstream os;
397 os << *prefix <<
"Done" << endl;
398 std::cerr << os.str ();
402 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
408 const bool restrictedMode)
412 const char modeString[] =
"beginImport (forward mode)";
417 const bool verbose = Behavior::verbose(
"DistObject");
418 std::unique_ptr<std::string> prefix;
420 prefix = this->createPrefix(
"DistObject", modeString);
421 std::ostringstream os;
422 os << *prefix <<
"Start" << endl;
423 std::cerr << os.str ();
425 this->beginTransfer(source, importer, modeString, DoForward, CM, restrictedMode);
427 std::ostringstream os;
428 os << *prefix <<
"Done" << endl;
429 std::cerr << os.str ();
433 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
435 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
436 beginExport(
const SrcDistObject& source,
437 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
439 const bool restrictedMode)
441 using Details::Behavior;
443 const char modeString[] =
"beginExport (forward mode)";
448 const bool verbose = Behavior::verbose(
"DistObject");
449 std::unique_ptr<std::string> prefix;
452 std::ostringstream os;
453 os << *prefix <<
"Start" << endl;
454 std::cerr << os.str ();
456 this->beginTransfer(source, exporter, modeString, DoForward, CM, restrictedMode);
458 std::ostringstream os;
459 os << *prefix <<
"Done" << endl;
460 std::cerr << os.str ();
464 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
466 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
467 beginImport(
const SrcDistObject& source,
468 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
470 const bool restrictedMode)
472 using Details::Behavior;
474 const char modeString[] =
"beginImport (reverse mode)";
479 const bool verbose = Behavior::verbose(
"DistObject");
480 std::unique_ptr<std::string> prefix;
483 std::ostringstream os;
484 os << *prefix <<
"Start" << endl;
485 std::cerr << os.str ();
487 this->beginTransfer(source, exporter, modeString, DoReverse, CM, restrictedMode);
489 std::ostringstream os;
490 os << *prefix <<
"Done" << endl;
491 std::cerr << os.str ();
495 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
497 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
498 beginExport(
const SrcDistObject& source,
499 const Import<LocalOrdinal, GlobalOrdinal, Node> & importer,
501 const bool restrictedMode)
503 using Details::Behavior;
505 const char modeString[] =
"beginExport (reverse mode)";
510 const bool verbose = Behavior::verbose(
"DistObject");
511 std::unique_ptr<std::string> prefix;
514 std::ostringstream os;
515 os << *prefix <<
"Start" << endl;
516 std::cerr << os.str ();
518 this->beginTransfer(source, importer, modeString, DoReverse, CM, restrictedMode);
520 std::ostringstream os;
521 os << *prefix <<
"Done" << endl;
522 std::cerr << os.str ();
526 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
528 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
529 endImport(
const SrcDistObject& source,
530 const Import<LocalOrdinal, GlobalOrdinal, Node>& importer,
532 const bool restrictedMode)
534 using Details::Behavior;
536 const char modeString[] =
"endImport (forward mode)";
541 const bool verbose = Behavior::verbose(
"DistObject");
542 std::unique_ptr<std::string> prefix;
545 std::ostringstream os;
546 os << *prefix <<
"Start" << endl;
547 std::cerr << os.str ();
549 this->endTransfer(source, importer, modeString, DoForward, CM, restrictedMode);
551 std::ostringstream os;
552 os << *prefix <<
"Done" << endl;
553 std::cerr << os.str ();
557 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
559 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
560 endExport(
const SrcDistObject& source,
561 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
563 const bool restrictedMode)
565 using Details::Behavior;
567 const char modeString[] =
"endExport (forward mode)";
572 const bool verbose = Behavior::verbose(
"DistObject");
573 std::unique_ptr<std::string> prefix;
576 std::ostringstream os;
577 os << *prefix <<
"Start" << endl;
578 std::cerr << os.str ();
580 this->endTransfer(source, exporter, modeString, DoForward, CM, restrictedMode);
582 std::ostringstream os;
583 os << *prefix <<
"Done" << endl;
584 std::cerr << os.str ();
588 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
590 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
591 endImport(
const SrcDistObject& source,
592 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
594 const bool restrictedMode)
596 using Details::Behavior;
598 const char modeString[] =
"endImport (reverse mode)";
603 const bool verbose = Behavior::verbose(
"DistObject");
604 std::unique_ptr<std::string> prefix;
607 std::ostringstream os;
608 os << *prefix <<
"Start" << endl;
609 std::cerr << os.str ();
611 this->endTransfer(source, exporter, modeString, DoReverse, CM, restrictedMode);
613 std::ostringstream os;
614 os << *prefix <<
"Done" << endl;
615 std::cerr << os.str ();
619 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
621 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
622 endExport(
const SrcDistObject& source,
623 const Import<LocalOrdinal, GlobalOrdinal, Node> & importer,
625 const bool restrictedMode)
627 using Details::Behavior;
629 const char modeString[] =
"endExport (reverse mode)";
634 const bool verbose = Behavior::verbose(
"DistObject");
635 std::unique_ptr<std::string> prefix;
638 std::ostringstream os;
639 os << *prefix <<
"Start" << endl;
640 std::cerr << os.str ();
642 this->endTransfer(source, importer, modeString, DoReverse, CM, restrictedMode);
644 std::ostringstream os;
645 os << *prefix <<
"Done" << endl;
646 std::cerr << os.str ();
650 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
654 return distributorActor_.isReady();
657 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
661 return map_->isDistributed ();
664 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
671 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
675 const ::Tpetra::Details::Transfer<local_ordinal_type, global_ordinal_type, node_type>& transfer,
676 const char modeString[],
681 beginTransfer(src, transfer, modeString, revOp, CM, restrictedMode);
682 endTransfer(src, transfer, modeString, revOp, CM, restrictedMode);
685 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
690 const std::string* prefix,
695 std::ostringstream os;
696 os << *prefix <<
"Realloc (if needed) imports_ from "
697 << imports_.extent (0) <<
" to " << newSize << std::endl;
698 std::cerr << os.str ();
701 const bool reallocated =
704 std::ostringstream os;
705 os << *prefix <<
"Finished realloc'ing imports_" << std::endl;
706 std::cerr << os.str ();
711 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
715 const size_t numImportLIDs)
725 constexpr
size_t tooBigFactor = 10;
727 const bool verbose = Behavior::verbose(
"DistObject");
728 std::unique_ptr<std::string> prefix;
730 prefix = this->createPrefix(
"DistObject",
731 "reallocArraysForNumPacketsPerLid");
732 std::ostringstream os;
734 <<
"numExportLIDs: " << numExportLIDs
735 <<
", numImportLIDs: " << numImportLIDs
737 os << *prefix <<
"DualView status before:" << endl
740 "numExportPacketsPerLID_")
744 "numImportPacketsPerLID_")
746 std::cerr << os.str ();
750 const bool firstReallocated =
753 "numExportPacketsPerLID",
760 const bool needFenceBeforeNextAlloc = ! firstReallocated;
761 const bool secondReallocated =
764 "numImportPacketsPerLID",
766 needFenceBeforeNextAlloc);
769 std::ostringstream os;
770 os << *prefix <<
"DualView status after:" << endl
772 "numExportPacketsPerLID_")
775 "numImportPacketsPerLID_")
777 std::cerr << os.str ();
780 return firstReallocated || secondReallocated;
783 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
787 const ::Tpetra::Details::Transfer<local_ordinal_type, global_ordinal_type, node_type>& transfer,
788 const char modeString[],
797 using Kokkos::Compat::getArrayView;
798 using Kokkos::Compat::getConstArrayView;
799 using Kokkos::Compat::getKokkosViewDeepCopy;
800 using Kokkos::Compat::create_const_view;
805 const bool commOnHost = ! Behavior::assumeMpiIsGPUAware ();
806 const char funcNameHost[] =
"Tpetra::DistObject::beginTransfer[Host]";
807 const char funcNameDevice[] =
"Tpetra::DistObject::beginTransfer[Device]";
808 const char *funcName = commOnHost ? funcNameHost : funcNameDevice;
810 ProfilingRegion region_doTransfer(funcName);
811 const bool verbose = Behavior::verbose(
"DistObject");
812 std::shared_ptr<std::string> prefix;
814 std::ostringstream os;
815 prefix = this->createPrefix(
"DistObject",
"doTransfer");
816 os << *prefix <<
"Source type: " << Teuchos::typeName(src)
817 <<
", Target type: " << Teuchos::typeName(*
this) << endl;
818 std::cerr << os.str();
831 const bool debug = Behavior::debug(
"DistObject");
833 if (! restrictedMode && revOp == DoForward) {
834 const bool myMapSameAsTransferTgtMap =
835 this->getMap ()->isSameAs (* (transfer.getTargetMap ()));
836 TEUCHOS_TEST_FOR_EXCEPTION
837 (! myMapSameAsTransferTgtMap, std::invalid_argument,
838 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
839 "communication, the target DistObject's Map must be the same "
840 "(in the sense of Tpetra::Map::isSameAs) as the input "
841 "Export/Import object's target Map.");
843 else if (! restrictedMode && revOp == DoReverse) {
844 const bool myMapSameAsTransferSrcMap =
845 this->getMap ()->isSameAs (* (transfer.getSourceMap ()));
846 TEUCHOS_TEST_FOR_EXCEPTION
847 (! myMapSameAsTransferSrcMap, std::invalid_argument,
848 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
849 "communication, the target DistObject's Map must be the same "
850 "(in the sense of Tpetra::Map::isSameAs) as the input "
851 "Export/Import object's source Map.");
853 else if (restrictedMode && revOp == DoForward) {
854 const bool myMapLocallyFittedTransferTgtMap =
855 this->getMap ()->isLocallyFitted (* (transfer.getTargetMap ()));
856 TEUCHOS_TEST_FOR_EXCEPTION
857 (! myMapLocallyFittedTransferTgtMap , std::invalid_argument,
858 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
859 "communication using restricted mode, Export/Import object's "
860 "target Map must be locally fitted (in the sense of "
861 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
864 const bool myMapLocallyFittedTransferSrcMap =
865 this->getMap ()->isLocallyFitted (* (transfer.getSourceMap ()));
866 TEUCHOS_TEST_FOR_EXCEPTION
867 (! myMapLocallyFittedTransferSrcMap, std::invalid_argument,
868 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
869 "communication using restricted mode, Export/Import object's "
870 "source Map must be locally fitted (in the sense of "
871 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
878 if (srcDistObj !=
nullptr) {
879 if (revOp == DoForward) {
880 const bool srcMapSameAsImportSrcMap =
881 srcDistObj->
getMap ()->isSameAs (* (transfer.getSourceMap ()));
882 TEUCHOS_TEST_FOR_EXCEPTION
883 (! srcMapSameAsImportSrcMap, std::invalid_argument,
884 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
885 "communication, the source DistObject's Map must be the same "
886 "as the input Export/Import object's source Map.");
889 const bool srcMapSameAsImportTgtMap =
890 srcDistObj->
getMap ()->isSameAs (* (transfer.getTargetMap ()));
891 TEUCHOS_TEST_FOR_EXCEPTION
892 (! srcMapSameAsImportTgtMap, std::invalid_argument,
893 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
894 "communication, the source DistObject's Map must be the same "
895 "as the input Export/Import object's target Map.");
900 const size_t numSameIDs = transfer.getNumSameIDs ();
904 TEUCHOS_TEST_FOR_EXCEPTION
905 (debug && restrictedMode &&
906 (transfer.getPermuteToLIDs_dv().extent(0) != 0 ||
907 transfer.getPermuteFromLIDs_dv().extent(0) != 0),
908 std::invalid_argument,
909 "Tpetra::DistObject::" << modeString <<
": Transfer object "
910 "cannot have permutes in restricted mode.");
914 std::ostringstream os;
915 os << *prefix <<
"doTransfer: Use new interface; "
916 "commOnHost=" << (commOnHost ?
"true" :
"false") << endl;
917 std::cerr << os.str ();
920 using const_lo_dv_type =
921 Kokkos::DualView<const local_ordinal_type*, buffer_device_type>;
922 const_lo_dv_type permuteToLIDs = (revOp == DoForward) ?
923 transfer.getPermuteToLIDs_dv () :
924 transfer.getPermuteFromLIDs_dv ();
925 const_lo_dv_type permuteFromLIDs = (revOp == DoForward) ?
926 transfer.getPermuteFromLIDs_dv () :
927 transfer.getPermuteToLIDs_dv ();
928 const_lo_dv_type remoteLIDs = (revOp == DoForward) ?
929 transfer.getRemoteLIDs_dv () :
930 transfer.getExportLIDs_dv ();
931 const_lo_dv_type exportLIDs = (revOp == DoForward) ?
932 transfer.getExportLIDs_dv () :
933 transfer.getRemoteLIDs_dv ();
934 const bool canTryAliasing = (revOp == DoForward) ?
935 transfer.areRemoteLIDsContiguous() :
936 transfer.areExportLIDsContiguous();
939 ProfilingRegion region_dTN(funcName);
940 #ifdef HAVE_TPETRA_TRANSFER_TIMERS
943 Teuchos::TimeMonitor doXferMon (*doXferTimer_);
944 #endif // HAVE_TPETRA_TRANSFER_TIMERS
947 std::ostringstream os;
948 os << *prefix <<
"Input arguments:" << endl
950 << *prefix <<
" numSameIDs: " << numSameIDs << endl
959 << *prefix <<
" revOp: Do" << (revOp == DoReverse ?
"Reverse" :
"Forward") << endl
960 << *prefix <<
" commOnHost: " << (commOnHost ?
"true" :
"false") << endl;
961 std::cerr << os.str ();
965 ProfilingRegion region_cs (
"Tpetra::DistObject::doTransferNew::checkSizes");
967 std::ostringstream os;
968 os << *prefix <<
"1. checkSizes" << endl;
969 std::cerr << os.str ();
971 const bool checkSizesResult = this->checkSizes (src);
972 TEUCHOS_TEST_FOR_EXCEPTION
973 (! checkSizesResult, std::invalid_argument,
974 "Tpetra::DistObject::doTransfer: checkSizes() indicates that the "
975 "destination object is not a legal target for redistribution from the "
976 "source object. This probably means that they do not have the same "
977 "dimensions. For example, MultiVectors must have the same number of "
978 "rows and columns.");
985 if (!restrictedMode && numSameIDs + permuteToLIDs.extent (0) != 0) {
988 std::ostringstream os;
989 os << *prefix <<
"2. copyAndPermute" << endl;
990 std::cerr << os.str ();
992 ProfilingRegion region_cp
993 (
"Tpetra::DistObject::doTransferNew::copyAndPermute");
994 #ifdef HAVE_TPETRA_TRANSFER_TIMERS
997 Teuchos::TimeMonitor copyAndPermuteMon (*copyAndPermuteTimer_);
998 #endif // HAVE_TPETRA_TRANSFER_TIMERS
1000 if (numSameIDs + permuteToLIDs.extent (0) != 0) {
1003 std::ostringstream os;
1004 os << *prefix <<
"2. copyAndPermute" << endl;
1005 std::cerr << os.str ();
1007 this->copyAndPermute (src, numSameIDs, permuteToLIDs,
1008 permuteFromLIDs, CM);
1010 std::ostringstream os;
1011 os << *prefix <<
"After copyAndPermute:" << endl
1018 std::cerr << os.str ();
1031 size_t constantNumPackets = this->constantNumberOfPackets ();
1033 std::ostringstream os;
1034 os << *prefix <<
"constantNumPackets=" << constantNumPackets << endl;
1035 std::cerr << os.str ();
1043 if (constantNumPackets == 0) {
1045 std::ostringstream os;
1046 os << *prefix <<
"3. (Re)allocate num{Ex,Im}portPacketsPerLID"
1048 std::cerr << os.str ();
1052 this->reallocArraysForNumPacketsPerLid (exportLIDs.extent (0),
1053 remoteLIDs.extent (0));
1057 std::ostringstream os;
1058 os << *prefix <<
"4. packAndPrepare: before, "
1061 std::cerr << os.str ();
1064 doPackAndPrepare(src, exportLIDs, constantNumPackets,
execution_space());
1066 this->exports_.sync_host();
1069 this->exports_.sync_device();
1073 std::ostringstream os;
1074 os << *prefix <<
"5.1. After packAndPrepare, "
1077 std::cerr << os.str ();
1083 if (constantNumPackets != 0) {
1088 const size_t rbufLen = remoteLIDs.extent (0) * constantNumPackets;
1089 reallocImportsIfNeeded (rbufLen, verbose, prefix.get (), canTryAliasing, CM);
1093 bool needCommunication =
true;
1098 if (revOp == DoReverse && ! this->isDistributed ()) {
1099 needCommunication =
false;
1108 else if (revOp == DoForward && srcDistObj != NULL &&
1110 needCommunication =
false;
1113 if (! needCommunication) {
1115 std::ostringstream os;
1116 os << *prefix <<
"Comm not needed; skipping" << endl;
1117 std::cerr << os.str ();
1121 ProfilingRegion region_dpw
1122 (
"Tpetra::DistObject::doTransferNew::doPostsAndWaits");
1123 #ifdef HAVE_TPETRA_TRANSFER_TIMERS
1126 Teuchos::TimeMonitor doPostsAndWaitsMon (*doPostsAndWaitsTimer_);
1127 #endif // HAVE_TPETRA_TRANSFER_TIMERS
1130 std::ostringstream os;
1131 os << *prefix <<
"7.0. "
1132 << (revOp == DoReverse ?
"Reverse" :
"Forward")
1134 std::cerr << os.str ();
1137 doPosts(distributorPlan, constantNumPackets, commOnHost, prefix, canTryAliasing, CM);
1142 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1146 const ::Tpetra::Details::Transfer<local_ordinal_type, global_ordinal_type, node_type>& transfer,
1147 const char modeString[],
1148 const ReverseOption revOp,
1150 bool restrictedMode)
1156 using Kokkos::Compat::getArrayView;
1157 using Kokkos::Compat::getConstArrayView;
1158 using Kokkos::Compat::getKokkosViewDeepCopy;
1159 using Kokkos::Compat::create_const_view;
1164 const bool commOnHost = ! Behavior::assumeMpiIsGPUAware ();
1165 const char funcNameHost[] =
"Tpetra::DistObject::endTransfer[Host]";
1166 const char funcNameDevice[] =
"Tpetra::DistObject::endTransfer[Device]";
1167 const char *funcName = commOnHost ? funcNameHost : funcNameDevice;
1168 ProfilingRegion region_doTransfer(funcName);
1169 const bool verbose = Behavior::verbose(
"DistObject");
1170 std::shared_ptr<std::string> prefix;
1172 std::ostringstream os;
1173 prefix = this->createPrefix(
"DistObject",
"doTransfer");
1174 os << *prefix <<
"Source type: " << Teuchos::typeName(src)
1175 <<
", Target type: " << Teuchos::typeName(*
this) << endl;
1176 std::cerr << os.str();
1189 const bool debug = Behavior::debug(
"DistObject");
1191 if (! restrictedMode && revOp == DoForward) {
1192 const bool myMapSameAsTransferTgtMap =
1193 this->getMap ()->isSameAs (* (transfer.getTargetMap ()));
1194 TEUCHOS_TEST_FOR_EXCEPTION
1195 (! myMapSameAsTransferTgtMap, std::invalid_argument,
1196 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
1197 "communication, the target DistObject's Map must be the same "
1198 "(in the sense of Tpetra::Map::isSameAs) as the input "
1199 "Export/Import object's target Map.");
1201 else if (! restrictedMode && revOp == DoReverse) {
1202 const bool myMapSameAsTransferSrcMap =
1203 this->getMap ()->isSameAs (* (transfer.getSourceMap ()));
1204 TEUCHOS_TEST_FOR_EXCEPTION
1205 (! myMapSameAsTransferSrcMap, std::invalid_argument,
1206 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
1207 "communication, the target DistObject's Map must be the same "
1208 "(in the sense of Tpetra::Map::isSameAs) as the input "
1209 "Export/Import object's source Map.");
1211 else if (restrictedMode && revOp == DoForward) {
1212 const bool myMapLocallyFittedTransferTgtMap =
1213 this->getMap ()->isLocallyFitted (* (transfer.getTargetMap ()));
1214 TEUCHOS_TEST_FOR_EXCEPTION
1215 (! myMapLocallyFittedTransferTgtMap , std::invalid_argument,
1216 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
1217 "communication using restricted mode, Export/Import object's "
1218 "target Map must be locally fitted (in the sense of "
1219 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
1222 const bool myMapLocallyFittedTransferSrcMap =
1223 this->getMap ()->isLocallyFitted (* (transfer.getSourceMap ()));
1224 TEUCHOS_TEST_FOR_EXCEPTION
1225 (! myMapLocallyFittedTransferSrcMap, std::invalid_argument,
1226 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
1227 "communication using restricted mode, Export/Import object's "
1228 "source Map must be locally fitted (in the sense of "
1229 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
1235 const this_type* srcDistObj =
dynamic_cast<const this_type*
> (&src);
1236 if (srcDistObj !=
nullptr) {
1237 if (revOp == DoForward) {
1238 const bool srcMapSameAsImportSrcMap =
1239 srcDistObj->getMap ()->isSameAs (* (transfer.getSourceMap ()));
1240 TEUCHOS_TEST_FOR_EXCEPTION
1241 (! srcMapSameAsImportSrcMap, std::invalid_argument,
1242 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
1243 "communication, the source DistObject's Map must be the same "
1244 "as the input Export/Import object's source Map.");
1247 const bool srcMapSameAsImportTgtMap =
1248 srcDistObj->getMap ()->isSameAs (* (transfer.getTargetMap ()));
1249 TEUCHOS_TEST_FOR_EXCEPTION
1250 (! srcMapSameAsImportTgtMap, std::invalid_argument,
1251 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
1252 "communication, the source DistObject's Map must be the same "
1253 "as the input Export/Import object's target Map.");
1258 Distributor& distor = transfer.getDistributor ();
1259 const Details::DistributorPlan& distributorPlan = (revOp == DoForward) ? distor.getPlan() : *distor.getPlan().getReversePlan();
1261 TEUCHOS_TEST_FOR_EXCEPTION
1262 (debug && restrictedMode &&
1263 (transfer.getPermuteToLIDs_dv().extent(0) != 0 ||
1264 transfer.getPermuteFromLIDs_dv().extent(0) != 0),
1265 std::invalid_argument,
1266 "Tpetra::DistObject::" << modeString <<
": Transfer object "
1267 "cannot have permutes in restricted mode.");
1271 std::ostringstream os;
1272 os << *prefix <<
"doTransfer: Use new interface; "
1273 "commOnHost=" << (commOnHost ?
"true" :
"false") << endl;
1274 std::cerr << os.str ();
1277 using const_lo_dv_type =
1278 Kokkos::DualView<const local_ordinal_type*, buffer_device_type>;
1279 const_lo_dv_type permuteToLIDs = (revOp == DoForward) ?
1280 transfer.getPermuteToLIDs_dv () :
1281 transfer.getPermuteFromLIDs_dv ();
1282 const_lo_dv_type permuteFromLIDs = (revOp == DoForward) ?
1283 transfer.getPermuteFromLIDs_dv () :
1284 transfer.getPermuteToLIDs_dv ();
1285 const_lo_dv_type remoteLIDs = (revOp == DoForward) ?
1286 transfer.getRemoteLIDs_dv () :
1287 transfer.getExportLIDs_dv ();
1288 const_lo_dv_type exportLIDs = (revOp == DoForward) ?
1289 transfer.getExportLIDs_dv () :
1290 transfer.getRemoteLIDs_dv ();
1291 const bool canTryAliasing = (revOp == DoForward) ?
1292 transfer.areRemoteLIDsContiguous() :
1293 transfer.areExportLIDsContiguous();
1295 size_t constantNumPackets = this->constantNumberOfPackets ();
1299 if (constantNumPackets != 0) {
1304 const size_t rbufLen = remoteLIDs.extent (0) * constantNumPackets;
1305 reallocImportsIfNeeded (rbufLen, verbose, prefix.get (), canTryAliasing, CM);
1309 bool needCommunication =
true;
1312 const this_type* srcDistObj =
dynamic_cast<const this_type*
> (&src);
1314 if (revOp == DoReverse && ! this->isDistributed ()) {
1315 needCommunication =
false;
1324 else if (revOp == DoForward && srcDistObj != NULL &&
1325 ! srcDistObj->isDistributed ()) {
1326 needCommunication =
false;
1329 if (! needCommunication) {
1331 std::ostringstream os;
1332 os << *prefix <<
"Comm not needed; skipping" << endl;
1333 std::cerr << os.str ();
1337 distributorActor_.doWaits(distributorPlan);
1340 std::ostringstream os;
1341 os << *prefix <<
"8. unpackAndCombine - remoteLIDs " << remoteLIDs.extent(0) <<
", constantNumPackets " << constantNumPackets << endl;
1342 std::cerr << os.str ();
1344 doUnpackAndCombine(remoteLIDs, constantNumPackets, CM, execution_space());
1349 std::ostringstream os;
1350 os << *prefix <<
"9. Done!" << endl;
1351 std::cerr << os.str ();
1355 std::ostringstream os;
1356 os << *prefix <<
"Tpetra::DistObject::doTransfer: Done!" << endl;
1357 std::cerr << os.str ();
1361 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1363 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1364 doPosts(
const Details::DistributorPlan& distributorPlan,
1365 size_t constantNumPackets,
1367 std::shared_ptr<std::string> prefix,
1368 const bool canTryAliasing,
1373 using Kokkos::Compat::create_const_view;
1378 if (constantNumPackets == 0) {
1380 std::ostringstream os;
1381 os << *prefix <<
"7.1. Variable # packets / LID: first comm "
1382 <<
"(commOnHost = " << (commOnHost ?
"true" :
"false") <<
")"
1384 std::cerr << os.str ();
1386 size_t totalImportPackets = 0;
1388 if (this->numExportPacketsPerLID_.need_sync_host ()) {
1389 this->numExportPacketsPerLID_.sync_host ();
1391 if (this->numImportPacketsPerLID_.need_sync_host ()) {
1392 this->numImportPacketsPerLID_.sync_host ();
1394 this->numImportPacketsPerLID_.modify_host ();
1396 create_const_view (this->numExportPacketsPerLID_.view_host ());
1397 auto numImp_h = this->numImportPacketsPerLID_.view_host ();
1401 std::ostringstream os;
1402 os << *prefix <<
"Call doPostsAndWaits"
1404 std::cerr << os.str ();
1406 distributorActor_.doPostsAndWaits(distributorPlan, numExp_h, 1, numImp_h);
1409 std::ostringstream os;
1410 os << *prefix <<
"Count totalImportPackets" << std::endl;
1411 std::cerr << os.str ();
1413 using the_dev_type =
typename decltype (numImp_h)::device_type;
1414 totalImportPackets = countTotalImportPackets<the_dev_type> (numImp_h);
1417 this->numExportPacketsPerLID_.sync_device ();
1418 this->numImportPacketsPerLID_.sync_device ();
1419 this->numImportPacketsPerLID_.modify_device ();
1420 auto numExp_d = create_const_view
1421 (this->numExportPacketsPerLID_.view_device ());
1422 auto numImp_d = this->numImportPacketsPerLID_.view_device ();
1426 std::ostringstream os;
1427 os << *prefix <<
"Call doPostsAndWaits"
1429 std::cerr << os.str ();
1432 distributorActor_.doPostsAndWaits(distributorPlan, numExp_d, 1, numImp_d);
1435 std::ostringstream os;
1436 os << *prefix <<
"Count totalImportPackets" << std::endl;
1437 std::cerr << os.str ();
1439 using the_dev_type =
typename decltype (numImp_d)::device_type;
1440 totalImportPackets = countTotalImportPackets<the_dev_type> (numImp_d);
1444 std::ostringstream os;
1445 os << *prefix <<
"totalImportPackets=" << totalImportPackets << endl;
1446 std::cerr << os.str ();
1448 this->reallocImportsIfNeeded (totalImportPackets, verbose,
1449 prefix.get (), canTryAliasing, CM);
1451 std::ostringstream os;
1452 os << *prefix <<
"7.3. Second comm" << std::endl;
1453 std::cerr << os.str ();
1459 this->numExportPacketsPerLID_.sync_host ();
1460 this->numImportPacketsPerLID_.sync_host ();
1469 auto numExportPacketsPerLID_av =
1471 auto numImportPacketsPerLID_av =
1479 this->imports_.clear_sync_state ();
1482 std::ostringstream os;
1483 os << *prefix <<
"Comm on "
1484 << (commOnHost ?
"host" :
"device")
1485 <<
"; call doPosts" << endl;
1486 std::cerr << os.str ();
1490 this->imports_.modify_host ();
1491 distributorActor_.doPosts
1493 create_const_view (this->exports_.view_host ()),
1494 numExportPacketsPerLID_av,
1495 this->imports_.view_host (),
1496 numImportPacketsPerLID_av);
1499 Kokkos::fence(
"DistObject::doPosts-1");
1500 this->imports_.modify_device ();
1501 distributorActor_.doPosts
1503 create_const_view (this->exports_.view_device ()),
1504 numExportPacketsPerLID_av,
1505 this->imports_.view_device (),
1506 numImportPacketsPerLID_av);
1511 std::ostringstream os;
1512 os << *prefix <<
"7.1. Const # packets per LID: " << endl
1519 std::cerr << os.str ();
1526 this->imports_.clear_sync_state ();
1529 std::ostringstream os;
1530 os << *prefix <<
"7.2. Comm on "
1531 << (commOnHost ?
"host" :
"device")
1532 <<
"; call doPosts" << endl;
1533 std::cerr << os.str ();
1536 this->imports_.modify_host ();
1537 distributorActor_.doPosts
1539 create_const_view (this->exports_.view_host ()),
1541 this->imports_.view_host ());
1544 Kokkos::fence(
"DistObject::doPosts-2");
1545 this->imports_.modify_device ();
1546 distributorActor_.doPosts
1548 create_const_view (this->exports_.view_device ()),
1550 this->imports_.view_device ());
1555 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1557 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1558 doPackAndPrepare(
const SrcDistObject& src,
1559 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& exportLIDs,
1560 size_t& constantNumPackets,
1561 const execution_space &space)
1563 using Details::ProfilingRegion;
1567 ProfilingRegion region_pp
1568 (
"Tpetra::DistObject::doPackAndPrepare");
1569 #ifdef HAVE_TPETRA_TRANSFER_TIMERS
1572 Teuchos::TimeMonitor packAndPrepareMon (*packAndPrepareTimer_);
1573 #endif // HAVE_TPETRA_TRANSFER_TIMERS
1592 std::ostringstream lclErrStrm;
1593 bool lclSuccess =
false;
1595 this->packAndPrepare (src, exportLIDs, this->exports_,
1596 this->numExportPacketsPerLID_,
1597 constantNumPackets, space);
1600 catch (std::exception& e) {
1601 lclErrStrm <<
"packAndPrepare threw an exception: "
1602 << endl << e.what();
1605 lclErrStrm <<
"packAndPrepare threw an exception "
1606 "not a subclass of std::exception.";
1608 const char gblErrMsgHeader[] =
"Tpetra::DistObject "
1609 "threw an exception in packAndPrepare on "
1610 "one or more processes in the DistObject's communicator.";
1611 auto comm = getMap()->getComm();
1612 Details::checkGlobalError(std::cerr, lclSuccess,
1613 lclErrStrm.str().c_str(),
1614 gblErrMsgHeader, *comm);
1617 this->packAndPrepare (src, exportLIDs, this->exports_,
1618 this->numExportPacketsPerLID_,
1619 constantNumPackets, space);
1623 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1625 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1626 doUnpackAndCombine(
const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& remoteLIDs,
1627 size_t constantNumPackets,
1629 const execution_space &space)
1631 using Details::ProfilingRegion;
1635 ProfilingRegion region_uc
1636 (
"Tpetra::DistObject::doUnpackAndCombine");
1637 #ifdef HAVE_TPETRA_TRANSFER_TIMERS
1640 Teuchos::TimeMonitor unpackAndCombineMon (*unpackAndCombineTimer_);
1641 #endif // HAVE_TPETRA_TRANSFER_TIMERS
1644 std::ostringstream lclErrStrm;
1645 bool lclSuccess =
false;
1647 this->unpackAndCombine (remoteLIDs, this->imports_,
1648 this->numImportPacketsPerLID_,
1649 constantNumPackets, CM, space);
1652 catch (std::exception& e) {
1653 lclErrStrm <<
"doUnpackAndCombine threw an exception: "
1654 << endl << e.what();
1657 lclErrStrm <<
"doUnpackAndCombine threw an exception "
1658 "not a subclass of std::exception.";
1660 const char gblErrMsgHeader[] =
"Tpetra::DistObject "
1661 "threw an exception in unpackAndCombine on "
1662 "one or more processes in the DistObject's communicator.";
1663 auto comm = getMap()->getComm();
1664 Details::checkGlobalError(std::cerr, lclSuccess,
1665 lclErrStrm.str().c_str(),
1666 gblErrMsgHeader, *comm);
1669 this->unpackAndCombine (remoteLIDs, this->imports_,
1670 this->numImportPacketsPerLID_,
1671 constantNumPackets, CM, space);
1675 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1681 const Kokkos::DualView<
1684 const Kokkos::DualView<
1691 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1694 const Kokkos::DualView<const local_ordinal_type *, buffer_device_type>
1696 const Kokkos::DualView<const local_ordinal_type *, buffer_device_type>
1710 copyAndPermute(source, numSameIDs, permuteToLIDs, permuteFromLIDs,
1718 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1723 const Kokkos::DualView<
1736 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1739 const Kokkos::DualView<const local_ordinal_type *, buffer_device_type>
1741 Kokkos::DualView<packet_type *, buffer_device_type> &exports,
1742 Kokkos::DualView<size_t *, buffer_device_type> numPacketsPerLID,
1760 packAndPrepare(source, exportLIDs, exports, numPacketsPerLID,
1761 constantNumPackets);
1769 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1773 (
const Kokkos::DualView<
1787 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1789 const Kokkos::DualView<const local_ordinal_type *, buffer_device_type>
1791 Kokkos::DualView<packet_type *, buffer_device_type> imports,
1792 Kokkos::DualView<size_t *, buffer_device_type> numPacketsPerLID,
1793 const size_t constantNumPackets,
const CombineMode combineMode,
1794 const execution_space &space) {
1798 unpackAndCombine(importLIDs, imports, numPacketsPerLID, constantNumPackets,
1802 execution_space().fence();
1807 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1809 std::ostream &os)
const {
1811 using Teuchos::FancyOStream;
1812 using Teuchos::getFancyOStream;
1814 using Teuchos::rcpFromRef;
1816 RCP<FancyOStream> out = getFancyOStream(rcpFromRef(os));
1817 this->describe(*out, Teuchos::VERB_DEFAULT);
1820 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1821 std::unique_ptr<std::string>
1823 const char className[],
const char methodName[])
const {
1824 auto map = this->getMap();
1825 auto comm = map.is_null() ? Teuchos::null : map->getComm();
1829 template <
class DistObjectType>
1831 Teuchos::RCP<DistObjectType> &input,
1832 const Teuchos::RCP<
const Map<
typename DistObjectType::local_ordinal_type,
1833 typename DistObjectType::global_ordinal_type,
1834 typename DistObjectType::node_type>> &newMap) {
1835 input->removeEmptyProcessesInPlace(newMap);
1836 if (newMap.is_null()) {
1837 input = Teuchos::null;
1841 template <
class DistObjectType>
1843 auto newMap = input->getMap()->removeEmptyProcesses();
1844 removeEmptyProcessesInPlace<DistObjectType>(input, newMap);
1848 #define TPETRA_DISTOBJECT_INSTANT(SCALAR, LO, GO, NODE) \
1849 template class DistObject<SCALAR, LO, GO, NODE>;
1853 #define TPETRA_DISTOBJECT_INSTANT_CHAR(LO, GO, NODE) \
1854 template class DistObject<char, LO, GO, NODE>;
1858 #endif // TPETRA_DISTOBJECT_DEF_HPP
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
const Details::DistributorPlan & getPlan() const
Get this Distributor's DistributorPlan.
virtual void copyAndPermute(const SrcDistObject &source, 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)
Perform copies and permutations that are local to the calling (MPI) process.
Declaration of Tpetra::Details::Profiling, a scope guard for Kokkos Profiling.
void doImport(const SrcDistObject &source, const Import< LocalOrdinal, GlobalOrdinal, Node > &importer, const CombineMode CM, const bool restrictedMode=false)
Import data into this object using an Import object ("forward mode").
typename::Kokkos::ArithTraits< Packet >::val_type packet_type
The type of each datum being sent or received in an Import or Export.
void print(std::ostream &os) const
Print this object to the given output stream.
virtual bool reallocArraysForNumPacketsPerLid(const size_t numExportLIDs, const size_t numImportLIDs)
Reallocate numExportPacketsPerLID_ and/or numImportPacketsPerLID_, if necessary.
bool isDistributed() const
Whether this is a globally distributed object.
void removeEmptyProcessesInPlace(Teuchos::RCP< DistObjectType > &input, const Teuchos::RCP< const Map< typename DistObjectType::local_ordinal_type, typename DistObjectType::global_ordinal_type, typename DistObjectType::node_type > > &newMap)
Remove processes which contain no elements in this object's Map.
virtual void unpackAndCombine(const Kokkos::DualView< const local_ordinal_type *, buffer_device_type > &importLIDs, Kokkos::DualView< packet_type *, buffer_device_type > imports, Kokkos::DualView< size_t *, buffer_device_type > numPacketsPerLID, const size_t constantNumPackets, const CombineMode combineMode)
Perform any unpacking and combining after communication.
static bool debug()
Whether Tpetra is in debug mode.
virtual void doTransfer(const SrcDistObject &src, const ::Tpetra::Details::Transfer< local_ordinal_type, global_ordinal_type, node_type > &transfer, const char modeString[], const ReverseOption revOp, const CombineMode CM, const bool restrictedMode)
Redistribute data across (MPI) processes.
void beginTransfer(const SrcDistObject &src, const ::Tpetra::Details::Transfer< local_ordinal_type, global_ordinal_type, node_type > &transfer, const char modeString[], const ReverseOption revOp, const CombineMode CM, const bool restrictedMode)
Implementation detail of doTransfer.
typename device_type::execution_space execution_space
The Kokkos execution space.
Kokkos::DualView< T *, DT > getDualViewCopyFromArrayView(const Teuchos::ArrayView< const T > &x_av, const char label[], const bool leaveOnHost)
Get a 1-D Kokkos::DualView which is a deep copy of the input Teuchos::ArrayView (which views host mem...
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
virtual void packAndPrepare(const SrcDistObject &source, const Kokkos::DualView< const local_ordinal_type *, buffer_device_type > &exportLIDs, Kokkos::DualView< packet_type *, buffer_device_type > &exports, Kokkos::DualView< size_t *, buffer_device_type > numPacketsPerLID, size_t &constantNumPackets)
Pack data and metadata for communication (sends).
Sets up and executes a communication plan for a Tpetra DistObject.
static bool verbose()
Whether Tpetra is in verbose mode.
CombineMode
Rule for combining data in an Import or Export.
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.
Abstract base class for objects that can be the source of an Import or Export operation.
Declaration and definition of Tpetra::Details::reallocDualViewIfNeeded, an implementation detail of T...
LocalOrdinal local_ordinal_type
The type of local indices.
Replace old values with zero.
std::string combineModeToString(const CombineMode combineMode)
Human-readable string representation of the given CombineMode.
ReverseOption
Whether the data transfer should be performed in forward or reverse mode.
DistObject(const Teuchos::RCP< const map_type > &map)
Constructor.
std::string dualViewStatusToString(const DualViewType &dv, const char name[])
Return the status of the given Kokkos::DualView, as a human-readable string.
virtual std::string description() const
One-line descriptiion of this object.
bool transferArrived() const
Whether the data from an import/export operation has arrived, and is ready for the unpack and combine...
virtual size_t constantNumberOfPackets() const
Whether the implementation's instance promises always to have a constant number of packets per LID (l...
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.
void doExport(const SrcDistObject &source, const Export< LocalOrdinal, GlobalOrdinal, Node > &exporter, const CombineMode CM, const bool restrictedMode=false)
Export data into this object using an Export object ("forward mode").
Teuchos::ArrayView< typename DualViewType::t_dev::value_type > getArrayViewFromDualView(const DualViewType &x)
Get a Teuchos::ArrayView which views the host Kokkos::View of the input 1-D Kokkos::DualView.
Stand-alone utility functions and macros.
virtual Teuchos::RCP< const map_type > getMap() const
The Map describing the parallel distribution of this object.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print a descriptiion of this object to the given output stream.
Kokkos::Device< typename device_type::execution_space, buffer_memory_space > buffer_device_type
Kokkos::Device specialization for communication buffers.
Base class for distributed Tpetra objects that support data redistribution.
std::unique_ptr< std::string > createPrefix(const int myRank, const char prefix[])
Create string prefix for each line of verbose output.
virtual void removeEmptyProcessesInPlace(const Teuchos::RCP< const map_type > &newMap)
Remove processes which contain no entries in this object's Map.
Description of Tpetra's behavior.
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.