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_.doWaits(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());
1319 std::ostringstream os;
1320 os << *prefix <<
"9. Done!" << endl;
1321 std::cerr << os.str ();
1325 std::ostringstream os;
1326 os << *prefix <<
"Tpetra::DistObject::doTransfer: Done!" << endl;
1327 std::cerr << os.str ();
1331 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1333 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1334 doPosts(
const Details::DistributorPlan& distributorPlan,
1335 size_t constantNumPackets,
1337 std::shared_ptr<std::string> prefix,
1338 const bool canTryAliasing,
1343 using Kokkos::Compat::create_const_view;
1348 if (constantNumPackets == 0) {
1350 std::ostringstream os;
1351 os << *prefix <<
"7.1. Variable # packets / LID: first comm "
1352 <<
"(commOnHost = " << (commOnHost ?
"true" :
"false") <<
")"
1354 std::cerr << os.str ();
1356 size_t totalImportPackets = 0;
1358 if (this->numExportPacketsPerLID_.need_sync_host ()) {
1359 this->numExportPacketsPerLID_.sync_host ();
1361 if (this->numImportPacketsPerLID_.need_sync_host ()) {
1362 this->numImportPacketsPerLID_.sync_host ();
1364 this->numImportPacketsPerLID_.modify_host ();
1366 create_const_view (this->numExportPacketsPerLID_.view_host ());
1367 auto numImp_h = this->numImportPacketsPerLID_.view_host ();
1371 std::ostringstream os;
1372 os << *prefix <<
"Call doPostsAndWaits"
1374 std::cerr << os.str ();
1376 distributorActor_.doPostsAndWaits(distributorPlan, numExp_h, 1, numImp_h);
1379 std::ostringstream os;
1380 os << *prefix <<
"Count totalImportPackets" << std::endl;
1381 std::cerr << os.str ();
1383 using the_dev_type =
typename decltype (numImp_h)::device_type;
1384 totalImportPackets = countTotalImportPackets<the_dev_type> (numImp_h);
1387 this->numExportPacketsPerLID_.sync_device ();
1388 this->numImportPacketsPerLID_.sync_device ();
1389 this->numImportPacketsPerLID_.modify_device ();
1390 auto numExp_d = create_const_view
1391 (this->numExportPacketsPerLID_.view_device ());
1392 auto numImp_d = this->numImportPacketsPerLID_.view_device ();
1396 std::ostringstream os;
1397 os << *prefix <<
"Call doPostsAndWaits"
1399 std::cerr << os.str ();
1402 distributorActor_.doPostsAndWaits(distributorPlan, numExp_d, 1, numImp_d);
1405 std::ostringstream os;
1406 os << *prefix <<
"Count totalImportPackets" << std::endl;
1407 std::cerr << os.str ();
1409 using the_dev_type =
typename decltype (numImp_d)::device_type;
1410 totalImportPackets = countTotalImportPackets<the_dev_type> (numImp_d);
1414 std::ostringstream os;
1415 os << *prefix <<
"totalImportPackets=" << totalImportPackets << endl;
1416 std::cerr << os.str ();
1418 this->reallocImportsIfNeeded (totalImportPackets, verbose,
1419 prefix.get (), canTryAliasing, CM);
1421 std::ostringstream os;
1422 os << *prefix <<
"7.3. Second comm" << std::endl;
1423 std::cerr << os.str ();
1429 this->numExportPacketsPerLID_.sync_host ();
1430 this->numImportPacketsPerLID_.sync_host ();
1439 auto numExportPacketsPerLID_av =
1441 auto numImportPacketsPerLID_av =
1449 this->imports_.clear_sync_state ();
1452 std::ostringstream os;
1453 os << *prefix <<
"Comm on "
1454 << (commOnHost ?
"host" :
"device")
1455 <<
"; call doPosts" << endl;
1456 std::cerr << os.str ();
1460 this->imports_.modify_host ();
1461 distributorActor_.doPosts
1463 create_const_view (this->exports_.view_host ()),
1464 numExportPacketsPerLID_av,
1465 this->imports_.view_host (),
1466 numImportPacketsPerLID_av);
1469 Kokkos::fence(
"DistObject::doPosts-1");
1470 this->imports_.modify_device ();
1471 distributorActor_.doPosts
1473 create_const_view (this->exports_.view_device ()),
1474 numExportPacketsPerLID_av,
1475 this->imports_.view_device (),
1476 numImportPacketsPerLID_av);
1481 std::ostringstream os;
1482 os << *prefix <<
"7.1. Const # packets per LID: " << endl
1489 std::cerr << os.str ();
1496 this->imports_.clear_sync_state ();
1499 std::ostringstream os;
1500 os << *prefix <<
"7.2. Comm on "
1501 << (commOnHost ?
"host" :
"device")
1502 <<
"; call doPosts" << endl;
1503 std::cerr << os.str ();
1506 this->imports_.modify_host ();
1507 distributorActor_.doPosts
1509 create_const_view (this->exports_.view_host ()),
1511 this->imports_.view_host ());
1514 Kokkos::fence(
"DistObject::doPosts-2");
1515 this->imports_.modify_device ();
1516 distributorActor_.doPosts
1518 create_const_view (this->exports_.view_device ()),
1520 this->imports_.view_device ());
1525 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1527 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1528 doPackAndPrepare(
const SrcDistObject& src,
1529 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& exportLIDs,
1530 size_t& constantNumPackets,
1531 const execution_space &space)
1533 using Details::ProfilingRegion;
1537 ProfilingRegion region_pp
1538 (
"Tpetra::DistObject::doPackAndPrepare");
1539 #ifdef HAVE_TPETRA_TRANSFER_TIMERS
1542 Teuchos::TimeMonitor packAndPrepareMon (*packAndPrepareTimer_);
1543 #endif // HAVE_TPETRA_TRANSFER_TIMERS
1562 std::ostringstream lclErrStrm;
1563 bool lclSuccess =
false;
1565 this->packAndPrepare (src, exportLIDs, this->exports_,
1566 this->numExportPacketsPerLID_,
1567 constantNumPackets, space);
1570 catch (std::exception& e) {
1571 lclErrStrm <<
"packAndPrepare threw an exception: "
1572 << endl << e.what();
1575 lclErrStrm <<
"packAndPrepare threw an exception "
1576 "not a subclass of std::exception.";
1578 const char gblErrMsgHeader[] =
"Tpetra::DistObject "
1579 "threw an exception in packAndPrepare on "
1580 "one or more processes in the DistObject's communicator.";
1581 auto comm = getMap()->getComm();
1582 Details::checkGlobalError(std::cerr, lclSuccess,
1583 lclErrStrm.str().c_str(),
1584 gblErrMsgHeader, *comm);
1587 this->packAndPrepare (src, exportLIDs, this->exports_,
1588 this->numExportPacketsPerLID_,
1589 constantNumPackets, space);
1593 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1595 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1596 doUnpackAndCombine(
const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& remoteLIDs,
1597 size_t constantNumPackets,
1599 const execution_space &space)
1601 using Details::ProfilingRegion;
1605 ProfilingRegion region_uc
1606 (
"Tpetra::DistObject::doUnpackAndCombine");
1607 #ifdef HAVE_TPETRA_TRANSFER_TIMERS
1610 Teuchos::TimeMonitor unpackAndCombineMon (*unpackAndCombineTimer_);
1611 #endif // HAVE_TPETRA_TRANSFER_TIMERS
1614 std::ostringstream lclErrStrm;
1615 bool lclSuccess =
false;
1617 this->unpackAndCombine (remoteLIDs, this->imports_,
1618 this->numImportPacketsPerLID_,
1619 constantNumPackets, CM, space);
1622 catch (std::exception& e) {
1623 lclErrStrm <<
"doUnpackAndCombine threw an exception: "
1624 << endl << e.what();
1627 lclErrStrm <<
"doUnpackAndCombine threw an exception "
1628 "not a subclass of std::exception.";
1630 const char gblErrMsgHeader[] =
"Tpetra::DistObject "
1631 "threw an exception in unpackAndCombine on "
1632 "one or more processes in the DistObject's communicator.";
1633 auto comm = getMap()->getComm();
1634 Details::checkGlobalError(std::cerr, lclSuccess,
1635 lclErrStrm.str().c_str(),
1636 gblErrMsgHeader, *comm);
1639 this->unpackAndCombine (remoteLIDs, this->imports_,
1640 this->numImportPacketsPerLID_,
1641 constantNumPackets, CM, space);
1645 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1651 const Kokkos::DualView<
1654 const Kokkos::DualView<
1661 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1664 const Kokkos::DualView<const local_ordinal_type *, buffer_device_type>
1666 const Kokkos::DualView<const local_ordinal_type *, buffer_device_type>
1680 copyAndPermute(source, numSameIDs, permuteToLIDs, permuteFromLIDs,
1688 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1693 const Kokkos::DualView<
1706 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1709 const Kokkos::DualView<const local_ordinal_type *, buffer_device_type>
1711 Kokkos::DualView<packet_type *, buffer_device_type> &exports,
1712 Kokkos::DualView<size_t *, buffer_device_type> numPacketsPerLID,
1730 packAndPrepare(source, exportLIDs, exports, numPacketsPerLID,
1731 constantNumPackets);
1739 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1743 (
const Kokkos::DualView<
1757 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1759 const Kokkos::DualView<const local_ordinal_type *, buffer_device_type>
1761 Kokkos::DualView<packet_type *, buffer_device_type> imports,
1762 Kokkos::DualView<size_t *, buffer_device_type> numPacketsPerLID,
1763 const size_t constantNumPackets,
const CombineMode combineMode,
1764 const execution_space &space) {
1768 unpackAndCombine(importLIDs, imports, numPacketsPerLID, constantNumPackets,
1772 execution_space().fence();
1777 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1779 std::ostream &os)
const {
1781 using Teuchos::FancyOStream;
1782 using Teuchos::getFancyOStream;
1784 using Teuchos::rcpFromRef;
1786 RCP<FancyOStream> out = getFancyOStream(rcpFromRef(os));
1787 this->describe(*out, Teuchos::VERB_DEFAULT);
1790 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1791 std::unique_ptr<std::string>
1793 const char className[],
const char methodName[])
const {
1794 auto map = this->getMap();
1795 auto comm = map.is_null() ? Teuchos::null : map->getComm();
1799 template <
class DistObjectType>
1801 Teuchos::RCP<DistObjectType> &input,
1802 const Teuchos::RCP<
const Map<
typename DistObjectType::local_ordinal_type,
1803 typename DistObjectType::global_ordinal_type,
1804 typename DistObjectType::node_type>> &newMap) {
1805 input->removeEmptyProcessesInPlace(newMap);
1806 if (newMap.is_null()) {
1807 input = Teuchos::null;
1811 template <
class DistObjectType>
1813 auto newMap = input->getMap()->removeEmptyProcesses();
1814 removeEmptyProcessesInPlace<DistObjectType>(input, newMap);
1818 #define TPETRA_DISTOBJECT_INSTANT(SCALAR, LO, GO, NODE) \
1819 template class DistObject<SCALAR, LO, GO, NODE>;
1823 #define TPETRA_DISTOBJECT_INSTANT_CHAR(LO, GO, NODE) \
1824 template class DistObject<char, LO, GO, NODE>;
1828 #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.