11 #ifndef TPETRA_DISTOBJECT_DEF_HPP
12 #define TPETRA_DISTOBJECT_DEF_HPP
22 #include "Tpetra_Distributor.hpp"
25 #include "Tpetra_Details_checkGlobalError.hpp"
28 #include "Teuchos_CommHelpers.hpp"
29 #include "Teuchos_TypeNameTraits.hpp"
37 template<
class DeviceType,
class IndexType =
size_t>
39 SumFunctor (
const Kokkos::View<const size_t*, DeviceType>& viewToSum) :
40 viewToSum_ (viewToSum) {}
41 KOKKOS_INLINE_FUNCTION
void operator() (
const IndexType i,
size_t& lclSum)
const {
42 lclSum += viewToSum_(i);
44 Kokkos::View<const size_t*, DeviceType> viewToSum_;
47 template<
class DeviceType,
class IndexType =
size_t>
49 countTotalImportPackets (
const Kokkos::View<const size_t*, DeviceType>& numImportPacketsPerLID)
51 using Kokkos::parallel_reduce;
52 typedef DeviceType DT;
53 typedef typename DT::execution_space DES;
54 typedef Kokkos::RangePolicy<DES, IndexType> range_type;
56 const IndexType numOut = numImportPacketsPerLID.extent (0);
57 size_t totalImportPackets = 0;
58 parallel_reduce (
"Count import packets",
59 range_type (0, numOut),
60 SumFunctor<DeviceType, IndexType> (numImportPacketsPerLID),
62 return totalImportPackets;
67 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
72 #ifdef HAVE_TPETRA_TRANSFER_TIMERS
75 using Teuchos::TimeMonitor;
77 RCP<Time> doXferTimer =
78 TimeMonitor::lookupCounter (
"Tpetra::DistObject::doTransfer");
79 if (doXferTimer.is_null ()) {
81 TimeMonitor::getNewCounter (
"Tpetra::DistObject::doTransfer");
83 doXferTimer_ = doXferTimer;
85 RCP<Time> copyAndPermuteTimer =
86 TimeMonitor::lookupCounter (
"Tpetra::DistObject::copyAndPermute");
87 if (copyAndPermuteTimer.is_null ()) {
89 TimeMonitor::getNewCounter (
"Tpetra::DistObject::copyAndPermute");
91 copyAndPermuteTimer_ = copyAndPermuteTimer;
93 RCP<Time> packAndPrepareTimer =
94 TimeMonitor::lookupCounter (
"Tpetra::DistObject::packAndPrepare");
95 if (packAndPrepareTimer.is_null ()) {
97 TimeMonitor::getNewCounter (
"Tpetra::DistObject::packAndPrepare");
99 packAndPrepareTimer_ = packAndPrepareTimer;
101 RCP<Time> doPostsAndWaitsTimer =
102 TimeMonitor::lookupCounter (
"Tpetra::DistObject::doPostsAndWaits");
103 if (doPostsAndWaitsTimer.is_null ()) {
104 doPostsAndWaitsTimer =
105 TimeMonitor::getNewCounter (
"Tpetra::DistObject::doPostsAndWaits");
107 doPostsAndWaitsTimer_ = doPostsAndWaitsTimer;
109 RCP<Time> unpackAndCombineTimer =
110 TimeMonitor::lookupCounter (
"Tpetra::DistObject::unpackAndCombine");
111 if (unpackAndCombineTimer.is_null ()) {
112 unpackAndCombineTimer =
113 TimeMonitor::getNewCounter (
"Tpetra::DistObject::unpackAndCombine");
115 unpackAndCombineTimer_ = unpackAndCombineTimer;
116 #endif // HAVE_TPETRA_TRANSFER_TIMERS
119 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
124 using Teuchos::TypeNameTraits;
126 std::ostringstream os;
127 os <<
"\"Tpetra::DistObject\": {"
128 <<
"Packet: " << TypeNameTraits<packet_type>::name ()
129 <<
", LocalOrdinal: " << TypeNameTraits<local_ordinal_type>::name ()
130 <<
", GlobalOrdinal: " << TypeNameTraits<global_ordinal_type>::name ()
131 <<
", Node: " << TypeNameTraits<Node>::name ();
132 if (this->getObjectLabel () !=
"") {
133 os <<
"Label: \"" << this->getObjectLabel () <<
"\"";
139 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
143 const Teuchos::EVerbosityLevel verbLevel)
const
145 using Teuchos::rcpFromRef;
146 using Teuchos::TypeNameTraits;
148 const Teuchos::EVerbosityLevel vl = (verbLevel == Teuchos::VERB_DEFAULT) ?
149 Teuchos::VERB_LOW : verbLevel;
150 Teuchos::RCP<const Teuchos::Comm<int> > comm = this->getMap ()->getComm ();
151 const int myRank = comm.is_null () ? 0 : comm->getRank ();
152 const int numProcs = comm.is_null () ? 1 : comm->getSize ();
154 if (vl != Teuchos::VERB_NONE) {
155 Teuchos::OSTab tab0 (out);
157 out <<
"\"Tpetra::DistObject\":" << endl;
159 Teuchos::OSTab tab1 (out);
161 out <<
"Template parameters:" << endl;
163 Teuchos::OSTab tab2 (out);
164 out <<
"Packet: " << TypeNameTraits<packet_type>::name () << endl
165 <<
"LocalOrdinal: " << TypeNameTraits<local_ordinal_type>::name () << endl
166 <<
"GlobalOrdinal: " << TypeNameTraits<global_ordinal_type>::name () << endl
167 <<
"Node: " << TypeNameTraits<node_type>::name () << endl;
169 if (this->getObjectLabel () !=
"") {
170 out <<
"Label: \"" << this->getObjectLabel () <<
"\"" << endl;
177 out <<
"Map:" << endl;
179 Teuchos::OSTab tab2 (out);
180 map_->describe (out, vl);
184 if (vl > Teuchos::VERB_LOW) {
185 for (
int p = 0; p < numProcs; ++p) {
187 out <<
"Process " << myRank <<
":" << endl;
188 Teuchos::OSTab tab2 (out);
189 out <<
"Export buffer size (in packets): "
190 << exports_.extent (0)
192 <<
"Import buffer size (in packets): "
193 << imports_.extent (0)
196 if (! comm.is_null ()) {
206 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
211 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
212 "Tpetra::DistObject::removeEmptyProcessesInPlace: Not implemented");
244 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
250 const bool restrictedMode)
254 const char modeString[] =
"doImport (forward mode)";
259 const bool verbose = Behavior::verbose(
"DistObject");
260 std::unique_ptr<std::string> prefix;
262 prefix = this->createPrefix(
"DistObject", modeString);
263 std::ostringstream os;
264 os << *prefix <<
"Start" << endl;
265 std::cerr << os.str ();
267 this->beginImport(source, importer, CM, restrictedMode);
268 this->endImport(source, importer, CM, restrictedMode);
270 std::ostringstream os;
271 os << *prefix <<
"Done" << endl;
272 std::cerr << os.str ();
276 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
282 const bool restrictedMode)
286 const char modeString[] =
"doExport (forward mode)";
291 const bool verbose = Behavior::verbose(
"DistObject");
292 std::unique_ptr<std::string> prefix;
294 prefix = this->createPrefix(
"DistObject", modeString);
295 std::ostringstream os;
296 os << *prefix <<
"Start" << endl;
297 std::cerr << os.str ();
299 this->beginExport(source, exporter, CM, restrictedMode);
300 this->endExport(source, exporter, CM, restrictedMode);
302 std::ostringstream os;
303 os << *prefix <<
"Done" << endl;
304 std::cerr << os.str ();
308 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
314 const bool restrictedMode)
318 const char modeString[] =
"doImport (reverse mode)";
323 const bool verbose = Behavior::verbose(
"DistObject");
324 std::unique_ptr<std::string> prefix;
326 prefix = this->createPrefix(
"DistObject", modeString);
327 std::ostringstream os;
328 os << *prefix <<
"Start" << endl;
329 std::cerr << os.str ();
331 this->beginImport(source, exporter, CM, restrictedMode);
332 this->endImport(source, exporter, CM, restrictedMode);
334 std::ostringstream os;
335 os << *prefix <<
"Done" << endl;
336 std::cerr << os.str ();
340 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
346 const bool restrictedMode)
350 const char modeString[] =
"doExport (reverse mode)";
355 const bool verbose = Behavior::verbose(
"DistObject");
356 std::unique_ptr<std::string> prefix;
358 prefix = this->createPrefix(
"DistObject", modeString);
359 std::ostringstream os;
360 os << *prefix <<
"Start" << endl;
361 std::cerr << os.str ();
363 this->beginExport(source, importer, CM, restrictedMode);
364 this->endExport(source, importer, CM, restrictedMode);
366 std::ostringstream os;
367 os << *prefix <<
"Done" << endl;
368 std::cerr << os.str ();
372 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
378 const bool restrictedMode)
382 const char modeString[] =
"beginImport (forward mode)";
387 const bool verbose = Behavior::verbose(
"DistObject");
388 std::unique_ptr<std::string> prefix;
390 prefix = this->createPrefix(
"DistObject", modeString);
391 std::ostringstream os;
392 os << *prefix <<
"Start" << endl;
393 std::cerr << os.str ();
395 this->beginTransfer(source, importer, modeString, DoForward, CM, restrictedMode);
397 std::ostringstream os;
398 os << *prefix <<
"Done" << endl;
399 std::cerr << os.str ();
403 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
405 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
406 beginExport(
const SrcDistObject& source,
407 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
409 const bool restrictedMode)
411 using Details::Behavior;
413 const char modeString[] =
"beginExport (forward mode)";
418 const bool verbose = Behavior::verbose(
"DistObject");
419 std::unique_ptr<std::string> prefix;
422 std::ostringstream os;
423 os << *prefix <<
"Start" << endl;
424 std::cerr << os.str ();
426 this->beginTransfer(source, exporter, modeString, DoForward, CM, restrictedMode);
428 std::ostringstream os;
429 os << *prefix <<
"Done" << endl;
430 std::cerr << os.str ();
434 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
436 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
437 beginImport(
const SrcDistObject& source,
438 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
440 const bool restrictedMode)
442 using Details::Behavior;
444 const char modeString[] =
"beginImport (reverse mode)";
449 const bool verbose = Behavior::verbose(
"DistObject");
450 std::unique_ptr<std::string> prefix;
453 std::ostringstream os;
454 os << *prefix <<
"Start" << endl;
455 std::cerr << os.str ();
457 this->beginTransfer(source, exporter, modeString, DoReverse, CM, restrictedMode);
459 std::ostringstream os;
460 os << *prefix <<
"Done" << endl;
461 std::cerr << os.str ();
465 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
467 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
468 beginExport(
const SrcDistObject& source,
469 const Import<LocalOrdinal, GlobalOrdinal, Node> & importer,
471 const bool restrictedMode)
473 using Details::Behavior;
475 const char modeString[] =
"beginExport (reverse mode)";
480 const bool verbose = Behavior::verbose(
"DistObject");
481 std::unique_ptr<std::string> prefix;
484 std::ostringstream os;
485 os << *prefix <<
"Start" << endl;
486 std::cerr << os.str ();
488 this->beginTransfer(source, importer, modeString, DoReverse, CM, restrictedMode);
490 std::ostringstream os;
491 os << *prefix <<
"Done" << endl;
492 std::cerr << os.str ();
496 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
498 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
499 endImport(
const SrcDistObject& source,
500 const Import<LocalOrdinal, GlobalOrdinal, Node>& importer,
502 const bool restrictedMode)
504 using Details::Behavior;
506 const char modeString[] =
"endImport (forward mode)";
511 const bool verbose = Behavior::verbose(
"DistObject");
512 std::unique_ptr<std::string> prefix;
515 std::ostringstream os;
516 os << *prefix <<
"Start" << endl;
517 std::cerr << os.str ();
519 this->endTransfer(source, importer, modeString, DoForward, CM, restrictedMode);
521 std::ostringstream os;
522 os << *prefix <<
"Done" << endl;
523 std::cerr << os.str ();
527 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
529 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
530 endExport(
const SrcDistObject& source,
531 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
533 const bool restrictedMode)
535 using Details::Behavior;
537 const char modeString[] =
"endExport (forward mode)";
542 const bool verbose = Behavior::verbose(
"DistObject");
543 std::unique_ptr<std::string> prefix;
546 std::ostringstream os;
547 os << *prefix <<
"Start" << endl;
548 std::cerr << os.str ();
550 this->endTransfer(source, exporter, modeString, DoForward, CM, restrictedMode);
552 std::ostringstream os;
553 os << *prefix <<
"Done" << endl;
554 std::cerr << os.str ();
558 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
560 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
561 endImport(
const SrcDistObject& source,
562 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
564 const bool restrictedMode)
566 using Details::Behavior;
568 const char modeString[] =
"endImport (reverse mode)";
573 const bool verbose = Behavior::verbose(
"DistObject");
574 std::unique_ptr<std::string> prefix;
577 std::ostringstream os;
578 os << *prefix <<
"Start" << endl;
579 std::cerr << os.str ();
581 this->endTransfer(source, exporter, modeString, DoReverse, CM, restrictedMode);
583 std::ostringstream os;
584 os << *prefix <<
"Done" << endl;
585 std::cerr << os.str ();
589 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
591 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
592 endExport(
const SrcDistObject& source,
593 const Import<LocalOrdinal, GlobalOrdinal, Node> & importer,
595 const bool restrictedMode)
597 using Details::Behavior;
599 const char modeString[] =
"endExport (reverse mode)";
604 const bool verbose = Behavior::verbose(
"DistObject");
605 std::unique_ptr<std::string> prefix;
608 std::ostringstream os;
609 os << *prefix <<
"Start" << endl;
610 std::cerr << os.str ();
612 this->endTransfer(source, importer, modeString, DoReverse, CM, restrictedMode);
614 std::ostringstream os;
615 os << *prefix <<
"Done" << endl;
616 std::cerr << os.str ();
620 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
624 return distributorActor_.isReady();
627 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
631 return map_->isDistributed ();
634 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
641 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
645 const ::Tpetra::Details::Transfer<local_ordinal_type, global_ordinal_type, node_type>& transfer,
646 const char modeString[],
651 beginTransfer(src, transfer, modeString, revOp, CM, restrictedMode);
652 endTransfer(src, transfer, modeString, revOp, CM, restrictedMode);
655 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
660 const std::string* prefix,
665 std::ostringstream os;
666 os << *prefix <<
"Realloc (if needed) imports_ from "
667 << imports_.extent (0) <<
" to " << newSize << std::endl;
668 std::cerr << os.str ();
671 const bool reallocated =
674 std::ostringstream os;
675 os << *prefix <<
"Finished realloc'ing imports_" << std::endl;
676 std::cerr << os.str ();
681 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
685 const size_t numImportLIDs)
695 constexpr
size_t tooBigFactor = 10;
697 const bool verbose = Behavior::verbose(
"DistObject");
698 std::unique_ptr<std::string> prefix;
700 prefix = this->createPrefix(
"DistObject",
701 "reallocArraysForNumPacketsPerLid");
702 std::ostringstream os;
704 <<
"numExportLIDs: " << numExportLIDs
705 <<
", numImportLIDs: " << numImportLIDs
707 os << *prefix <<
"DualView status before:" << endl
710 "numExportPacketsPerLID_")
714 "numImportPacketsPerLID_")
716 std::cerr << os.str ();
720 const bool firstReallocated =
723 "numExportPacketsPerLID",
730 const bool needFenceBeforeNextAlloc = ! firstReallocated;
731 const bool secondReallocated =
734 "numImportPacketsPerLID",
736 needFenceBeforeNextAlloc);
739 std::ostringstream os;
740 os << *prefix <<
"DualView status after:" << endl
742 "numExportPacketsPerLID_")
745 "numImportPacketsPerLID_")
747 std::cerr << os.str ();
750 return firstReallocated || secondReallocated;
753 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
757 const ::Tpetra::Details::Transfer<local_ordinal_type, global_ordinal_type, node_type>& transfer,
758 const char modeString[],
767 using Kokkos::Compat::getArrayView;
768 using Kokkos::Compat::getConstArrayView;
769 using Kokkos::Compat::getKokkosViewDeepCopy;
770 using Kokkos::Compat::create_const_view;
775 const bool commOnHost = ! Behavior::assumeMpiIsGPUAware ();
776 const char funcNameHost[] =
"Tpetra::DistObject::beginTransfer[Host]";
777 const char funcNameDevice[] =
"Tpetra::DistObject::beginTransfer[Device]";
778 const char *funcName = commOnHost ? funcNameHost : funcNameDevice;
780 ProfilingRegion region_doTransfer(funcName);
781 const bool verbose = Behavior::verbose(
"DistObject");
782 std::shared_ptr<std::string> prefix;
784 std::ostringstream os;
785 prefix = this->createPrefix(
"DistObject",
"doTransfer");
786 os << *prefix <<
"Source type: " << Teuchos::typeName(src)
787 <<
", Target type: " << Teuchos::typeName(*
this) << endl;
788 std::cerr << os.str();
801 const bool debug = Behavior::debug(
"DistObject");
803 if (! restrictedMode && revOp == DoForward) {
804 const bool myMapSameAsTransferTgtMap =
805 this->getMap ()->isSameAs (* (transfer.getTargetMap ()));
806 TEUCHOS_TEST_FOR_EXCEPTION
807 (! myMapSameAsTransferTgtMap, std::invalid_argument,
808 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
809 "communication, the target DistObject's Map must be the same "
810 "(in the sense of Tpetra::Map::isSameAs) as the input "
811 "Export/Import object's target Map.");
813 else if (! restrictedMode && revOp == DoReverse) {
814 const bool myMapSameAsTransferSrcMap =
815 this->getMap ()->isSameAs (* (transfer.getSourceMap ()));
816 TEUCHOS_TEST_FOR_EXCEPTION
817 (! myMapSameAsTransferSrcMap, std::invalid_argument,
818 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
819 "communication, the target DistObject's Map must be the same "
820 "(in the sense of Tpetra::Map::isSameAs) as the input "
821 "Export/Import object's source Map.");
823 else if (restrictedMode && revOp == DoForward) {
824 const bool myMapLocallyFittedTransferTgtMap =
825 this->getMap ()->isLocallyFitted (* (transfer.getTargetMap ()));
826 TEUCHOS_TEST_FOR_EXCEPTION
827 (! myMapLocallyFittedTransferTgtMap , std::invalid_argument,
828 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
829 "communication using restricted mode, Export/Import object's "
830 "target Map must be locally fitted (in the sense of "
831 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
834 const bool myMapLocallyFittedTransferSrcMap =
835 this->getMap ()->isLocallyFitted (* (transfer.getSourceMap ()));
836 TEUCHOS_TEST_FOR_EXCEPTION
837 (! myMapLocallyFittedTransferSrcMap, std::invalid_argument,
838 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
839 "communication using restricted mode, Export/Import object's "
840 "source Map must be locally fitted (in the sense of "
841 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
848 if (srcDistObj !=
nullptr) {
849 if (revOp == DoForward) {
850 const bool srcMapSameAsImportSrcMap =
851 srcDistObj->
getMap ()->isSameAs (* (transfer.getSourceMap ()));
852 TEUCHOS_TEST_FOR_EXCEPTION
853 (! srcMapSameAsImportSrcMap, std::invalid_argument,
854 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
855 "communication, the source DistObject's Map must be the same "
856 "as the input Export/Import object's source Map.");
859 const bool srcMapSameAsImportTgtMap =
860 srcDistObj->
getMap ()->isSameAs (* (transfer.getTargetMap ()));
861 TEUCHOS_TEST_FOR_EXCEPTION
862 (! srcMapSameAsImportTgtMap, std::invalid_argument,
863 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
864 "communication, the source DistObject's Map must be the same "
865 "as the input Export/Import object's target Map.");
870 const size_t numSameIDs = transfer.getNumSameIDs ();
874 TEUCHOS_TEST_FOR_EXCEPTION
875 (debug && restrictedMode &&
876 (transfer.getPermuteToLIDs_dv().extent(0) != 0 ||
877 transfer.getPermuteFromLIDs_dv().extent(0) != 0),
878 std::invalid_argument,
879 "Tpetra::DistObject::" << modeString <<
": Transfer object "
880 "cannot have permutes in restricted mode.");
884 std::ostringstream os;
885 os << *prefix <<
"doTransfer: Use new interface; "
886 "commOnHost=" << (commOnHost ?
"true" :
"false") << endl;
887 std::cerr << os.str ();
890 using const_lo_dv_type =
891 Kokkos::DualView<const local_ordinal_type*, buffer_device_type>;
892 const_lo_dv_type permuteToLIDs = (revOp == DoForward) ?
893 transfer.getPermuteToLIDs_dv () :
894 transfer.getPermuteFromLIDs_dv ();
895 const_lo_dv_type permuteFromLIDs = (revOp == DoForward) ?
896 transfer.getPermuteFromLIDs_dv () :
897 transfer.getPermuteToLIDs_dv ();
898 const_lo_dv_type remoteLIDs = (revOp == DoForward) ?
899 transfer.getRemoteLIDs_dv () :
900 transfer.getExportLIDs_dv ();
901 const_lo_dv_type exportLIDs = (revOp == DoForward) ?
902 transfer.getExportLIDs_dv () :
903 transfer.getRemoteLIDs_dv ();
904 const bool canTryAliasing = (revOp == DoForward) ?
905 transfer.areRemoteLIDsContiguous() :
906 transfer.areExportLIDsContiguous();
909 ProfilingRegion region_dTN(funcName);
910 #ifdef HAVE_TPETRA_TRANSFER_TIMERS
913 Teuchos::TimeMonitor doXferMon (*doXferTimer_);
914 #endif // HAVE_TPETRA_TRANSFER_TIMERS
917 std::ostringstream os;
918 os << *prefix <<
"Input arguments:" << endl
920 << *prefix <<
" numSameIDs: " << numSameIDs << endl
929 << *prefix <<
" revOp: Do" << (revOp == DoReverse ?
"Reverse" :
"Forward") << endl
930 << *prefix <<
" commOnHost: " << (commOnHost ?
"true" :
"false") << endl;
931 std::cerr << os.str ();
935 ProfilingRegion region_cs (
"Tpetra::DistObject::doTransferNew::checkSizes");
937 std::ostringstream os;
938 os << *prefix <<
"1. checkSizes" << endl;
939 std::cerr << os.str ();
941 const bool checkSizesResult = this->checkSizes (src);
942 TEUCHOS_TEST_FOR_EXCEPTION
943 (! checkSizesResult, std::invalid_argument,
944 "Tpetra::DistObject::doTransfer: checkSizes() indicates that the "
945 "destination object is not a legal target for redistribution from the "
946 "source object. This probably means that they do not have the same "
947 "dimensions. For example, MultiVectors must have the same number of "
948 "rows and columns.");
955 if (!restrictedMode && numSameIDs + permuteToLIDs.extent (0) != 0) {
958 std::ostringstream os;
959 os << *prefix <<
"2. copyAndPermute" << endl;
960 std::cerr << os.str ();
962 ProfilingRegion region_cp
963 (
"Tpetra::DistObject::doTransferNew::copyAndPermute");
964 #ifdef HAVE_TPETRA_TRANSFER_TIMERS
967 Teuchos::TimeMonitor copyAndPermuteMon (*copyAndPermuteTimer_);
968 #endif // HAVE_TPETRA_TRANSFER_TIMERS
970 if (numSameIDs + permuteToLIDs.extent (0) != 0) {
973 std::ostringstream os;
974 os << *prefix <<
"2. copyAndPermute" << endl;
975 std::cerr << os.str ();
977 this->copyAndPermute (src, numSameIDs, permuteToLIDs,
978 permuteFromLIDs, CM);
980 std::ostringstream os;
981 os << *prefix <<
"After copyAndPermute:" << endl
988 std::cerr << os.str ();
1001 size_t constantNumPackets = this->constantNumberOfPackets ();
1003 std::ostringstream os;
1004 os << *prefix <<
"constantNumPackets=" << constantNumPackets << endl;
1005 std::cerr << os.str ();
1013 if (constantNumPackets == 0) {
1015 std::ostringstream os;
1016 os << *prefix <<
"3. (Re)allocate num{Ex,Im}portPacketsPerLID"
1018 std::cerr << os.str ();
1022 this->reallocArraysForNumPacketsPerLid (exportLIDs.extent (0),
1023 remoteLIDs.extent (0));
1027 std::ostringstream os;
1028 os << *prefix <<
"4. packAndPrepare: before, "
1031 std::cerr << os.str ();
1034 doPackAndPrepare(src, exportLIDs, constantNumPackets,
execution_space());
1036 this->exports_.sync_host();
1039 this->exports_.sync_device();
1043 std::ostringstream os;
1044 os << *prefix <<
"5.1. After packAndPrepare, "
1047 std::cerr << os.str ();
1053 if (constantNumPackets != 0) {
1058 const size_t rbufLen = remoteLIDs.extent (0) * constantNumPackets;
1059 reallocImportsIfNeeded (rbufLen, verbose, prefix.get (), canTryAliasing, CM);
1063 bool needCommunication =
true;
1068 if (revOp == DoReverse && ! this->isDistributed ()) {
1069 needCommunication =
false;
1078 else if (revOp == DoForward && srcDistObj != NULL &&
1080 needCommunication =
false;
1083 if (! needCommunication) {
1085 std::ostringstream os;
1086 os << *prefix <<
"Comm not needed; skipping" << endl;
1087 std::cerr << os.str ();
1091 ProfilingRegion region_dpw
1092 (
"Tpetra::DistObject::doTransferNew::doPostsAndWaits");
1093 #ifdef HAVE_TPETRA_TRANSFER_TIMERS
1096 Teuchos::TimeMonitor doPostsAndWaitsMon (*doPostsAndWaitsTimer_);
1097 #endif // HAVE_TPETRA_TRANSFER_TIMERS
1100 std::ostringstream os;
1101 os << *prefix <<
"7.0. "
1102 << (revOp == DoReverse ?
"Reverse" :
"Forward")
1104 std::cerr << os.str ();
1107 doPosts(distributorPlan, constantNumPackets, commOnHost, prefix, canTryAliasing, CM);
1112 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1116 const ::Tpetra::Details::Transfer<local_ordinal_type, global_ordinal_type, node_type>& transfer,
1117 const char modeString[],
1118 const ReverseOption revOp,
1120 bool restrictedMode)
1126 using Kokkos::Compat::getArrayView;
1127 using Kokkos::Compat::getConstArrayView;
1128 using Kokkos::Compat::getKokkosViewDeepCopy;
1129 using Kokkos::Compat::create_const_view;
1134 const bool commOnHost = ! Behavior::assumeMpiIsGPUAware ();
1135 const char funcNameHost[] =
"Tpetra::DistObject::endTransfer[Host]";
1136 const char funcNameDevice[] =
"Tpetra::DistObject::endTransfer[Device]";
1137 const char *funcName = commOnHost ? funcNameHost : funcNameDevice;
1138 ProfilingRegion region_doTransfer(funcName);
1139 const bool verbose = Behavior::verbose(
"DistObject");
1140 std::shared_ptr<std::string> prefix;
1142 std::ostringstream os;
1143 prefix = this->createPrefix(
"DistObject",
"doTransfer");
1144 os << *prefix <<
"Source type: " << Teuchos::typeName(src)
1145 <<
", Target type: " << Teuchos::typeName(*
this) << endl;
1146 std::cerr << os.str();
1159 const bool debug = Behavior::debug(
"DistObject");
1161 if (! restrictedMode && revOp == DoForward) {
1162 const bool myMapSameAsTransferTgtMap =
1163 this->getMap ()->isSameAs (* (transfer.getTargetMap ()));
1164 TEUCHOS_TEST_FOR_EXCEPTION
1165 (! myMapSameAsTransferTgtMap, std::invalid_argument,
1166 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
1167 "communication, the target DistObject's Map must be the same "
1168 "(in the sense of Tpetra::Map::isSameAs) as the input "
1169 "Export/Import object's target Map.");
1171 else if (! restrictedMode && revOp == DoReverse) {
1172 const bool myMapSameAsTransferSrcMap =
1173 this->getMap ()->isSameAs (* (transfer.getSourceMap ()));
1174 TEUCHOS_TEST_FOR_EXCEPTION
1175 (! myMapSameAsTransferSrcMap, std::invalid_argument,
1176 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
1177 "communication, the target DistObject's Map must be the same "
1178 "(in the sense of Tpetra::Map::isSameAs) as the input "
1179 "Export/Import object's source Map.");
1181 else if (restrictedMode && revOp == DoForward) {
1182 const bool myMapLocallyFittedTransferTgtMap =
1183 this->getMap ()->isLocallyFitted (* (transfer.getTargetMap ()));
1184 TEUCHOS_TEST_FOR_EXCEPTION
1185 (! myMapLocallyFittedTransferTgtMap , std::invalid_argument,
1186 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
1187 "communication using restricted mode, Export/Import object's "
1188 "target Map must be locally fitted (in the sense of "
1189 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
1192 const bool myMapLocallyFittedTransferSrcMap =
1193 this->getMap ()->isLocallyFitted (* (transfer.getSourceMap ()));
1194 TEUCHOS_TEST_FOR_EXCEPTION
1195 (! myMapLocallyFittedTransferSrcMap, std::invalid_argument,
1196 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
1197 "communication using restricted mode, Export/Import object's "
1198 "source Map must be locally fitted (in the sense of "
1199 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
1205 const this_type* srcDistObj =
dynamic_cast<const this_type*
> (&src);
1206 if (srcDistObj !=
nullptr) {
1207 if (revOp == DoForward) {
1208 const bool srcMapSameAsImportSrcMap =
1209 srcDistObj->getMap ()->isSameAs (* (transfer.getSourceMap ()));
1210 TEUCHOS_TEST_FOR_EXCEPTION
1211 (! srcMapSameAsImportSrcMap, std::invalid_argument,
1212 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
1213 "communication, the source DistObject's Map must be the same "
1214 "as the input Export/Import object's source Map.");
1217 const bool srcMapSameAsImportTgtMap =
1218 srcDistObj->getMap ()->isSameAs (* (transfer.getTargetMap ()));
1219 TEUCHOS_TEST_FOR_EXCEPTION
1220 (! srcMapSameAsImportTgtMap, std::invalid_argument,
1221 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
1222 "communication, the source DistObject's Map must be the same "
1223 "as the input Export/Import object's target Map.");
1228 Distributor& distor = transfer.getDistributor ();
1229 const Details::DistributorPlan& distributorPlan = (revOp == DoForward) ? distor.getPlan() : *distor.getPlan().getReversePlan();
1231 TEUCHOS_TEST_FOR_EXCEPTION
1232 (debug && restrictedMode &&
1233 (transfer.getPermuteToLIDs_dv().extent(0) != 0 ||
1234 transfer.getPermuteFromLIDs_dv().extent(0) != 0),
1235 std::invalid_argument,
1236 "Tpetra::DistObject::" << modeString <<
": Transfer object "
1237 "cannot have permutes in restricted mode.");
1241 std::ostringstream os;
1242 os << *prefix <<
"doTransfer: Use new interface; "
1243 "commOnHost=" << (commOnHost ?
"true" :
"false") << endl;
1244 std::cerr << os.str ();
1247 using const_lo_dv_type =
1248 Kokkos::DualView<const local_ordinal_type*, buffer_device_type>;
1249 const_lo_dv_type permuteToLIDs = (revOp == DoForward) ?
1250 transfer.getPermuteToLIDs_dv () :
1251 transfer.getPermuteFromLIDs_dv ();
1252 const_lo_dv_type permuteFromLIDs = (revOp == DoForward) ?
1253 transfer.getPermuteFromLIDs_dv () :
1254 transfer.getPermuteToLIDs_dv ();
1255 const_lo_dv_type remoteLIDs = (revOp == DoForward) ?
1256 transfer.getRemoteLIDs_dv () :
1257 transfer.getExportLIDs_dv ();
1258 const_lo_dv_type exportLIDs = (revOp == DoForward) ?
1259 transfer.getExportLIDs_dv () :
1260 transfer.getRemoteLIDs_dv ();
1261 const bool canTryAliasing = (revOp == DoForward) ?
1262 transfer.areRemoteLIDsContiguous() :
1263 transfer.areExportLIDsContiguous();
1265 size_t constantNumPackets = this->constantNumberOfPackets ();
1269 if (constantNumPackets != 0) {
1274 const size_t rbufLen = remoteLIDs.extent (0) * constantNumPackets;
1275 reallocImportsIfNeeded (rbufLen, verbose, prefix.get (), canTryAliasing, CM);
1279 bool needCommunication =
true;
1282 const this_type* srcDistObj =
dynamic_cast<const this_type*
> (&src);
1284 if (revOp == DoReverse && ! this->isDistributed ()) {
1285 needCommunication =
false;
1294 else if (revOp == DoForward && srcDistObj != NULL &&
1295 ! srcDistObj->isDistributed ()) {
1296 needCommunication =
false;
1299 if (! needCommunication) {
1301 std::ostringstream os;
1302 os << *prefix <<
"Comm not needed; skipping" << endl;
1303 std::cerr << os.str ();
1307 distributorActor_.doWaitsRecv(distributorPlan);
1310 std::ostringstream os;
1311 os << *prefix <<
"8. unpackAndCombine - remoteLIDs " << remoteLIDs.extent(0) <<
", constantNumPackets " << constantNumPackets << endl;
1312 std::cerr << os.str ();
1314 doUnpackAndCombine(remoteLIDs, constantNumPackets, CM, execution_space());
1316 distributorActor_.doWaitsSend(distributorPlan);
1321 std::ostringstream os;
1322 os << *prefix <<
"9. Done!" << endl;
1323 std::cerr << os.str ();
1327 std::ostringstream os;
1328 os << *prefix <<
"Tpetra::DistObject::doTransfer: Done!" << endl;
1329 std::cerr << os.str ();
1333 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1335 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1336 doPosts(
const Details::DistributorPlan& distributorPlan,
1337 size_t constantNumPackets,
1339 std::shared_ptr<std::string> prefix,
1340 const bool canTryAliasing,
1345 using Kokkos::Compat::create_const_view;
1350 if (constantNumPackets == 0) {
1352 std::ostringstream os;
1353 os << *prefix <<
"7.1. Variable # packets / LID: first comm "
1354 <<
"(commOnHost = " << (commOnHost ?
"true" :
"false") <<
")"
1356 std::cerr << os.str ();
1358 size_t totalImportPackets = 0;
1360 if (this->numExportPacketsPerLID_.need_sync_host ()) {
1361 this->numExportPacketsPerLID_.sync_host ();
1363 if (this->numImportPacketsPerLID_.need_sync_host ()) {
1364 this->numImportPacketsPerLID_.sync_host ();
1366 this->numImportPacketsPerLID_.modify_host ();
1368 create_const_view (this->numExportPacketsPerLID_.view_host ());
1369 auto numImp_h = this->numImportPacketsPerLID_.view_host ();
1373 std::ostringstream os;
1374 os << *prefix <<
"Call doPostsAndWaits"
1376 std::cerr << os.str ();
1378 distributorActor_.doPostsAndWaits(distributorPlan, numExp_h, 1, numImp_h);
1381 std::ostringstream os;
1382 os << *prefix <<
"Count totalImportPackets" << std::endl;
1383 std::cerr << os.str ();
1385 using the_dev_type =
typename decltype (numImp_h)::device_type;
1386 totalImportPackets = countTotalImportPackets<the_dev_type> (numImp_h);
1389 this->numExportPacketsPerLID_.sync_device ();
1390 this->numImportPacketsPerLID_.sync_device ();
1391 this->numImportPacketsPerLID_.modify_device ();
1392 auto numExp_d = create_const_view
1393 (this->numExportPacketsPerLID_.view_device ());
1394 auto numImp_d = this->numImportPacketsPerLID_.view_device ();
1398 std::ostringstream os;
1399 os << *prefix <<
"Call doPostsAndWaits"
1401 std::cerr << os.str ();
1404 distributorActor_.doPostsAndWaits(distributorPlan, numExp_d, 1, numImp_d);
1407 std::ostringstream os;
1408 os << *prefix <<
"Count totalImportPackets" << std::endl;
1409 std::cerr << os.str ();
1411 using the_dev_type =
typename decltype (numImp_d)::device_type;
1412 totalImportPackets = countTotalImportPackets<the_dev_type> (numImp_d);
1416 std::ostringstream os;
1417 os << *prefix <<
"totalImportPackets=" << totalImportPackets << endl;
1418 std::cerr << os.str ();
1420 this->reallocImportsIfNeeded (totalImportPackets, verbose,
1421 prefix.get (), canTryAliasing, CM);
1423 std::ostringstream os;
1424 os << *prefix <<
"7.3. Second comm" << std::endl;
1425 std::cerr << os.str ();
1431 this->numExportPacketsPerLID_.sync_host ();
1432 this->numImportPacketsPerLID_.sync_host ();
1441 auto numExportPacketsPerLID_av =
1443 auto numImportPacketsPerLID_av =
1451 this->imports_.clear_sync_state ();
1454 std::ostringstream os;
1455 os << *prefix <<
"Comm on "
1456 << (commOnHost ?
"host" :
"device")
1457 <<
"; call doPosts" << endl;
1458 std::cerr << os.str ();
1462 this->imports_.modify_host ();
1463 distributorActor_.doPosts
1465 create_const_view (this->exports_.view_host ()),
1466 numExportPacketsPerLID_av,
1467 this->imports_.view_host (),
1468 numImportPacketsPerLID_av);
1471 Kokkos::fence(
"DistObject::doPosts-1");
1472 this->imports_.modify_device ();
1473 distributorActor_.doPosts
1475 create_const_view (this->exports_.view_device ()),
1476 numExportPacketsPerLID_av,
1477 this->imports_.view_device (),
1478 numImportPacketsPerLID_av);
1483 std::ostringstream os;
1484 os << *prefix <<
"7.1. Const # packets per LID: " << endl
1491 std::cerr << os.str ();
1498 this->imports_.clear_sync_state ();
1501 std::ostringstream os;
1502 os << *prefix <<
"7.2. Comm on "
1503 << (commOnHost ?
"host" :
"device")
1504 <<
"; call doPosts" << endl;
1505 std::cerr << os.str ();
1508 this->imports_.modify_host ();
1509 distributorActor_.doPosts
1511 create_const_view (this->exports_.view_host ()),
1513 this->imports_.view_host ());
1516 Kokkos::fence(
"DistObject::doPosts-2");
1517 this->imports_.modify_device ();
1518 distributorActor_.doPosts
1520 create_const_view (this->exports_.view_device ()),
1522 this->imports_.view_device ());
1527 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1529 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1530 doPackAndPrepare(
const SrcDistObject& src,
1531 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& exportLIDs,
1532 size_t& constantNumPackets,
1533 const execution_space &space)
1535 using Details::ProfilingRegion;
1539 ProfilingRegion region_pp
1540 (
"Tpetra::DistObject::doPackAndPrepare");
1541 #ifdef HAVE_TPETRA_TRANSFER_TIMERS
1544 Teuchos::TimeMonitor packAndPrepareMon (*packAndPrepareTimer_);
1545 #endif // HAVE_TPETRA_TRANSFER_TIMERS
1564 std::ostringstream lclErrStrm;
1565 bool lclSuccess =
false;
1567 this->packAndPrepare (src, exportLIDs, this->exports_,
1568 this->numExportPacketsPerLID_,
1569 constantNumPackets, space);
1572 catch (std::exception& e) {
1573 lclErrStrm <<
"packAndPrepare threw an exception: "
1574 << endl << e.what();
1577 lclErrStrm <<
"packAndPrepare threw an exception "
1578 "not a subclass of std::exception.";
1580 const char gblErrMsgHeader[] =
"Tpetra::DistObject "
1581 "threw an exception in packAndPrepare on "
1582 "one or more processes in the DistObject's communicator.";
1583 auto comm = getMap()->getComm();
1584 Details::checkGlobalError(std::cerr, lclSuccess,
1585 lclErrStrm.str().c_str(),
1586 gblErrMsgHeader, *comm);
1589 this->packAndPrepare (src, exportLIDs, this->exports_,
1590 this->numExportPacketsPerLID_,
1591 constantNumPackets, space);
1595 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1597 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1598 doUnpackAndCombine(
const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& remoteLIDs,
1599 size_t constantNumPackets,
1601 const execution_space &space)
1603 using Details::ProfilingRegion;
1607 ProfilingRegion region_uc
1608 (
"Tpetra::DistObject::doUnpackAndCombine");
1609 #ifdef HAVE_TPETRA_TRANSFER_TIMERS
1612 Teuchos::TimeMonitor unpackAndCombineMon (*unpackAndCombineTimer_);
1613 #endif // HAVE_TPETRA_TRANSFER_TIMERS
1616 std::ostringstream lclErrStrm;
1617 bool lclSuccess =
false;
1619 this->unpackAndCombine (remoteLIDs, this->imports_,
1620 this->numImportPacketsPerLID_,
1621 constantNumPackets, CM, space);
1624 catch (std::exception& e) {
1625 lclErrStrm <<
"doUnpackAndCombine threw an exception: "
1626 << endl << e.what();
1629 lclErrStrm <<
"doUnpackAndCombine threw an exception "
1630 "not a subclass of std::exception.";
1632 const char gblErrMsgHeader[] =
"Tpetra::DistObject "
1633 "threw an exception in unpackAndCombine on "
1634 "one or more processes in the DistObject's communicator.";
1635 auto comm = getMap()->getComm();
1636 Details::checkGlobalError(std::cerr, lclSuccess,
1637 lclErrStrm.str().c_str(),
1638 gblErrMsgHeader, *comm);
1641 this->unpackAndCombine (remoteLIDs, this->imports_,
1642 this->numImportPacketsPerLID_,
1643 constantNumPackets, CM, space);
1647 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1653 const Kokkos::DualView<
1656 const Kokkos::DualView<
1663 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1666 const Kokkos::DualView<const local_ordinal_type *, buffer_device_type>
1668 const Kokkos::DualView<const local_ordinal_type *, buffer_device_type>
1682 copyAndPermute(source, numSameIDs, permuteToLIDs, permuteFromLIDs,
1690 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1695 const Kokkos::DualView<
1708 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1711 const Kokkos::DualView<const local_ordinal_type *, buffer_device_type>
1713 Kokkos::DualView<packet_type *, buffer_device_type> &exports,
1714 Kokkos::DualView<size_t *, buffer_device_type> numPacketsPerLID,
1732 packAndPrepare(source, exportLIDs, exports, numPacketsPerLID,
1733 constantNumPackets);
1741 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1745 (
const Kokkos::DualView<
1759 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1761 const Kokkos::DualView<const local_ordinal_type *, buffer_device_type>
1763 Kokkos::DualView<packet_type *, buffer_device_type> imports,
1764 Kokkos::DualView<size_t *, buffer_device_type> numPacketsPerLID,
1765 const size_t constantNumPackets,
const CombineMode combineMode,
1766 const execution_space &space) {
1770 unpackAndCombine(importLIDs, imports, numPacketsPerLID, constantNumPackets,
1774 execution_space().fence();
1779 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1781 std::ostream &os)
const {
1783 using Teuchos::FancyOStream;
1784 using Teuchos::getFancyOStream;
1786 using Teuchos::rcpFromRef;
1788 RCP<FancyOStream> out = getFancyOStream(rcpFromRef(os));
1789 this->describe(*out, Teuchos::VERB_DEFAULT);
1792 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1793 std::unique_ptr<std::string>
1795 const char className[],
const char methodName[])
const {
1796 auto map = this->getMap();
1797 auto comm = map.is_null() ? Teuchos::null : map->getComm();
1801 template <
class DistObjectType>
1803 Teuchos::RCP<DistObjectType> &input,
1804 const Teuchos::RCP<
const Map<
typename DistObjectType::local_ordinal_type,
1805 typename DistObjectType::global_ordinal_type,
1806 typename DistObjectType::node_type>> &newMap) {
1807 input->removeEmptyProcessesInPlace(newMap);
1808 if (newMap.is_null()) {
1809 input = Teuchos::null;
1813 template <
class DistObjectType>
1815 auto newMap = input->getMap()->removeEmptyProcesses();
1816 removeEmptyProcessesInPlace<DistObjectType>(input, newMap);
1820 #define TPETRA_DISTOBJECT_INSTANT(SCALAR, LO, GO, NODE) \
1821 template class DistObject<SCALAR, LO, GO, NODE>;
1825 #define TPETRA_DISTOBJECT_INSTANT_CHAR(LO, GO, NODE) \
1826 template class DistObject<char, LO, GO, NODE>;
1830 #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.