40#ifndef TPETRA_DISTOBJECT_DEF_HPP
41#define TPETRA_DISTOBJECT_DEF_HPP
51#include "Tpetra_Distributor.hpp"
54#include "Tpetra_Details_checkGlobalError.hpp"
57#include "Teuchos_CommHelpers.hpp"
58#include "Teuchos_TypeNameTraits.hpp"
66 template<
class DeviceType,
class IndexType =
size_t>
68 SumFunctor (
const Kokkos::View<const size_t*, DeviceType>& viewToSum) :
69 viewToSum_ (viewToSum) {}
70 KOKKOS_INLINE_FUNCTION
void operator() (
const IndexType i,
size_t& lclSum)
const {
71 lclSum += viewToSum_(i);
73 Kokkos::View<const size_t*, DeviceType> viewToSum_;
76 template<
class DeviceType,
class IndexType =
size_t>
78 countTotalImportPackets (
const Kokkos::View<const size_t*, DeviceType>& numImportPacketsPerLID)
80 using Kokkos::parallel_reduce;
81 typedef DeviceType DT;
82 typedef typename DT::execution_space DES;
83 typedef Kokkos::RangePolicy<DES, IndexType> range_type;
85 const IndexType numOut = numImportPacketsPerLID.extent (0);
86 size_t totalImportPackets = 0;
87 parallel_reduce (
"Count import packets",
88 range_type (0, numOut),
89 SumFunctor<DeviceType, IndexType> (numImportPacketsPerLID),
91 return totalImportPackets;
96 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
98 DistObject (
const Teuchos::RCP<const map_type>& map) :
101#ifdef HAVE_TPETRA_TRANSFER_TIMERS
104 using Teuchos::TimeMonitor;
106 RCP<Time> doXferTimer =
107 TimeMonitor::lookupCounter (
"Tpetra::DistObject::doTransfer");
108 if (doXferTimer.is_null ()) {
110 TimeMonitor::getNewCounter (
"Tpetra::DistObject::doTransfer");
112 doXferTimer_ = doXferTimer;
114 RCP<Time> copyAndPermuteTimer =
115 TimeMonitor::lookupCounter (
"Tpetra::DistObject::copyAndPermute");
116 if (copyAndPermuteTimer.is_null ()) {
117 copyAndPermuteTimer =
118 TimeMonitor::getNewCounter (
"Tpetra::DistObject::copyAndPermute");
120 copyAndPermuteTimer_ = copyAndPermuteTimer;
122 RCP<Time> packAndPrepareTimer =
123 TimeMonitor::lookupCounter (
"Tpetra::DistObject::packAndPrepare");
124 if (packAndPrepareTimer.is_null ()) {
125 packAndPrepareTimer =
126 TimeMonitor::getNewCounter (
"Tpetra::DistObject::packAndPrepare");
128 packAndPrepareTimer_ = packAndPrepareTimer;
130 RCP<Time> doPostsAndWaitsTimer =
131 TimeMonitor::lookupCounter (
"Tpetra::DistObject::doPostsAndWaits");
132 if (doPostsAndWaitsTimer.is_null ()) {
133 doPostsAndWaitsTimer =
134 TimeMonitor::getNewCounter (
"Tpetra::DistObject::doPostsAndWaits");
136 doPostsAndWaitsTimer_ = doPostsAndWaitsTimer;
138 RCP<Time> unpackAndCombineTimer =
139 TimeMonitor::lookupCounter (
"Tpetra::DistObject::unpackAndCombine");
140 if (unpackAndCombineTimer.is_null ()) {
141 unpackAndCombineTimer =
142 TimeMonitor::getNewCounter (
"Tpetra::DistObject::unpackAndCombine");
144 unpackAndCombineTimer_ = unpackAndCombineTimer;
148 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
153 using Teuchos::TypeNameTraits;
155 std::ostringstream os;
156 os <<
"\"Tpetra::DistObject\": {"
157 <<
"Packet: " << TypeNameTraits<packet_type>::name ()
158 <<
", LocalOrdinal: " << TypeNameTraits<local_ordinal_type>::name ()
159 <<
", GlobalOrdinal: " << TypeNameTraits<global_ordinal_type>::name ()
160 <<
", Node: " << TypeNameTraits<Node>::name ();
161 if (this->getObjectLabel () !=
"") {
162 os <<
"Label: \"" << this->getObjectLabel () <<
"\"";
168 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
171 describe (Teuchos::FancyOStream &out,
172 const Teuchos::EVerbosityLevel verbLevel)
const
174 using Teuchos::rcpFromRef;
175 using Teuchos::TypeNameTraits;
177 const Teuchos::EVerbosityLevel vl = (verbLevel == Teuchos::VERB_DEFAULT) ?
178 Teuchos::VERB_LOW : verbLevel;
179 Teuchos::RCP<const Teuchos::Comm<int> > comm = this->getMap ()->getComm ();
180 const int myRank = comm.is_null () ? 0 : comm->getRank ();
181 const int numProcs = comm.is_null () ? 1 : comm->getSize ();
183 if (vl != Teuchos::VERB_NONE) {
184 Teuchos::OSTab tab0 (out);
186 out <<
"\"Tpetra::DistObject\":" << endl;
188 Teuchos::OSTab tab1 (out);
190 out <<
"Template parameters:" << endl;
192 Teuchos::OSTab tab2 (out);
193 out <<
"Packet: " << TypeNameTraits<packet_type>::name () << endl
194 <<
"LocalOrdinal: " << TypeNameTraits<local_ordinal_type>::name () << endl
195 <<
"GlobalOrdinal: " << TypeNameTraits<global_ordinal_type>::name () << endl
196 <<
"Node: " << TypeNameTraits<node_type>::name () << endl;
198 if (this->getObjectLabel () !=
"") {
199 out <<
"Label: \"" << this->getObjectLabel () <<
"\"" << endl;
206 out <<
"Map:" << endl;
208 Teuchos::OSTab tab2 (out);
209 map_->describe (out, vl);
213 if (vl > Teuchos::VERB_LOW) {
214 for (
int p = 0; p < numProcs; ++p) {
216 out <<
"Process " << myRank <<
":" << endl;
217 Teuchos::OSTab tab2 (out);
218 out <<
"Export buffer size (in packets): "
219 << exports_.extent (0)
221 <<
"Import buffer size (in packets): "
222 << imports_.extent (0)
225 if (! comm.is_null ()) {
235 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
240 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
241 "Tpetra::DistObject::removeEmptyProcessesInPlace: Not implemented");
273 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
279 const bool restrictedMode)
283 const char modeString[] =
"doImport (forward mode)";
288 const bool verbose = Behavior::verbose(
"DistObject");
289 std::unique_ptr<std::string> prefix;
291 prefix = this->createPrefix(
"DistObject", modeString);
292 std::ostringstream os;
293 os << *prefix <<
"Start" << endl;
294 std::cerr << os.str ();
296 this->beginImport(source, importer, CM, restrictedMode);
297 this->endImport(source, importer, CM, restrictedMode);
299 std::ostringstream os;
300 os << *prefix <<
"Done" << endl;
301 std::cerr << os.str ();
305 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
311 const bool restrictedMode)
315 const char modeString[] =
"doExport (forward mode)";
320 const bool verbose = Behavior::verbose(
"DistObject");
321 std::unique_ptr<std::string> prefix;
323 prefix = this->createPrefix(
"DistObject", modeString);
324 std::ostringstream os;
325 os << *prefix <<
"Start" << endl;
326 std::cerr << os.str ();
328 this->beginExport(source, exporter, CM, restrictedMode);
329 this->endExport(source, exporter, CM, restrictedMode);
331 std::ostringstream os;
332 os << *prefix <<
"Done" << endl;
333 std::cerr << os.str ();
337 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
343 const bool restrictedMode)
347 const char modeString[] =
"doImport (reverse mode)";
352 const bool verbose = Behavior::verbose(
"DistObject");
353 std::unique_ptr<std::string> prefix;
355 prefix = this->createPrefix(
"DistObject", modeString);
356 std::ostringstream os;
357 os << *prefix <<
"Start" << endl;
358 std::cerr << os.str ();
360 this->beginImport(source, exporter, CM, restrictedMode);
361 this->endImport(source, exporter, CM, restrictedMode);
363 std::ostringstream os;
364 os << *prefix <<
"Done" << endl;
365 std::cerr << os.str ();
369 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
375 const bool restrictedMode)
379 const char modeString[] =
"doExport (reverse mode)";
384 const bool verbose = Behavior::verbose(
"DistObject");
385 std::unique_ptr<std::string> prefix;
387 prefix = this->createPrefix(
"DistObject", modeString);
388 std::ostringstream os;
389 os << *prefix <<
"Start" << endl;
390 std::cerr << os.str ();
392 this->beginExport(source, importer, CM, restrictedMode);
393 this->endExport(source, importer, CM, restrictedMode);
395 std::ostringstream os;
396 os << *prefix <<
"Done" << endl;
397 std::cerr << os.str ();
401 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
407 const bool restrictedMode)
411 const char modeString[] =
"beginImport (forward mode)";
416 const bool verbose = Behavior::verbose(
"DistObject");
417 std::unique_ptr<std::string> prefix;
419 prefix = this->createPrefix(
"DistObject", modeString);
420 std::ostringstream os;
421 os << *prefix <<
"Start" << endl;
422 std::cerr << os.str ();
424 this->beginTransfer(source, importer, modeString, DoForward, CM, restrictedMode);
426 std::ostringstream os;
427 os << *prefix <<
"Done" << endl;
428 std::cerr << os.str ();
432 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
434 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
435 beginExport(
const SrcDistObject& source,
436 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
438 const bool restrictedMode)
440 using Details::Behavior;
442 const char modeString[] =
"beginExport (forward mode)";
447 const bool verbose = Behavior::verbose(
"DistObject");
448 std::unique_ptr<std::string> prefix;
450 prefix = this->createPrefix(
"DistObject", modeString);
451 std::ostringstream os;
452 os << *prefix <<
"Start" << endl;
453 std::cerr << os.str ();
455 this->beginTransfer(source, exporter, modeString, DoForward, CM, restrictedMode);
457 std::ostringstream os;
458 os << *prefix <<
"Done" << endl;
459 std::cerr << os.str ();
463 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
465 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
466 beginImport(
const SrcDistObject& source,
467 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
469 const bool restrictedMode)
471 using Details::Behavior;
473 const char modeString[] =
"beginImport (reverse mode)";
478 const bool verbose = Behavior::verbose(
"DistObject");
479 std::unique_ptr<std::string> prefix;
481 prefix = this->createPrefix(
"DistObject", modeString);
482 std::ostringstream os;
483 os << *prefix <<
"Start" << endl;
484 std::cerr << os.str ();
486 this->beginTransfer(source, exporter, modeString, DoReverse, CM, restrictedMode);
488 std::ostringstream os;
489 os << *prefix <<
"Done" << endl;
490 std::cerr << os.str ();
494 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
496 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
497 beginExport(
const SrcDistObject& source,
498 const Import<LocalOrdinal, GlobalOrdinal, Node> & importer,
500 const bool restrictedMode)
502 using Details::Behavior;
504 const char modeString[] =
"beginExport (reverse mode)";
509 const bool verbose = Behavior::verbose(
"DistObject");
510 std::unique_ptr<std::string> prefix;
513 std::ostringstream os;
514 os << *prefix <<
"Start" << endl;
515 std::cerr << os.str ();
517 this->beginTransfer(source, importer, modeString, DoReverse, CM, restrictedMode);
519 std::ostringstream os;
520 os << *prefix <<
"Done" << endl;
521 std::cerr << os.str ();
525 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
527 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
528 endImport(
const SrcDistObject& source,
529 const Import<LocalOrdinal, GlobalOrdinal, Node>& importer,
531 const bool restrictedMode)
533 using Details::Behavior;
535 const char modeString[] =
"endImport (forward mode)";
540 const bool verbose = Behavior::verbose(
"DistObject");
541 std::unique_ptr<std::string> prefix;
544 std::ostringstream os;
545 os << *prefix <<
"Start" << endl;
546 std::cerr << os.str ();
548 this->endTransfer(source, importer, modeString, DoForward, CM, restrictedMode);
550 std::ostringstream os;
551 os << *prefix <<
"Done" << endl;
552 std::cerr << os.str ();
556 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
558 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
559 endExport(
const SrcDistObject& source,
560 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
562 const bool restrictedMode)
564 using Details::Behavior;
566 const char modeString[] =
"endExport (forward mode)";
571 const bool verbose = Behavior::verbose(
"DistObject");
572 std::unique_ptr<std::string> prefix;
574 prefix = this->createPrefix(
"DistObject", modeString);
575 std::ostringstream os;
576 os << *prefix <<
"Start" << endl;
577 std::cerr << os.str ();
579 this->endTransfer(source, exporter, modeString, DoForward, CM, restrictedMode);
581 std::ostringstream os;
582 os << *prefix <<
"Done" << endl;
583 std::cerr << os.str ();
587 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
589 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
590 endImport(
const SrcDistObject& source,
591 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
593 const bool restrictedMode)
595 using Details::Behavior;
597 const char modeString[] =
"endImport (reverse mode)";
602 const bool verbose = Behavior::verbose(
"DistObject");
603 std::unique_ptr<std::string> prefix;
605 prefix = this->createPrefix(
"DistObject", modeString);
606 std::ostringstream os;
607 os << *prefix <<
"Start" << endl;
608 std::cerr << os.str ();
610 this->endTransfer(source, exporter, modeString, DoReverse, CM, restrictedMode);
612 std::ostringstream os;
613 os << *prefix <<
"Done" << endl;
614 std::cerr << os.str ();
618 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
620 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
621 endExport(
const SrcDistObject& source,
622 const Import<LocalOrdinal, GlobalOrdinal, Node> & importer,
624 const bool restrictedMode)
626 using Details::Behavior;
628 const char modeString[] =
"endExport (reverse mode)";
633 const bool verbose = Behavior::verbose(
"DistObject");
634 std::unique_ptr<std::string> prefix;
636 prefix = this->createPrefix(
"DistObject", modeString);
637 std::ostringstream os;
638 os << *prefix <<
"Start" << endl;
639 std::cerr << os.str ();
641 this->endTransfer(source, importer, modeString, DoReverse, CM, restrictedMode);
643 std::ostringstream os;
644 os << *prefix <<
"Done" << endl;
645 std::cerr << os.str ();
649 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
653 return distributorActor_.isReady();
656 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
660 return map_->isDistributed ();
663 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
670 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
674 const ::Tpetra::Details::Transfer<local_ordinal_type, global_ordinal_type, node_type>& transfer,
675 const char modeString[],
680 beginTransfer(src, transfer, modeString, revOp, CM, restrictedMode);
681 endTransfer(src, transfer, modeString, revOp, CM, restrictedMode);
684 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
689 const std::string* prefix,
694 std::ostringstream os;
695 os << *prefix <<
"Realloc (if needed) imports_ from "
696 << imports_.extent (0) <<
" to " << newSize << std::endl;
697 std::cerr << os.str ();
699 using ::Tpetra::Details::reallocDualViewIfNeeded;
700 const bool reallocated =
701 reallocDualViewIfNeeded (this->imports_, newSize,
"imports");
703 std::ostringstream os;
704 os << *prefix <<
"Finished realloc'ing imports_" << std::endl;
705 std::cerr << os.str ();
710 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
714 const size_t numImportLIDs)
717 using ::Tpetra::Details::dualViewStatusToString;
718 using ::Tpetra::Details::reallocDualViewIfNeeded;
724 constexpr size_t tooBigFactor = 10;
726 const bool verbose = Behavior::verbose(
"DistObject");
727 std::unique_ptr<std::string> prefix;
729 prefix = this->createPrefix(
"DistObject",
730 "reallocArraysForNumPacketsPerLid");
731 std::ostringstream os;
733 <<
"numExportLIDs: " << numExportLIDs
734 <<
", numImportLIDs: " << numImportLIDs
736 os << *prefix <<
"DualView status before:" << endl
738 << dualViewStatusToString (this->numExportPacketsPerLID_,
739 "numExportPacketsPerLID_")
742 << dualViewStatusToString (this->numImportPacketsPerLID_,
743 "numImportPacketsPerLID_")
745 std::cerr << os.str ();
749 const bool firstReallocated =
750 reallocDualViewIfNeeded (this->numExportPacketsPerLID_,
752 "numExportPacketsPerLID",
759 const bool needFenceBeforeNextAlloc = ! firstReallocated;
760 const bool secondReallocated =
761 reallocDualViewIfNeeded (this->numImportPacketsPerLID_,
763 "numImportPacketsPerLID",
765 needFenceBeforeNextAlloc);
768 std::ostringstream os;
769 os << *prefix <<
"DualView status after:" << endl
770 << *prefix << dualViewStatusToString (this->numExportPacketsPerLID_,
771 "numExportPacketsPerLID_")
773 << *prefix << dualViewStatusToString (this->numImportPacketsPerLID_,
774 "numImportPacketsPerLID_")
776 std::cerr << os.str ();
779 return firstReallocated || secondReallocated;
782 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
786 const ::Tpetra::Details::Transfer<local_ordinal_type, global_ordinal_type, node_type>& transfer,
787 const char modeString[],
793 using ::Tpetra::Details::dualViewStatusToString;
794 using ::Tpetra::Details::getArrayViewFromDualView;
796 using Kokkos::Compat::getArrayView;
797 using Kokkos::Compat::getConstArrayView;
798 using Kokkos::Compat::getKokkosViewDeepCopy;
799 using Kokkos::Compat::create_const_view;
803 const char funcName[] =
"Tpetra::DistObject::doTransfer";
805 ProfilingRegion region_doTransfer(funcName);
806 const bool verbose = Behavior::verbose(
"DistObject");
807 std::shared_ptr<std::string> prefix;
809 std::ostringstream os;
810 prefix = this->createPrefix(
"DistObject",
"doTransfer");
811 os << *prefix <<
"Source type: " << Teuchos::typeName(src)
812 <<
", Target type: " << Teuchos::typeName(*
this) << endl;
813 std::cerr << os.str();
826 const bool debug = Behavior::debug(
"DistObject");
828 if (! restrictedMode && revOp == DoForward) {
829 const bool myMapSameAsTransferTgtMap =
830 this->getMap ()->isSameAs (* (transfer.getTargetMap ()));
831 TEUCHOS_TEST_FOR_EXCEPTION
832 (! myMapSameAsTransferTgtMap, std::invalid_argument,
833 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
834 "communication, the target DistObject's Map must be the same "
835 "(in the sense of Tpetra::Map::isSameAs) as the input "
836 "Export/Import object's target Map.");
838 else if (! restrictedMode && revOp == DoReverse) {
839 const bool myMapSameAsTransferSrcMap =
840 this->getMap ()->isSameAs (* (transfer.getSourceMap ()));
841 TEUCHOS_TEST_FOR_EXCEPTION
842 (! myMapSameAsTransferSrcMap, std::invalid_argument,
843 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
844 "communication, the target DistObject's Map must be the same "
845 "(in the sense of Tpetra::Map::isSameAs) as the input "
846 "Export/Import object's source Map.");
848 else if (restrictedMode && revOp == DoForward) {
849 const bool myMapLocallyFittedTransferTgtMap =
850 this->getMap ()->isLocallyFitted (* (transfer.getTargetMap ()));
851 TEUCHOS_TEST_FOR_EXCEPTION
852 (! myMapLocallyFittedTransferTgtMap , std::invalid_argument,
853 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
854 "communication using restricted mode, Export/Import object's "
855 "target Map must be locally fitted (in the sense of "
856 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
859 const bool myMapLocallyFittedTransferSrcMap =
860 this->getMap ()->isLocallyFitted (* (transfer.getSourceMap ()));
861 TEUCHOS_TEST_FOR_EXCEPTION
862 (! myMapLocallyFittedTransferSrcMap, std::invalid_argument,
863 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
864 "communication using restricted mode, Export/Import object's "
865 "source Map must be locally fitted (in the sense of "
866 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
872 const this_type* srcDistObj =
dynamic_cast<const this_type*
> (&src);
873 if (srcDistObj !=
nullptr) {
874 if (revOp == DoForward) {
875 const bool srcMapSameAsImportSrcMap =
876 srcDistObj->getMap ()->isSameAs (* (transfer.getSourceMap ()));
877 TEUCHOS_TEST_FOR_EXCEPTION
878 (! srcMapSameAsImportSrcMap, std::invalid_argument,
879 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
880 "communication, the source DistObject's Map must be the same "
881 "as the input Export/Import object's source Map.");
884 const bool srcMapSameAsImportTgtMap =
885 srcDistObj->getMap ()->isSameAs (* (transfer.getTargetMap ()));
886 TEUCHOS_TEST_FOR_EXCEPTION
887 (! srcMapSameAsImportTgtMap, std::invalid_argument,
888 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
889 "communication, the source DistObject's Map must be the same "
890 "as the input Export/Import object's target Map.");
895 const size_t numSameIDs = transfer.getNumSameIDs ();
896 Distributor& distor = transfer.getDistributor ();
897 const Details::DistributorPlan& distributorPlan = (revOp == DoForward) ? distor.getPlan() : *distor.getPlan().getReversePlan();
899 TEUCHOS_TEST_FOR_EXCEPTION
900 (debug && restrictedMode &&
901 (transfer.getPermuteToLIDs_dv().extent(0) != 0 ||
902 transfer.getPermuteFromLIDs_dv().extent(0) != 0),
903 std::invalid_argument,
904 "Tpetra::DistObject::" << modeString <<
": Transfer object "
905 "cannot have permutes in restricted mode.");
908 const bool commOnHost = ! Behavior::assumeMpiIsGPUAware ();
910 std::ostringstream os;
911 os << *prefix <<
"doTransfer: Use new interface; "
912 "commOnHost=" << (commOnHost ?
"true" :
"false") << endl;
913 std::cerr << os.str ();
916 using const_lo_dv_type =
917 Kokkos::DualView<const local_ordinal_type*, buffer_device_type>;
918 const_lo_dv_type permuteToLIDs = (revOp == DoForward) ?
919 transfer.getPermuteToLIDs_dv () :
920 transfer.getPermuteFromLIDs_dv ();
921 const_lo_dv_type permuteFromLIDs = (revOp == DoForward) ?
922 transfer.getPermuteFromLIDs_dv () :
923 transfer.getPermuteToLIDs_dv ();
924 const_lo_dv_type remoteLIDs = (revOp == DoForward) ?
925 transfer.getRemoteLIDs_dv () :
926 transfer.getExportLIDs_dv ();
927 const_lo_dv_type exportLIDs = (revOp == DoForward) ?
928 transfer.getExportLIDs_dv () :
929 transfer.getRemoteLIDs_dv ();
930 const bool canTryAliasing = (revOp == DoForward) ?
931 transfer.areRemoteLIDsContiguous() :
932 transfer.areExportLIDsContiguous();
935 ProfilingRegion region_dTN(funcName);
936#ifdef HAVE_TPETRA_TRANSFER_TIMERS
939 Teuchos::TimeMonitor doXferMon (*doXferTimer_);
943 std::ostringstream os;
944 os << *prefix <<
"Input arguments:" << endl
946 << *prefix <<
" numSameIDs: " << numSameIDs << endl
948 << dualViewStatusToString (permuteToLIDs,
"permuteToLIDs") << endl
950 << dualViewStatusToString (permuteFromLIDs,
"permuteFromLIDs") << endl
952 << dualViewStatusToString (remoteLIDs,
"remoteLIDs") << endl
954 << dualViewStatusToString (exportLIDs,
"exportLIDs") << endl
955 << *prefix <<
" revOp: Do" << (revOp == DoReverse ?
"Reverse" :
"Forward") << endl
956 << *prefix <<
" commOnHost: " << (commOnHost ?
"true" :
"false") << endl;
957 std::cerr << os.str ();
961 ProfilingRegion region_cs (
"Tpetra::DistObject::doTransferNew::checkSizes");
963 std::ostringstream os;
964 os << *prefix <<
"1. checkSizes" << endl;
965 std::cerr << os.str ();
967 const bool checkSizesResult = this->checkSizes (src);
968 TEUCHOS_TEST_FOR_EXCEPTION
969 (! checkSizesResult, std::invalid_argument,
970 "Tpetra::DistObject::doTransfer: checkSizes() indicates that the "
971 "destination object is not a legal target for redistribution from the "
972 "source object. This probably means that they do not have the same "
973 "dimensions. For example, MultiVectors must have the same number of "
974 "rows and columns.");
981 if (!restrictedMode && numSameIDs + permuteToLIDs.extent (0) != 0) {
984 std::ostringstream os;
985 os << *prefix <<
"2. copyAndPermute" << endl;
986 std::cerr << os.str ();
988 ProfilingRegion region_cp
989 (
"Tpetra::DistObject::doTransferNew::copyAndPermute");
990#ifdef HAVE_TPETRA_TRANSFER_TIMERS
993 Teuchos::TimeMonitor copyAndPermuteMon (*copyAndPermuteTimer_);
996 if (numSameIDs + permuteToLIDs.extent (0) != 0) {
999 std::ostringstream os;
1000 os << *prefix <<
"2. copyAndPermute" << endl;
1001 std::cerr << os.str ();
1003 this->copyAndPermute (src, numSameIDs, permuteToLIDs,
1004 permuteFromLIDs, CM);
1006 std::ostringstream os;
1007 os << *prefix <<
"After copyAndPermute:" << endl
1009 << dualViewStatusToString (permuteToLIDs,
"permuteToLIDs")
1012 << dualViewStatusToString (permuteFromLIDs,
"permuteFromLIDs")
1014 std::cerr << os.str ();
1027 size_t constantNumPackets = this->constantNumberOfPackets ();
1029 std::ostringstream os;
1030 os << *prefix <<
"constantNumPackets=" << constantNumPackets << endl;
1031 std::cerr << os.str ();
1039 if (constantNumPackets == 0) {
1041 std::ostringstream os;
1042 os << *prefix <<
"3. (Re)allocate num{Ex,Im}portPacketsPerLID"
1044 std::cerr << os.str ();
1048 this->reallocArraysForNumPacketsPerLid (exportLIDs.extent (0),
1049 remoteLIDs.extent (0));
1053 std::ostringstream os;
1054 os << *prefix <<
"4. packAndPrepare: before, "
1057 std::cerr << os.str ();
1060 doPackAndPrepare(src, exportLIDs, constantNumPackets);
1062 this->exports_.sync_host();
1065 this->exports_.sync_device();
1069 std::ostringstream os;
1070 os << *prefix <<
"5.1. After packAndPrepare, "
1073 std::cerr << os.str ();
1079 if (constantNumPackets != 0) {
1084 const size_t rbufLen = remoteLIDs.extent (0) * constantNumPackets;
1085 reallocImportsIfNeeded (rbufLen, verbose, prefix.get (), canTryAliasing, CM);
1089 bool needCommunication =
true;
1092 const this_type* srcDistObj =
dynamic_cast<const this_type*
> (&src);
1094 if (revOp == DoReverse && ! this->isDistributed ()) {
1095 needCommunication =
false;
1104 else if (revOp == DoForward && srcDistObj != NULL &&
1105 ! srcDistObj->isDistributed ()) {
1106 needCommunication =
false;
1109 if (! needCommunication) {
1111 std::ostringstream os;
1112 os << *prefix <<
"Comm not needed; skipping" << endl;
1113 std::cerr << os.str ();
1117 ProfilingRegion region_dpw
1118 (
"Tpetra::DistObject::doTransferNew::doPostsAndWaits");
1119#ifdef HAVE_TPETRA_TRANSFER_TIMERS
1122 Teuchos::TimeMonitor doPostsAndWaitsMon (*doPostsAndWaitsTimer_);
1126 std::ostringstream os;
1127 os << *prefix <<
"7.0. "
1128 << (revOp == DoReverse ?
"Reverse" :
"Forward")
1130 std::cerr << os.str ();
1133 doPosts(distributorPlan, constantNumPackets, commOnHost, prefix, canTryAliasing, CM);
1138 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1140 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1141 endTransfer(
const SrcDistObject& src,
1142 const ::Tpetra::Details::Transfer<local_ordinal_type, global_ordinal_type, node_type>& transfer,
1143 const char modeString[],
1144 const ReverseOption revOp,
1146 bool restrictedMode)
1148 using Details::Behavior;
1149 using ::Tpetra::Details::dualViewStatusToString;
1150 using ::Tpetra::Details::getArrayViewFromDualView;
1151 using Details::ProfilingRegion;
1152 using Kokkos::Compat::getArrayView;
1153 using Kokkos::Compat::getConstArrayView;
1154 using Kokkos::Compat::getKokkosViewDeepCopy;
1155 using Kokkos::Compat::create_const_view;
1158 using Details::ProfilingRegion;
1159 const char funcName[] =
"Tpetra::DistObject::doTransfer";
1161 ProfilingRegion region_doTransfer(funcName);
1162 const bool verbose = Behavior::verbose(
"DistObject");
1163 std::shared_ptr<std::string> prefix;
1165 std::ostringstream os;
1166 prefix = this->
createPrefix(
"DistObject",
"doTransfer");
1167 os << *prefix <<
"Source type: " << Teuchos::typeName(src)
1168 <<
", Target type: " << Teuchos::typeName(*
this) << endl;
1169 std::cerr << os.str();
1182 const bool debug = Behavior::debug(
"DistObject");
1184 if (! restrictedMode && revOp == DoForward) {
1185 const bool myMapSameAsTransferTgtMap =
1186 this->getMap ()->isSameAs (* (transfer.getTargetMap ()));
1187 TEUCHOS_TEST_FOR_EXCEPTION
1188 (! myMapSameAsTransferTgtMap, std::invalid_argument,
1189 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
1190 "communication, the target DistObject's Map must be the same "
1191 "(in the sense of Tpetra::Map::isSameAs) as the input "
1192 "Export/Import object's target Map.");
1194 else if (! restrictedMode && revOp == DoReverse) {
1195 const bool myMapSameAsTransferSrcMap =
1196 this->getMap ()->isSameAs (* (transfer.getSourceMap ()));
1197 TEUCHOS_TEST_FOR_EXCEPTION
1198 (! myMapSameAsTransferSrcMap, std::invalid_argument,
1199 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
1200 "communication, the target DistObject's Map must be the same "
1201 "(in the sense of Tpetra::Map::isSameAs) as the input "
1202 "Export/Import object's source Map.");
1204 else if (restrictedMode && revOp == DoForward) {
1205 const bool myMapLocallyFittedTransferTgtMap =
1206 this->getMap ()->isLocallyFitted (* (transfer.getTargetMap ()));
1207 TEUCHOS_TEST_FOR_EXCEPTION
1208 (! myMapLocallyFittedTransferTgtMap , std::invalid_argument,
1209 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
1210 "communication using restricted mode, Export/Import object's "
1211 "target Map must be locally fitted (in the sense of "
1212 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
1215 const bool myMapLocallyFittedTransferSrcMap =
1216 this->getMap ()->isLocallyFitted (* (transfer.getSourceMap ()));
1217 TEUCHOS_TEST_FOR_EXCEPTION
1218 (! myMapLocallyFittedTransferSrcMap, std::invalid_argument,
1219 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
1220 "communication using restricted mode, Export/Import object's "
1221 "source Map must be locally fitted (in the sense of "
1222 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
1228 const this_type* srcDistObj =
dynamic_cast<const this_type*
> (&src);
1229 if (srcDistObj !=
nullptr) {
1230 if (revOp == DoForward) {
1231 const bool srcMapSameAsImportSrcMap =
1232 srcDistObj->getMap ()->isSameAs (* (transfer.getSourceMap ()));
1233 TEUCHOS_TEST_FOR_EXCEPTION
1234 (! srcMapSameAsImportSrcMap, std::invalid_argument,
1235 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
1236 "communication, the source DistObject's Map must be the same "
1237 "as the input Export/Import object's source Map.");
1240 const bool srcMapSameAsImportTgtMap =
1241 srcDistObj->getMap ()->isSameAs (* (transfer.getTargetMap ()));
1242 TEUCHOS_TEST_FOR_EXCEPTION
1243 (! srcMapSameAsImportTgtMap, std::invalid_argument,
1244 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
1245 "communication, the source DistObject's Map must be the same "
1246 "as the input Export/Import object's target Map.");
1251 Distributor& distor = transfer.getDistributor ();
1252 const Details::DistributorPlan& distributorPlan = (revOp == DoForward) ? distor.getPlan() : *distor.getPlan().getReversePlan();
1254 TEUCHOS_TEST_FOR_EXCEPTION
1255 (debug && restrictedMode &&
1256 (transfer.getPermuteToLIDs_dv().extent(0) != 0 ||
1257 transfer.getPermuteFromLIDs_dv().extent(0) != 0),
1258 std::invalid_argument,
1259 "Tpetra::DistObject::" << modeString <<
": Transfer object "
1260 "cannot have permutes in restricted mode.");
1263 const bool commOnHost = ! Behavior::assumeMpiIsGPUAware ();
1265 std::ostringstream os;
1266 os << *prefix <<
"doTransfer: Use new interface; "
1267 "commOnHost=" << (commOnHost ?
"true" :
"false") << endl;
1268 std::cerr << os.str ();
1271 using const_lo_dv_type =
1272 Kokkos::DualView<const local_ordinal_type*, buffer_device_type>;
1273 const_lo_dv_type permuteToLIDs = (revOp == DoForward) ?
1274 transfer.getPermuteToLIDs_dv () :
1275 transfer.getPermuteFromLIDs_dv ();
1276 const_lo_dv_type permuteFromLIDs = (revOp == DoForward) ?
1277 transfer.getPermuteFromLIDs_dv () :
1278 transfer.getPermuteToLIDs_dv ();
1279 const_lo_dv_type remoteLIDs = (revOp == DoForward) ?
1280 transfer.getRemoteLIDs_dv () :
1281 transfer.getExportLIDs_dv ();
1282 const_lo_dv_type exportLIDs = (revOp == DoForward) ?
1283 transfer.getExportLIDs_dv () :
1284 transfer.getRemoteLIDs_dv ();
1285 const bool canTryAliasing = (revOp == DoForward) ?
1286 transfer.areRemoteLIDsContiguous() :
1287 transfer.areExportLIDsContiguous();
1289 size_t constantNumPackets = this->constantNumberOfPackets ();
1293 if (constantNumPackets != 0) {
1298 const size_t rbufLen = remoteLIDs.extent (0) * constantNumPackets;
1299 reallocImportsIfNeeded (rbufLen, verbose, prefix.get (), canTryAliasing, CM);
1303 bool needCommunication =
true;
1306 const this_type* srcDistObj =
dynamic_cast<const this_type*
> (&src);
1308 if (revOp == DoReverse && ! this->isDistributed ()) {
1309 needCommunication =
false;
1318 else if (revOp == DoForward && srcDistObj != NULL &&
1319 ! srcDistObj->isDistributed ()) {
1320 needCommunication =
false;
1323 if (! needCommunication) {
1325 std::ostringstream os;
1326 os << *prefix <<
"Comm not needed; skipping" << endl;
1327 std::cerr << os.str ();
1331 distributorActor_.doWaits(distributorPlan);
1334 std::ostringstream os;
1335 os << *prefix <<
"8. unpackAndCombine - remoteLIDs " << remoteLIDs.extent(0) <<
", constantNumPackets " << constantNumPackets << endl;
1336 std::cerr << os.str ();
1338 doUnpackAndCombine(remoteLIDs, constantNumPackets, CM);
1343 std::ostringstream os;
1344 os << *prefix <<
"9. Done!" << endl;
1345 std::cerr << os.str ();
1349 std::ostringstream os;
1350 os << *prefix <<
"Tpetra::DistObject::doTransfer: Done!" << endl;
1351 std::cerr << os.str ();
1355 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1357 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1358 doPosts(
const Details::DistributorPlan& distributorPlan,
1359 size_t constantNumPackets,
1361 std::shared_ptr<std::string> prefix,
1362 const bool canTryAliasing,
1365 using ::Tpetra::Details::dualViewStatusToString;
1366 using ::Tpetra::Details::getArrayViewFromDualView;
1367 using Kokkos::Compat::create_const_view;
1372 if (constantNumPackets == 0) {
1374 std::ostringstream os;
1375 os << *prefix <<
"7.1. Variable # packets / LID: first comm "
1376 <<
"(commOnHost = " << (commOnHost ?
"true" :
"false") <<
")"
1378 std::cerr << os.str ();
1380 size_t totalImportPackets = 0;
1382 if (this->numExportPacketsPerLID_.need_sync_host ()) {
1383 this->numExportPacketsPerLID_.sync_host ();
1385 if (this->numImportPacketsPerLID_.need_sync_host ()) {
1386 this->numImportPacketsPerLID_.sync_host ();
1388 this->numImportPacketsPerLID_.modify_host ();
1390 create_const_view (this->numExportPacketsPerLID_.view_host ());
1391 auto numImp_h = this->numImportPacketsPerLID_.view_host ();
1395 std::ostringstream os;
1396 os << *prefix <<
"Call doPostsAndWaits"
1398 std::cerr << os.str ();
1400 distributorActor_.doPostsAndWaits(distributorPlan, numExp_h, 1, numImp_h);
1403 std::ostringstream os;
1404 os << *prefix <<
"Count totalImportPackets" << std::endl;
1405 std::cerr << os.str ();
1407 using the_dev_type =
typename decltype (numImp_h)::device_type;
1408 totalImportPackets = countTotalImportPackets<the_dev_type> (numImp_h);
1411 this->numExportPacketsPerLID_.sync_device ();
1412 this->numImportPacketsPerLID_.sync_device ();
1413 this->numImportPacketsPerLID_.modify_device ();
1414 auto numExp_d = create_const_view
1415 (this->numExportPacketsPerLID_.view_device ());
1416 auto numImp_d = this->numImportPacketsPerLID_.view_device ();
1420 std::ostringstream os;
1421 os << *prefix <<
"Call doPostsAndWaits"
1423 std::cerr << os.str ();
1426 distributorActor_.doPostsAndWaits(distributorPlan, numExp_d, 1, numImp_d);
1429 std::ostringstream os;
1430 os << *prefix <<
"Count totalImportPackets" << std::endl;
1431 std::cerr << os.str ();
1433 using the_dev_type =
typename decltype (numImp_d)::device_type;
1434 totalImportPackets = countTotalImportPackets<the_dev_type> (numImp_d);
1438 std::ostringstream os;
1439 os << *prefix <<
"totalImportPackets=" << totalImportPackets << endl;
1440 std::cerr << os.str ();
1442 this->reallocImportsIfNeeded (totalImportPackets, verbose,
1443 prefix.get (), canTryAliasing, CM);
1445 std::ostringstream os;
1446 os << *prefix <<
"7.3. Second comm" << std::endl;
1447 std::cerr << os.str ();
1453 this->numExportPacketsPerLID_.sync_host ();
1454 this->numImportPacketsPerLID_.sync_host ();
1463 auto numExportPacketsPerLID_av =
1465 auto numImportPacketsPerLID_av =
1473 this->imports_.clear_sync_state ();
1476 std::ostringstream os;
1477 os << *prefix <<
"Comm on "
1478 << (commOnHost ?
"host" :
"device")
1479 <<
"; call doPosts" << endl;
1480 std::cerr << os.str ();
1484 this->imports_.modify_host ();
1485 distributorActor_.doPosts
1487 create_const_view (this->exports_.view_host ()),
1488 numExportPacketsPerLID_av,
1489 this->imports_.view_host (),
1490 numImportPacketsPerLID_av);
1494 this->imports_.modify_device ();
1495 distributorActor_.doPosts
1497 create_const_view (this->exports_.view_device ()),
1498 numExportPacketsPerLID_av,
1499 this->imports_.view_device (),
1500 numImportPacketsPerLID_av);
1505 std::ostringstream os;
1506 os << *prefix <<
"7.1. Const # packets per LID: " << endl
1513 std::cerr << os.str ();
1520 this->imports_.clear_sync_state ();
1523 std::ostringstream os;
1524 os << *prefix <<
"7.2. Comm on "
1525 << (commOnHost ?
"host" :
"device")
1526 <<
"; call doPosts" << endl;
1527 std::cerr << os.str ();
1530 this->imports_.modify_host ();
1531 distributorActor_.doPosts
1533 create_const_view (this->exports_.view_host ()),
1535 this->imports_.view_host ());
1539 this->imports_.modify_device ();
1540 distributorActor_.doPosts
1542 create_const_view (this->exports_.view_device ()),
1544 this->imports_.view_device ());
1549 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1551 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1552 doPackAndPrepare(
const SrcDistObject& src,
1553 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& exportLIDs,
1554 size_t& constantNumPackets)
1556 using Details::ProfilingRegion;
1560 ProfilingRegion region_pp
1561 (
"Tpetra::DistObject::doTransferNew::packAndPrepare");
1562#ifdef HAVE_TPETRA_TRANSFER_TIMERS
1565 Teuchos::TimeMonitor packAndPrepareMon (*packAndPrepareTimer_);
1585 std::ostringstream lclErrStrm;
1586 bool lclSuccess =
false;
1588 this->packAndPrepare (src, exportLIDs, this->exports_,
1589 this->numExportPacketsPerLID_,
1590 constantNumPackets);
1593 catch (std::exception& e) {
1594 lclErrStrm <<
"packAndPrepare threw an exception: "
1595 << endl << e.what();
1598 lclErrStrm <<
"packAndPrepare threw an exception "
1599 "not a subclass of std::exception.";
1601 const char gblErrMsgHeader[] =
"Tpetra::DistObject "
1602 "threw an exception in packAndPrepare on "
1603 "one or more processes in the DistObject's communicator.";
1604 auto comm = getMap()->getComm();
1605 Details::checkGlobalError(std::cerr, lclSuccess,
1606 lclErrStrm.str().c_str(),
1607 gblErrMsgHeader, *comm);
1610 this->packAndPrepare (src, exportLIDs, this->exports_,
1611 this->numExportPacketsPerLID_,
1612 constantNumPackets);
1616 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1618 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1619 doUnpackAndCombine(
const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& remoteLIDs,
1620 size_t constantNumPackets,
1623 using Details::ProfilingRegion;
1627 ProfilingRegion region_uc
1628 (
"Tpetra::DistObject::doTransferNew::unpackAndCombine");
1629#ifdef HAVE_TPETRA_TRANSFER_TIMERS
1632 Teuchos::TimeMonitor unpackAndCombineMon (*unpackAndCombineTimer_);
1636 std::ostringstream lclErrStrm;
1637 bool lclSuccess =
false;
1640 this->numImportPacketsPerLID_,
1641 constantNumPackets, CM);
1644 catch (std::exception& e) {
1645 lclErrStrm <<
"unpackAndCombine threw an exception: "
1646 << endl << e.what();
1649 lclErrStrm <<
"unpackAndCombine threw an exception "
1650 "not a subclass of std::exception.";
1652 const char gblErrMsgHeader[] =
"Tpetra::DistObject "
1653 "threw an exception in unpackAndCombine on "
1654 "one or more processes in the DistObject's communicator.";
1655 auto comm = getMap()->getComm();
1656 Details::checkGlobalError(std::cerr, lclSuccess,
1657 lclErrStrm.str().c_str(),
1658 gblErrMsgHeader, *comm);
1662 this->numImportPacketsPerLID_,
1663 constantNumPackets, CM);
1667 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1673 const Kokkos::DualView<
1676 const Kokkos::DualView<
1682 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1687 const Kokkos::DualView<
1699 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1703 (
const Kokkos::DualView<
1717 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1720 print (std::ostream& os)
const
1722 using Teuchos::FancyOStream;
1723 using Teuchos::getFancyOStream;
1725 using Teuchos::rcpFromRef;
1728 RCP<FancyOStream> out = getFancyOStream (rcpFromRef (os));
1729 this->describe (*out, Teuchos::VERB_DEFAULT);
1732 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1733 std::unique_ptr<std::string>
1736 const char methodName[])
const
1738 auto map = this->getMap();
1739 auto comm = map.is_null() ? Teuchos::null : map->getComm();
1741 comm.getRawPtr(), className, methodName);
1744 template<
class DistObjectType>
1747 Teuchos::RCP<DistObjectType>& input,
1748 const Teuchos::RCP<
const Map<
1749 typename DistObjectType::local_ordinal_type,
1750 typename DistObjectType::global_ordinal_type,
1751 typename DistObjectType::node_type>>& newMap)
1753 input->removeEmptyProcessesInPlace (newMap);
1754 if (newMap.is_null ()) {
1755 input = Teuchos::null;
1759 template<
class DistObjectType>
1763 auto newMap = input->getMap ()->removeEmptyProcesses ();
1764 removeEmptyProcessesInPlace<DistObjectType> (input, newMap);
1768#define TPETRA_DISTOBJECT_INSTANT(SCALAR, LO, GO, NODE) \
1769 template class DistObject< SCALAR , LO , GO , NODE >;
1773#define TPETRA_DISTOBJECT_INSTANT_CHAR(LO, GO, NODE) \
1774 template class DistObject< char , LO , GO , NODE >;
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.
Declaration of Tpetra::Details::Profiling, a scope guard for Kokkos Profiling.
Declaration and definition of Tpetra::Details::reallocDualViewIfNeeded, an implementation detail of T...
void unpackAndCombine(const RowView &row_ptrs_beg, const RowView &row_ptrs_end, IndicesView &indices, const Kokkos::View< const GlobalOrdinal *, BufferDevice, Kokkos::MemoryUnmanaged > &imports, const Kokkos::View< const size_t *, BufferDevice, Kokkos::MemoryUnmanaged > &num_packets_per_lid, const Kokkos::View< const LocalOrdinal *, BufferDevice, Kokkos::MemoryUnmanaged > &import_lids, const typename CrsGraph< LocalOrdinal, GlobalOrdinal, Node >::padding_type &padding, const bool unpack_pids, const int myRank, const bool verbose)
Perform the unpack operation for the graph.
Stand-alone utility functions and macros.
Description of Tpetra's behavior.
static bool debug()
Whether Tpetra is in debug mode.
static bool verbose()
Whether Tpetra is in verbose mode.
Base class for distributed Tpetra objects that support data redistribution.
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.
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.
virtual bool reallocArraysForNumPacketsPerLid(const size_t numExportLIDs, const size_t numImportLIDs)
Reallocate numExportPacketsPerLID_ and/or numImportPacketsPerLID_, if necessary.
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").
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.
DistObject(const Teuchos::RCP< const map_type > &map)
Constructor.
bool transferArrived() const
Whether the data from an import/export operation has arrived, and is ready for the unpack and combine...
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).
Kokkos::Device< typename device_type::execution_space, buffer_memory_space > buffer_device_type
Kokkos::Device specialization for communication buffers.
LocalOrdinal local_ordinal_type
The type of local indices.
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 print(std::ostream &os) const
Print this object to the given output stream.
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.
typename ::Kokkos::Details::ArithTraits< Packet >::val_type packet_type
The type of each datum being sent or received in an Import or Export.
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.
ReverseOption
Whether the data transfer should be performed in forward or reverse mode.
virtual size_t constantNumberOfPackets() const
Whether the implementation's instance promises always to have a constant number of packets per LID (l...
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").
virtual std::string description() const
One-line descriptiion of this object.
virtual void removeEmptyProcessesInPlace(const Teuchos::RCP< const map_type > &newMap)
Remove processes which contain no entries in this object's Map.
bool isDistributed() const
Whether this is a globally distributed object.
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
A parallel distribution of indices over processes.
Abstract base class for objects that can be the source of an Import or Export operation.
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.
std::unique_ptr< std::string > createPrefix(const int myRank, const char prefix[])
Create string prefix for each line of verbose output.
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...
std::string dualViewStatusToString(const DualViewType &dv, const char name[])
Return the status of the given Kokkos::DualView, as a human-readable string.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
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.
std::string combineModeToString(const CombineMode combineMode)
Human-readable string representation of the given CombineMode.
CombineMode
Rule for combining data in an Import or Export.
@ ZERO
Replace old values with zero.