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 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
77 using Teuchos::TypeNameTraits;
79 std::ostringstream os;
80 os <<
"\"Tpetra::DistObject\": {"
81 <<
"Packet: " << TypeNameTraits<packet_type>::name ()
82 <<
", LocalOrdinal: " << TypeNameTraits<local_ordinal_type>::name ()
83 <<
", GlobalOrdinal: " << TypeNameTraits<global_ordinal_type>::name ()
84 <<
", Node: " << TypeNameTraits<Node>::name ();
85 if (this->getObjectLabel () !=
"") {
86 os <<
"Label: \"" << this->getObjectLabel () <<
"\"";
92 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
96 const Teuchos::EVerbosityLevel verbLevel)
const
98 using Teuchos::rcpFromRef;
99 using Teuchos::TypeNameTraits;
101 const Teuchos::EVerbosityLevel vl = (verbLevel == Teuchos::VERB_DEFAULT) ?
102 Teuchos::VERB_LOW : verbLevel;
103 Teuchos::RCP<const Teuchos::Comm<int> > comm = this->getMap ()->getComm ();
104 const int myRank = comm.is_null () ? 0 : comm->getRank ();
105 const int numProcs = comm.is_null () ? 1 : comm->getSize ();
107 if (vl != Teuchos::VERB_NONE) {
108 Teuchos::OSTab tab0 (out);
110 out <<
"\"Tpetra::DistObject\":" << endl;
112 Teuchos::OSTab tab1 (out);
114 out <<
"Template parameters:" << endl;
116 Teuchos::OSTab tab2 (out);
117 out <<
"Packet: " << TypeNameTraits<packet_type>::name () << endl
118 <<
"LocalOrdinal: " << TypeNameTraits<local_ordinal_type>::name () << endl
119 <<
"GlobalOrdinal: " << TypeNameTraits<global_ordinal_type>::name () << endl
120 <<
"Node: " << TypeNameTraits<node_type>::name () << endl;
122 if (this->getObjectLabel () !=
"") {
123 out <<
"Label: \"" << this->getObjectLabel () <<
"\"" << endl;
130 out <<
"Map:" << endl;
132 Teuchos::OSTab tab2 (out);
133 map_->describe (out, vl);
137 if (vl > Teuchos::VERB_LOW) {
138 for (
int p = 0; p < numProcs; ++p) {
140 out <<
"Process " << myRank <<
":" << endl;
141 Teuchos::OSTab tab2 (out);
142 out <<
"Export buffer size (in packets): "
143 << exports_.extent (0)
145 <<
"Import buffer size (in packets): "
146 << imports_.extent (0)
149 if (! comm.is_null ()) {
159 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
164 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
165 "Tpetra::DistObject::removeEmptyProcessesInPlace: Not implemented");
197 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
203 const bool restrictedMode)
207 const char modeString[] =
"doImport (forward mode)";
212 const bool verbose = Behavior::verbose(
"DistObject");
213 std::unique_ptr<std::string> prefix;
215 prefix = this->createPrefix(
"DistObject", modeString);
216 std::ostringstream os;
217 os << *prefix <<
"Start" << endl;
218 std::cerr << os.str ();
220 this->beginImport(source, importer, CM, restrictedMode);
221 this->endImport(source, importer, CM, restrictedMode);
223 std::ostringstream os;
224 os << *prefix <<
"Done" << endl;
225 std::cerr << os.str ();
229 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
235 const bool restrictedMode)
239 const char modeString[] =
"doExport (forward mode)";
244 const bool verbose = Behavior::verbose(
"DistObject");
245 std::unique_ptr<std::string> prefix;
247 prefix = this->createPrefix(
"DistObject", modeString);
248 std::ostringstream os;
249 os << *prefix <<
"Start" << endl;
250 std::cerr << os.str ();
252 this->beginExport(source, exporter, CM, restrictedMode);
253 this->endExport(source, exporter, CM, restrictedMode);
255 std::ostringstream os;
256 os << *prefix <<
"Done" << endl;
257 std::cerr << os.str ();
261 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
267 const bool restrictedMode)
271 const char modeString[] =
"doImport (reverse mode)";
276 const bool verbose = Behavior::verbose(
"DistObject");
277 std::unique_ptr<std::string> prefix;
279 prefix = this->createPrefix(
"DistObject", modeString);
280 std::ostringstream os;
281 os << *prefix <<
"Start" << endl;
282 std::cerr << os.str ();
284 this->beginImport(source, exporter, CM, restrictedMode);
285 this->endImport(source, exporter, CM, restrictedMode);
287 std::ostringstream os;
288 os << *prefix <<
"Done" << endl;
289 std::cerr << os.str ();
293 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
299 const bool restrictedMode)
303 const char modeString[] =
"doExport (reverse mode)";
308 const bool verbose = Behavior::verbose(
"DistObject");
309 std::unique_ptr<std::string> prefix;
311 prefix = this->createPrefix(
"DistObject", modeString);
312 std::ostringstream os;
313 os << *prefix <<
"Start" << endl;
314 std::cerr << os.str ();
316 this->beginExport(source, importer, CM, restrictedMode);
317 this->endExport(source, importer, CM, restrictedMode);
319 std::ostringstream os;
320 os << *prefix <<
"Done" << endl;
321 std::cerr << os.str ();
325 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
331 const bool restrictedMode)
335 const char modeString[] =
"beginImport (forward mode)";
340 const bool verbose = Behavior::verbose(
"DistObject");
341 std::unique_ptr<std::string> prefix;
343 prefix = this->createPrefix(
"DistObject", modeString);
344 std::ostringstream os;
345 os << *prefix <<
"Start" << endl;
346 std::cerr << os.str ();
348 this->beginTransfer(source, importer, modeString, DoForward, CM, restrictedMode);
350 std::ostringstream os;
351 os << *prefix <<
"Done" << endl;
352 std::cerr << os.str ();
356 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
358 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
359 beginExport(
const SrcDistObject& source,
360 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
362 const bool restrictedMode)
364 using Details::Behavior;
366 const char modeString[] =
"beginExport (forward mode)";
371 const bool verbose = Behavior::verbose(
"DistObject");
372 std::unique_ptr<std::string> prefix;
375 std::ostringstream os;
376 os << *prefix <<
"Start" << endl;
377 std::cerr << os.str ();
379 this->beginTransfer(source, exporter, modeString, DoForward, CM, restrictedMode);
381 std::ostringstream os;
382 os << *prefix <<
"Done" << endl;
383 std::cerr << os.str ();
387 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
389 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
390 beginImport(
const SrcDistObject& source,
391 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
393 const bool restrictedMode)
395 using Details::Behavior;
397 const char modeString[] =
"beginImport (reverse mode)";
402 const bool verbose = Behavior::verbose(
"DistObject");
403 std::unique_ptr<std::string> prefix;
406 std::ostringstream os;
407 os << *prefix <<
"Start" << endl;
408 std::cerr << os.str ();
410 this->beginTransfer(source, exporter, modeString, DoReverse, CM, restrictedMode);
412 std::ostringstream os;
413 os << *prefix <<
"Done" << endl;
414 std::cerr << os.str ();
418 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
420 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
421 beginExport(
const SrcDistObject& source,
422 const Import<LocalOrdinal, GlobalOrdinal, Node> & importer,
424 const bool restrictedMode)
426 using Details::Behavior;
428 const char modeString[] =
"beginExport (reverse mode)";
433 const bool verbose = Behavior::verbose(
"DistObject");
434 std::unique_ptr<std::string> prefix;
437 std::ostringstream os;
438 os << *prefix <<
"Start" << endl;
439 std::cerr << os.str ();
441 this->beginTransfer(source, importer, modeString, DoReverse, CM, restrictedMode);
443 std::ostringstream os;
444 os << *prefix <<
"Done" << endl;
445 std::cerr << os.str ();
449 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
451 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
452 endImport(
const SrcDistObject& source,
453 const Import<LocalOrdinal, GlobalOrdinal, Node>& importer,
455 const bool restrictedMode)
457 using Details::Behavior;
459 const char modeString[] =
"endImport (forward mode)";
464 const bool verbose = Behavior::verbose(
"DistObject");
465 std::unique_ptr<std::string> prefix;
468 std::ostringstream os;
469 os << *prefix <<
"Start" << endl;
470 std::cerr << os.str ();
472 this->endTransfer(source, importer, modeString, DoForward, CM, restrictedMode);
474 std::ostringstream os;
475 os << *prefix <<
"Done" << endl;
476 std::cerr << os.str ();
480 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
482 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
483 endExport(
const SrcDistObject& source,
484 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
486 const bool restrictedMode)
488 using Details::Behavior;
490 const char modeString[] =
"endExport (forward mode)";
495 const bool verbose = Behavior::verbose(
"DistObject");
496 std::unique_ptr<std::string> prefix;
499 std::ostringstream os;
500 os << *prefix <<
"Start" << endl;
501 std::cerr << os.str ();
503 this->endTransfer(source, exporter, modeString, DoForward, CM, restrictedMode);
505 std::ostringstream os;
506 os << *prefix <<
"Done" << endl;
507 std::cerr << os.str ();
511 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
513 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
514 endImport(
const SrcDistObject& source,
515 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
517 const bool restrictedMode)
519 using Details::Behavior;
521 const char modeString[] =
"endImport (reverse mode)";
526 const bool verbose = Behavior::verbose(
"DistObject");
527 std::unique_ptr<std::string> prefix;
530 std::ostringstream os;
531 os << *prefix <<
"Start" << endl;
532 std::cerr << os.str ();
534 this->endTransfer(source, exporter, modeString, DoReverse, CM, restrictedMode);
536 std::ostringstream os;
537 os << *prefix <<
"Done" << endl;
538 std::cerr << os.str ();
542 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
544 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
545 endExport(
const SrcDistObject& source,
546 const Import<LocalOrdinal, GlobalOrdinal, Node> & importer,
548 const bool restrictedMode)
550 using Details::Behavior;
552 const char modeString[] =
"endExport (reverse mode)";
557 const bool verbose = Behavior::verbose(
"DistObject");
558 std::unique_ptr<std::string> prefix;
561 std::ostringstream os;
562 os << *prefix <<
"Start" << endl;
563 std::cerr << os.str ();
565 this->endTransfer(source, importer, modeString, DoReverse, CM, restrictedMode);
567 std::ostringstream os;
568 os << *prefix <<
"Done" << endl;
569 std::cerr << os.str ();
573 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
577 return distributorActor_.isReady();
580 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
584 return map_->isDistributed ();
587 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
594 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
598 const ::Tpetra::Details::Transfer<local_ordinal_type, global_ordinal_type, node_type>& transfer,
599 const char modeString[],
604 beginTransfer(src, transfer, modeString, revOp, CM, restrictedMode);
605 endTransfer(src, transfer, modeString, revOp, CM, restrictedMode);
608 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
613 const std::string* prefix,
618 std::ostringstream os;
619 os << *prefix <<
"Realloc (if needed) imports_ from "
620 << imports_.extent (0) <<
" to " << newSize << std::endl;
621 std::cerr << os.str ();
624 const bool reallocated =
627 std::ostringstream os;
628 os << *prefix <<
"Finished realloc'ing imports_" << std::endl;
629 std::cerr << os.str ();
634 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
638 const size_t numImportLIDs)
648 constexpr
size_t tooBigFactor = 10;
650 const bool verbose = Behavior::verbose(
"DistObject");
651 std::unique_ptr<std::string> prefix;
653 prefix = this->createPrefix(
"DistObject",
654 "reallocArraysForNumPacketsPerLid");
655 std::ostringstream os;
657 <<
"numExportLIDs: " << numExportLIDs
658 <<
", numImportLIDs: " << numImportLIDs
660 os << *prefix <<
"DualView status before:" << endl
663 "numExportPacketsPerLID_")
667 "numImportPacketsPerLID_")
669 std::cerr << os.str ();
673 const bool firstReallocated =
676 "numExportPacketsPerLID",
683 const bool needFenceBeforeNextAlloc = ! firstReallocated;
684 const bool secondReallocated =
687 "numImportPacketsPerLID",
689 needFenceBeforeNextAlloc);
692 std::ostringstream os;
693 os << *prefix <<
"DualView status after:" << endl
695 "numExportPacketsPerLID_")
698 "numImportPacketsPerLID_")
700 std::cerr << os.str ();
703 return firstReallocated || secondReallocated;
706 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
710 const ::Tpetra::Details::Transfer<local_ordinal_type, global_ordinal_type, node_type>& transfer,
711 const char modeString[],
720 using Kokkos::Compat::getArrayView;
721 using Kokkos::Compat::getConstArrayView;
722 using Kokkos::Compat::getKokkosViewDeepCopy;
723 using Kokkos::Compat::create_const_view;
728 const bool commOnHost = ! Behavior::assumeMpiIsGPUAware ();
729 const char funcNameHost[] =
"Tpetra::DistObject::beginTransfer[Host]";
730 const char funcNameDevice[] =
"Tpetra::DistObject::beginTransfer[Device]";
731 const char *funcName = commOnHost ? funcNameHost : funcNameDevice;
733 ProfilingRegion region_doTransfer(funcName);
734 const bool verbose = Behavior::verbose(
"DistObject");
735 std::shared_ptr<std::string> prefix;
737 std::ostringstream os;
738 prefix = this->createPrefix(
"DistObject",
"doTransfer");
739 os << *prefix <<
"Source type: " << Teuchos::typeName(src)
740 <<
", Target type: " << Teuchos::typeName(*
this) << endl;
741 std::cerr << os.str();
754 const bool debug = Behavior::debug(
"DistObject");
756 if (! restrictedMode && revOp == DoForward) {
757 const bool myMapSameAsTransferTgtMap =
758 this->getMap ()->isSameAs (* (transfer.getTargetMap ()));
759 TEUCHOS_TEST_FOR_EXCEPTION
760 (! myMapSameAsTransferTgtMap, std::invalid_argument,
761 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
762 "communication, the target DistObject's Map must be the same "
763 "(in the sense of Tpetra::Map::isSameAs) as the input "
764 "Export/Import object's target Map.");
766 else if (! restrictedMode && revOp == DoReverse) {
767 const bool myMapSameAsTransferSrcMap =
768 this->getMap ()->isSameAs (* (transfer.getSourceMap ()));
769 TEUCHOS_TEST_FOR_EXCEPTION
770 (! myMapSameAsTransferSrcMap, std::invalid_argument,
771 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
772 "communication, the target DistObject's Map must be the same "
773 "(in the sense of Tpetra::Map::isSameAs) as the input "
774 "Export/Import object's source Map.");
776 else if (restrictedMode && revOp == DoForward) {
777 const bool myMapLocallyFittedTransferTgtMap =
778 this->getMap ()->isLocallyFitted (* (transfer.getTargetMap ()));
779 TEUCHOS_TEST_FOR_EXCEPTION
780 (! myMapLocallyFittedTransferTgtMap , std::invalid_argument,
781 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
782 "communication using restricted mode, Export/Import object's "
783 "target Map must be locally fitted (in the sense of "
784 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
787 const bool myMapLocallyFittedTransferSrcMap =
788 this->getMap ()->isLocallyFitted (* (transfer.getSourceMap ()));
789 TEUCHOS_TEST_FOR_EXCEPTION
790 (! myMapLocallyFittedTransferSrcMap, std::invalid_argument,
791 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
792 "communication using restricted mode, Export/Import object's "
793 "source Map must be locally fitted (in the sense of "
794 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
801 if (srcDistObj !=
nullptr) {
802 if (revOp == DoForward) {
803 const bool srcMapSameAsImportSrcMap =
804 srcDistObj->
getMap ()->isSameAs (* (transfer.getSourceMap ()));
805 TEUCHOS_TEST_FOR_EXCEPTION
806 (! srcMapSameAsImportSrcMap, std::invalid_argument,
807 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
808 "communication, the source DistObject's Map must be the same "
809 "as the input Export/Import object's source Map.");
812 const bool srcMapSameAsImportTgtMap =
813 srcDistObj->
getMap ()->isSameAs (* (transfer.getTargetMap ()));
814 TEUCHOS_TEST_FOR_EXCEPTION
815 (! srcMapSameAsImportTgtMap, std::invalid_argument,
816 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
817 "communication, the source DistObject's Map must be the same "
818 "as the input Export/Import object's target Map.");
823 const size_t numSameIDs = transfer.getNumSameIDs ();
827 TEUCHOS_TEST_FOR_EXCEPTION
828 (debug && restrictedMode &&
829 (transfer.getPermuteToLIDs_dv().extent(0) != 0 ||
830 transfer.getPermuteFromLIDs_dv().extent(0) != 0),
831 std::invalid_argument,
832 "Tpetra::DistObject::" << modeString <<
": Transfer object "
833 "cannot have permutes in restricted mode.");
837 std::ostringstream os;
838 os << *prefix <<
"doTransfer: Use new interface; "
839 "commOnHost=" << (commOnHost ?
"true" :
"false") << endl;
840 std::cerr << os.str ();
843 using const_lo_dv_type =
844 Kokkos::DualView<const local_ordinal_type*, buffer_device_type>;
845 const_lo_dv_type permuteToLIDs = (revOp == DoForward) ?
846 transfer.getPermuteToLIDs_dv () :
847 transfer.getPermuteFromLIDs_dv ();
848 const_lo_dv_type permuteFromLIDs = (revOp == DoForward) ?
849 transfer.getPermuteFromLIDs_dv () :
850 transfer.getPermuteToLIDs_dv ();
851 const_lo_dv_type remoteLIDs = (revOp == DoForward) ?
852 transfer.getRemoteLIDs_dv () :
853 transfer.getExportLIDs_dv ();
854 const_lo_dv_type exportLIDs = (revOp == DoForward) ?
855 transfer.getExportLIDs_dv () :
856 transfer.getRemoteLIDs_dv ();
857 const bool canTryAliasing = (revOp == DoForward) ?
858 transfer.areRemoteLIDsContiguous() :
859 transfer.areExportLIDsContiguous();
862 ProfilingRegion region_dTN(funcName);
865 std::ostringstream os;
866 os << *prefix <<
"Input arguments:" << endl
868 << *prefix <<
" numSameIDs: " << numSameIDs << endl
877 << *prefix <<
" revOp: Do" << (revOp == DoReverse ?
"Reverse" :
"Forward") << endl
878 << *prefix <<
" commOnHost: " << (commOnHost ?
"true" :
"false") << endl;
879 std::cerr << os.str ();
883 ProfilingRegion region_cs (
"Tpetra::DistObject::beginTransfer::checkSizes");
885 std::ostringstream os;
886 os << *prefix <<
"1. checkSizes" << endl;
887 std::cerr << os.str ();
889 const bool checkSizesResult = this->checkSizes (src);
890 TEUCHOS_TEST_FOR_EXCEPTION
891 (! checkSizesResult, std::invalid_argument,
892 "Tpetra::DistObject::doTransfer: checkSizes() indicates that the "
893 "destination object is not a legal target for redistribution from the "
894 "source object. This probably means that they do not have the same "
895 "dimensions. For example, MultiVectors must have the same number of "
896 "rows and columns.");
907 size_t constantNumPackets = this->constantNumberOfPackets ();
909 std::ostringstream os;
910 os << *prefix <<
"constantNumPackets=" << constantNumPackets << endl;
911 std::cerr << os.str ();
915 bool needCommunication =
true;
921 if (revOp == DoReverse && ! this->isDistributed ()) {
922 needCommunication =
false;
931 else if (revOp == DoForward && srcDistObj != NULL &&
933 needCommunication =
false;
937 needCommunication =
false;
996 const bool overlapTransferSteps = (constantNumPackets != 0) && Behavior::enableGranularTransfers();
999 std::ostringstream os;
1000 os << *prefix <<
"overlapTransferSteps=" << overlapTransferSteps << endl;
1001 std::cerr << os.str ();
1005 const bool thereAreIDsToCopy = (numSameIDs + permuteToLIDs.extent (0) != 0);
1006 const bool needCopyAndPermute = (!restrictedMode && thereAreIDsToCopy);
1008 if ( ! overlapTransferSteps ) {
1017 if ( needCopyAndPermute ) {
1021 std::ostringstream os;
1022 os << *prefix <<
"2. copyAndPermute" << endl;
1023 std::cerr << os.str ();
1026 ProfilingRegion region_cp (
"Tpetra::DistObject::beginTransfer::copyAndPermute");
1028 this->copyAndPermute (src, numSameIDs, permuteToLIDs, permuteFromLIDs, CM);
1031 std::ostringstream os;
1032 os << *prefix <<
"After copyAndPermute:" << endl
1039 std::cerr << os.str ();
1043 if ( ! needCommunication ) {
1045 std::ostringstream os;
1046 os << *prefix <<
"Comm not needed; skipping" << endl;
1047 std::cerr << os.str ();
1054 if (constantNumPackets == 0) {
1056 std::ostringstream os;
1057 os << *prefix <<
"3. (Re)allocate num{Ex,Im}portPacketsPerLID"
1059 std::cerr << os.str ();
1063 this->reallocArraysForNumPacketsPerLid (exportLIDs.extent (0),
1064 remoteLIDs.extent (0));
1068 std::ostringstream os;
1069 os << *prefix <<
"4. packAndPrepare: before, "
1072 std::cerr << os.str ();
1075 doPackAndPrepare(src, exportLIDs, constantNumPackets,
execution_space());
1077 this->exports_.sync_host();
1080 this->exports_.sync_device();
1084 std::ostringstream os;
1085 os << *prefix <<
"5.1. After packAndPrepare, "
1088 std::cerr << os.str ();
1093 if (constantNumPackets != 0) {
1094 ProfilingRegion region_reallocImportsIfNeeded(
"Tpetra::DistObject::beginTransfer::reallocImportsIfNeeded");
1100 const size_t rbufLen = remoteLIDs.extent (0) * constantNumPackets;
1101 reallocImportsIfNeeded (rbufLen, verbose, prefix.get (), canTryAliasing, CM);
1110 std::ostringstream os;
1111 os << *prefix <<
"7.0. "
1112 << (revOp == DoReverse ?
"Reverse" :
"Forward")
1114 std::cerr << os.str ();
1117 doPostRecvs(distributorPlan, constantNumPackets, commOnHost, prefix, canTryAliasing, CM);
1122 doPostSends(distributorPlan, constantNumPackets, commOnHost, prefix);
1130 if ( ! needCommunication ) {
1132 std::ostringstream os;
1133 os << *prefix <<
"Comm not needed; skipping" << endl;
1134 std::cerr << os.str ();
1144 if (constantNumPackets != 0) {
1145 ProfilingRegion region_reallocImportsIfNeeded(
"Tpetra::DistObject::beginTransfer::reallocImportsIfNeeded");
1151 const size_t rbufLen = remoteLIDs.extent (0) * constantNumPackets;
1152 reallocImportsIfNeeded (rbufLen, verbose, prefix.get (), canTryAliasing, CM);
1158 std::ostringstream os;
1159 os << *prefix <<
"7.0. "
1160 << (revOp == DoReverse ?
"Reverse" :
"Forward")
1162 std::cerr << os.str ();
1165 doPostRecvs(distributorPlan, constantNumPackets, commOnHost, prefix, canTryAliasing, CM);
1170 if (constantNumPackets == 0) {
1172 std::ostringstream os;
1173 os << *prefix <<
"3. (Re)allocate num{Ex,Im}portPacketsPerLID"
1175 std::cerr << os.str ();
1179 this->reallocArraysForNumPacketsPerLid (exportLIDs.extent (0),
1180 remoteLIDs.extent (0));
1184 std::ostringstream os;
1185 os << *prefix <<
"4. packAndPrepare: before, "
1188 std::cerr << os.str ();
1191 doPackAndPrepare(src, exportLIDs, constantNumPackets,
execution_space());
1194 this->exports_.sync_host();
1197 this->exports_.sync_device();
1201 std::ostringstream os;
1202 os << *prefix <<
"5.1. After packAndPrepare, "
1205 std::cerr << os.str ();
1211 doPostSends(distributorPlan, constantNumPackets, commOnHost, prefix);
1222 if ( needCopyAndPermute ) {
1225 std::ostringstream os;
1226 os << *prefix <<
"2. copyAndPermute" << endl;
1227 std::cerr << os.str ();
1231 ProfilingRegion region_cp(
"Tpetra::DistObject::beginTransfer::copyAndPermute");
1233 this->copyAndPermute (src, numSameIDs, permuteToLIDs, permuteFromLIDs, CM);
1237 std::ostringstream os;
1238 os << *prefix <<
"After copyAndPermute:" << endl
1245 std::cerr << os.str ();
1251 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1255 const ::Tpetra::Details::Transfer<local_ordinal_type, global_ordinal_type, node_type>& transfer,
1256 const char modeString[],
1257 const ReverseOption revOp,
1259 bool restrictedMode)
1265 using Kokkos::Compat::getArrayView;
1266 using Kokkos::Compat::getConstArrayView;
1267 using Kokkos::Compat::getKokkosViewDeepCopy;
1268 using Kokkos::Compat::create_const_view;
1273 const bool commOnHost = ! Behavior::assumeMpiIsGPUAware ();
1274 const char funcNameHost[] =
"Tpetra::DistObject::endTransfer[Host]";
1275 const char funcNameDevice[] =
"Tpetra::DistObject::endTransfer[Device]";
1276 const char *funcName = commOnHost ? funcNameHost : funcNameDevice;
1277 ProfilingRegion region_doTransfer(funcName);
1278 const bool verbose = Behavior::verbose(
"DistObject");
1279 std::shared_ptr<std::string> prefix;
1281 std::ostringstream os;
1282 prefix = this->createPrefix(
"DistObject",
"doTransfer");
1283 os << *prefix <<
"Source type: " << Teuchos::typeName(src)
1284 <<
", Target type: " << Teuchos::typeName(*
this) << endl;
1285 std::cerr << os.str();
1298 const bool debug = Behavior::debug(
"DistObject");
1300 if (! restrictedMode && revOp == DoForward) {
1301 const bool myMapSameAsTransferTgtMap =
1302 this->getMap ()->isSameAs (* (transfer.getTargetMap ()));
1303 TEUCHOS_TEST_FOR_EXCEPTION
1304 (! myMapSameAsTransferTgtMap, std::invalid_argument,
1305 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
1306 "communication, the target DistObject's Map must be the same "
1307 "(in the sense of Tpetra::Map::isSameAs) as the input "
1308 "Export/Import object's target Map.");
1310 else if (! restrictedMode && revOp == DoReverse) {
1311 const bool myMapSameAsTransferSrcMap =
1312 this->getMap ()->isSameAs (* (transfer.getSourceMap ()));
1313 TEUCHOS_TEST_FOR_EXCEPTION
1314 (! myMapSameAsTransferSrcMap, std::invalid_argument,
1315 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
1316 "communication, the target DistObject's Map must be the same "
1317 "(in the sense of Tpetra::Map::isSameAs) as the input "
1318 "Export/Import object's source Map.");
1320 else if (restrictedMode && revOp == DoForward) {
1321 const bool myMapLocallyFittedTransferTgtMap =
1322 this->getMap ()->isLocallyFitted (* (transfer.getTargetMap ()));
1323 TEUCHOS_TEST_FOR_EXCEPTION
1324 (! myMapLocallyFittedTransferTgtMap , std::invalid_argument,
1325 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
1326 "communication using restricted mode, Export/Import object's "
1327 "target Map must be locally fitted (in the sense of "
1328 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
1331 const bool myMapLocallyFittedTransferSrcMap =
1332 this->getMap ()->isLocallyFitted (* (transfer.getSourceMap ()));
1333 TEUCHOS_TEST_FOR_EXCEPTION
1334 (! myMapLocallyFittedTransferSrcMap, std::invalid_argument,
1335 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
1336 "communication using restricted mode, Export/Import object's "
1337 "source Map must be locally fitted (in the sense of "
1338 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
1344 const this_type* srcDistObj =
dynamic_cast<const this_type*
> (&src);
1345 if (srcDistObj !=
nullptr) {
1346 if (revOp == DoForward) {
1347 const bool srcMapSameAsImportSrcMap =
1348 srcDistObj->getMap ()->isSameAs (* (transfer.getSourceMap ()));
1349 TEUCHOS_TEST_FOR_EXCEPTION
1350 (! srcMapSameAsImportSrcMap, std::invalid_argument,
1351 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
1352 "communication, the source DistObject's Map must be the same "
1353 "as the input Export/Import object's source Map.");
1356 const bool srcMapSameAsImportTgtMap =
1357 srcDistObj->getMap ()->isSameAs (* (transfer.getTargetMap ()));
1358 TEUCHOS_TEST_FOR_EXCEPTION
1359 (! srcMapSameAsImportTgtMap, std::invalid_argument,
1360 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
1361 "communication, the source DistObject's Map must be the same "
1362 "as the input Export/Import object's target Map.");
1367 Distributor& distor = transfer.getDistributor ();
1368 const Details::DistributorPlan& distributorPlan = (revOp == DoForward) ? distor.getPlan() : *distor.getPlan().getReversePlan();
1370 TEUCHOS_TEST_FOR_EXCEPTION
1371 (debug && restrictedMode &&
1372 (transfer.getPermuteToLIDs_dv().extent(0) != 0 ||
1373 transfer.getPermuteFromLIDs_dv().extent(0) != 0),
1374 std::invalid_argument,
1375 "Tpetra::DistObject::" << modeString <<
": Transfer object "
1376 "cannot have permutes in restricted mode.");
1380 std::ostringstream os;
1381 os << *prefix <<
"doTransfer: Use new interface; "
1382 "commOnHost=" << (commOnHost ?
"true" :
"false") << endl;
1383 std::cerr << os.str ();
1386 using const_lo_dv_type =
1387 Kokkos::DualView<const local_ordinal_type*, buffer_device_type>;
1388 const_lo_dv_type remoteLIDs = (revOp == DoForward) ?
1389 transfer.getRemoteLIDs_dv () :
1390 transfer.getExportLIDs_dv ();
1392 size_t constantNumPackets = this->constantNumberOfPackets ();
1397 bool needCommunication =
true;
1400 const this_type* srcDistObj =
dynamic_cast<const this_type*
> (&src);
1402 if (revOp == DoReverse && ! this->isDistributed ()) {
1403 needCommunication =
false;
1412 else if (revOp == DoForward && srcDistObj != NULL &&
1413 ! srcDistObj->isDistributed ()) {
1414 needCommunication =
false;
1417 if (! needCommunication) {
1419 std::ostringstream os;
1420 os << *prefix <<
"Comm not needed; skipping" << endl;
1421 std::cerr << os.str ();
1425 distributorActor_.doWaitsRecv(distributorPlan);
1428 std::ostringstream os;
1429 os << *prefix <<
"8. unpackAndCombine - remoteLIDs " << remoteLIDs.extent(0) <<
", constantNumPackets " << constantNumPackets << endl;
1430 std::cerr << os.str ();
1432 doUnpackAndCombine(remoteLIDs, constantNumPackets, CM, execution_space());
1434 distributorActor_.doWaitsSend(distributorPlan);
1439 std::ostringstream os;
1440 os << *prefix <<
"9. Done!" << endl;
1441 std::cerr << os.str ();
1445 std::ostringstream os;
1446 os << *prefix <<
"Tpetra::DistObject::doTransfer: Done!" << endl;
1447 std::cerr << os.str ();
1451 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1453 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1454 doPostRecvs(
const Details::DistributorPlan& distributorPlan,
1455 size_t constantNumPackets,
1457 std::shared_ptr<std::string> prefix,
1458 const bool canTryAliasing,
1463 using Kokkos::Compat::create_const_view;
1465 using Details::ProfilingRegion;
1467 const char funcNameHost[] =
"Tpetra::DistObject::doPostRecvs[Host]";
1468 const char funcNameDevice[] =
"Tpetra::DistObject::doPostRecvs[Device]";
1469 const char *funcName = commOnHost ? funcNameHost : funcNameDevice;
1470 ProfilingRegion region_dpr (funcName);
1474 if (constantNumPackets == 0) {
1476 std::ostringstream os;
1477 os << *prefix <<
"7.1. Variable # packets / LID: first comm "
1478 <<
"(commOnHost = " << (commOnHost ?
"true" :
"false") <<
")"
1480 std::cerr << os.str ();
1482 size_t totalImportPackets = 0;
1484 if (this->numExportPacketsPerLID_.need_sync_host ()) {
1485 this->numExportPacketsPerLID_.sync_host ();
1487 if (this->numImportPacketsPerLID_.need_sync_host ()) {
1488 this->numImportPacketsPerLID_.sync_host ();
1490 this->numImportPacketsPerLID_.modify_host ();
1492 create_const_view (this->numExportPacketsPerLID_.view_host ());
1493 auto numImp_h = this->numImportPacketsPerLID_.view_host ();
1497 std::ostringstream os;
1498 os << *prefix <<
"Call doPostsAndWaits"
1500 std::cerr << os.str ();
1502 distributorActor_.doPostsAndWaits(distributorPlan, numExp_h, 1, numImp_h);
1505 std::ostringstream os;
1506 os << *prefix <<
"Count totalImportPackets" << std::endl;
1507 std::cerr << os.str ();
1509 using the_dev_type =
typename decltype (numImp_h)::device_type;
1510 totalImportPackets = countTotalImportPackets<the_dev_type> (numImp_h);
1513 this->numExportPacketsPerLID_.sync_device ();
1514 this->numImportPacketsPerLID_.sync_device ();
1515 this->numImportPacketsPerLID_.modify_device ();
1516 auto numExp_d = create_const_view
1517 (this->numExportPacketsPerLID_.view_device ());
1518 auto numImp_d = this->numImportPacketsPerLID_.view_device ();
1522 std::ostringstream os;
1523 os << *prefix <<
"Call doPostsAndWaits"
1525 std::cerr << os.str ();
1528 distributorActor_.doPostsAndWaits(distributorPlan, numExp_d, 1, numImp_d);
1531 std::ostringstream os;
1532 os << *prefix <<
"Count totalImportPackets" << std::endl;
1533 std::cerr << os.str ();
1535 using the_dev_type =
typename decltype (numImp_d)::device_type;
1536 totalImportPackets = countTotalImportPackets<the_dev_type> (numImp_d);
1540 std::ostringstream os;
1541 os << *prefix <<
"totalImportPackets=" << totalImportPackets << endl;
1542 std::cerr << os.str ();
1544 this->reallocImportsIfNeeded (totalImportPackets, verbose,
1545 prefix.get (), canTryAliasing, CM);
1547 std::ostringstream os;
1548 os << *prefix <<
"7.3. Second comm" << std::endl;
1549 std::cerr << os.str ();
1555 this->numImportPacketsPerLID_.sync_host ();
1564 auto numImportPacketsPerLID_av =
1572 this->imports_.clear_sync_state ();
1575 std::ostringstream os;
1576 os << *prefix <<
"Comm on "
1577 << (commOnHost ?
"host" :
"device")
1578 <<
"; call doPostRecvs" << endl;
1579 std::cerr << os.str ();
1583 this->imports_.modify_host ();
1584 distributorActor_.doPostRecvs
1586 this->imports_.view_host (),
1587 numImportPacketsPerLID_av);
1590 this->imports_.modify_device ();
1591 distributorActor_.doPostRecvs
1593 this->imports_.view_device (),
1594 numImportPacketsPerLID_av);
1599 std::ostringstream os;
1600 os << *prefix <<
"7.1. Const # packets per LID: " << endl
1607 std::cerr << os.str ();
1614 this->imports_.clear_sync_state ();
1617 std::ostringstream os;
1618 os << *prefix <<
"7.2. Comm on "
1619 << (commOnHost ?
"host" :
"device")
1620 <<
"; call doPostRecvs" << endl;
1621 std::cerr << os.str ();
1624 this->imports_.modify_host ();
1625 distributorActor_.doPostRecvs
1628 this->imports_.view_host ());
1631 this->imports_.modify_device ();
1632 distributorActor_.doPostRecvs
1635 this->imports_.view_device ());
1640 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1642 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1643 doPostSends(
const Details::DistributorPlan& distributorPlan,
1644 size_t constantNumPackets,
1646 std::shared_ptr<std::string> prefix)
1649 using Kokkos::Compat::create_const_view;
1651 using Details::ProfilingRegion;
1653 const char funcNameHost[] =
"Tpetra::DistObject::doPostSends[Host]";
1654 const char funcNameDevice[] =
"Tpetra::DistObject::doPostSends[Device]";
1655 const char *funcName = commOnHost ? funcNameHost : funcNameDevice;
1656 ProfilingRegion region_dps (funcName);
1660 std::ostringstream os;
1661 os << *prefix <<
"Comm on "
1662 << (commOnHost ?
"host" :
"device")
1663 <<
"; call doPostSends" << endl;
1664 std::cerr << os.str ();
1667 if (constantNumPackets == 0) {
1671 this->numExportPacketsPerLID_.sync_host ();
1672 this->numImportPacketsPerLID_.sync_host ();
1681 auto numExportPacketsPerLID_av =
1683 auto numImportPacketsPerLID_av =
1687 distributorActor_.doPostSends
1689 create_const_view (this->exports_.view_host ()),
1690 numExportPacketsPerLID_av,
1691 this->imports_.view_host (),
1692 numImportPacketsPerLID_av);
1696 Kokkos::fence(
"DistObject::doPostSends-1");
1697 distributorActor_.doPostSends
1699 create_const_view (this->exports_.view_device ()),
1700 numExportPacketsPerLID_av,
1701 this->imports_.view_device (),
1702 numImportPacketsPerLID_av);
1707 distributorActor_.doPostSends
1709 create_const_view (this->exports_.view_host ()),
1711 this->imports_.view_host ());
1715 Kokkos::fence(
"DistObject::doPostSends-2");
1716 distributorActor_.doPostSends
1718 create_const_view (this->exports_.view_device ()),
1720 this->imports_.view_device ());
1725 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1727 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1728 doPackAndPrepare(
const SrcDistObject& src,
1729 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& exportLIDs,
1730 size_t& constantNumPackets,
1731 const execution_space &space)
1733 using Details::ProfilingRegion;
1737 ProfilingRegion region_pp
1738 (
"Tpetra::DistObject::doPackAndPrepare");
1757 std::ostringstream lclErrStrm;
1758 bool lclSuccess =
false;
1760 this->packAndPrepare (src, exportLIDs, this->exports_,
1761 this->numExportPacketsPerLID_,
1762 constantNumPackets, space);
1765 catch (std::exception& e) {
1766 lclErrStrm <<
"packAndPrepare threw an exception: "
1767 << endl << e.what();
1770 lclErrStrm <<
"packAndPrepare threw an exception "
1771 "not a subclass of std::exception.";
1773 const char gblErrMsgHeader[] =
"Tpetra::DistObject "
1774 "threw an exception in packAndPrepare on "
1775 "one or more processes in the DistObject's communicator.";
1776 auto comm = getMap()->getComm();
1777 Details::checkGlobalError(std::cerr, lclSuccess,
1778 lclErrStrm.str().c_str(),
1779 gblErrMsgHeader, *comm);
1782 this->packAndPrepare (src, exportLIDs, this->exports_,
1783 this->numExportPacketsPerLID_,
1784 constantNumPackets, space);
1788 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1790 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1791 doUnpackAndCombine(
const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& remoteLIDs,
1792 size_t constantNumPackets,
1794 const execution_space &space)
1796 using Details::ProfilingRegion;
1800 ProfilingRegion region_uc
1801 (
"Tpetra::DistObject::doUnpackAndCombine");
1804 std::ostringstream lclErrStrm;
1805 bool lclSuccess =
false;
1807 this->unpackAndCombine (remoteLIDs, this->imports_,
1808 this->numImportPacketsPerLID_,
1809 constantNumPackets, CM, space);
1812 catch (std::exception& e) {
1813 lclErrStrm <<
"doUnpackAndCombine threw an exception: "
1814 << endl << e.what();
1817 lclErrStrm <<
"doUnpackAndCombine threw an exception "
1818 "not a subclass of std::exception.";
1820 const char gblErrMsgHeader[] =
"Tpetra::DistObject "
1821 "threw an exception in unpackAndCombine on "
1822 "one or more processes in the DistObject's communicator.";
1823 auto comm = getMap()->getComm();
1824 Details::checkGlobalError(std::cerr, lclSuccess,
1825 lclErrStrm.str().c_str(),
1826 gblErrMsgHeader, *comm);
1829 this->unpackAndCombine (remoteLIDs, this->imports_,
1830 this->numImportPacketsPerLID_,
1831 constantNumPackets, CM, space);
1835 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1841 const Kokkos::DualView<
1844 const Kokkos::DualView<
1851 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1854 const Kokkos::DualView<const local_ordinal_type *, buffer_device_type>
1856 const Kokkos::DualView<const local_ordinal_type *, buffer_device_type>
1870 copyAndPermute(source, numSameIDs, permuteToLIDs, permuteFromLIDs,
1878 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1883 const Kokkos::DualView<
1896 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1899 const Kokkos::DualView<const local_ordinal_type *, buffer_device_type>
1901 Kokkos::DualView<packet_type *, buffer_device_type> &exports,
1902 Kokkos::DualView<size_t *, buffer_device_type> numPacketsPerLID,
1920 packAndPrepare(source, exportLIDs, exports, numPacketsPerLID,
1921 constantNumPackets);
1929 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1933 (
const Kokkos::DualView<
1947 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1949 const Kokkos::DualView<const local_ordinal_type *, buffer_device_type>
1951 Kokkos::DualView<packet_type *, buffer_device_type> imports,
1952 Kokkos::DualView<size_t *, buffer_device_type> numPacketsPerLID,
1953 const size_t constantNumPackets,
const CombineMode combineMode,
1954 const execution_space &space) {
1958 unpackAndCombine(importLIDs, imports, numPacketsPerLID, constantNumPackets,
1962 execution_space().fence();
1967 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1969 std::ostream &os)
const {
1971 using Teuchos::FancyOStream;
1972 using Teuchos::getFancyOStream;
1974 using Teuchos::rcpFromRef;
1976 RCP<FancyOStream> out = getFancyOStream(rcpFromRef(os));
1977 this->describe(*out, Teuchos::VERB_DEFAULT);
1980 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1981 std::unique_ptr<std::string>
1983 const char className[],
const char methodName[])
const {
1984 auto map = this->getMap();
1985 auto comm = map.is_null() ? Teuchos::null : map->getComm();
1989 template <
class DistObjectType>
1991 Teuchos::RCP<DistObjectType> &input,
1992 const Teuchos::RCP<
const Map<
typename DistObjectType::local_ordinal_type,
1993 typename DistObjectType::global_ordinal_type,
1994 typename DistObjectType::node_type>> &newMap) {
1995 input->removeEmptyProcessesInPlace(newMap);
1996 if (newMap.is_null()) {
1997 input = Teuchos::null;
2001 template <
class DistObjectType>
2003 auto newMap = input->getMap()->removeEmptyProcesses();
2004 removeEmptyProcessesInPlace<DistObjectType>(input, newMap);
2008 #define TPETRA_DISTOBJECT_INSTANT(SCALAR, LO, GO, NODE) \
2009 template class DistObject<SCALAR, LO, GO, NODE>;
2013 #define TPETRA_DISTOBJECT_INSTANT_CHAR(LO, GO, NODE) \
2014 template class DistObject<char, LO, GO, NODE>;
2018 #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.