10 #ifndef TPETRA_DISTOBJECT_DEF_HPP
11 #define TPETRA_DISTOBJECT_DEF_HPP
21 #include "Tpetra_Distributor.hpp"
24 #include "Tpetra_Details_checkGlobalError.hpp"
27 #include "Teuchos_CommHelpers.hpp"
28 #include "Teuchos_TypeNameTraits.hpp"
36 template <
class DeviceType,
class IndexType =
size_t>
38 SumFunctor(
const Kokkos::View<const size_t*, DeviceType>& viewToSum)
39 : viewToSum_(viewToSum) {}
40 KOKKOS_INLINE_FUNCTION
void operator()(
const IndexType i,
size_t& lclSum)
const {
41 lclSum += viewToSum_(i);
43 Kokkos::View<const size_t*, DeviceType> viewToSum_;
46 template <
class DeviceType,
class IndexType =
size_t>
48 countTotalImportPackets(
const Kokkos::View<const size_t*, DeviceType>& numImportPacketsPerLID) {
49 using Kokkos::parallel_reduce;
50 typedef DeviceType DT;
51 typedef typename DT::execution_space DES;
52 typedef Kokkos::RangePolicy<DES, IndexType> range_type;
54 const IndexType numOut = numImportPacketsPerLID.extent(0);
55 size_t totalImportPackets = 0;
56 parallel_reduce(
"Count import packets",
57 range_type(0, numOut),
58 SumFunctor<DeviceType, IndexType>(numImportPacketsPerLID),
60 return totalImportPackets;
64 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
69 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
73 using Teuchos::TypeNameTraits;
75 std::ostringstream os;
76 os <<
"\"Tpetra::DistObject\": {"
77 <<
"Packet: " << TypeNameTraits<packet_type>::name()
78 <<
", LocalOrdinal: " << TypeNameTraits<local_ordinal_type>::name()
79 <<
", GlobalOrdinal: " << TypeNameTraits<global_ordinal_type>::name()
80 <<
", Node: " << TypeNameTraits<Node>::name();
81 if (this->getObjectLabel() !=
"") {
82 os <<
"Label: \"" << this->getObjectLabel() <<
"\"";
88 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
91 const Teuchos::EVerbosityLevel verbLevel)
const {
93 using Teuchos::rcpFromRef;
94 using Teuchos::TypeNameTraits;
95 const Teuchos::EVerbosityLevel vl = (verbLevel == Teuchos::VERB_DEFAULT) ? Teuchos::VERB_LOW : verbLevel;
96 Teuchos::RCP<const Teuchos::Comm<int>> comm = this->getMap()->getComm();
97 const int myRank = comm.is_null() ? 0 : comm->getRank();
98 const int numProcs = comm.is_null() ? 1 : comm->getSize();
100 if (vl != Teuchos::VERB_NONE) {
101 Teuchos::OSTab tab0(out);
103 out <<
"\"Tpetra::DistObject\":" << endl;
105 Teuchos::OSTab tab1(out);
107 out <<
"Template parameters:" << endl;
109 Teuchos::OSTab tab2(out);
110 out <<
"Packet: " << TypeNameTraits<packet_type>::name() << endl
111 <<
"LocalOrdinal: " << TypeNameTraits<local_ordinal_type>::name() << endl
112 <<
"GlobalOrdinal: " << TypeNameTraits<global_ordinal_type>::name() << endl
113 <<
"Node: " << TypeNameTraits<node_type>::name() << endl;
115 if (this->getObjectLabel() !=
"") {
116 out <<
"Label: \"" << this->getObjectLabel() <<
"\"" << endl;
123 out <<
"Map:" << endl;
125 Teuchos::OSTab tab2(out);
126 map_->describe(out, vl);
130 if (vl > Teuchos::VERB_LOW) {
131 for (
int p = 0; p < numProcs; ++p) {
133 out <<
"Process " << myRank <<
":" << endl;
134 Teuchos::OSTab tab2(out);
135 out <<
"Export buffer size (in packets): "
136 << exports_.extent(0)
138 <<
"Import buffer size (in packets): "
139 << imports_.extent(0)
142 if (!comm.is_null()) {
152 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
155 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
156 "Tpetra::DistObject::removeEmptyProcessesInPlace: Not implemented");
188 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
193 const bool restrictedMode) {
196 const char modeString[] =
"doImport (forward mode)";
201 const bool verbose = Behavior::verbose(
"DistObject");
202 std::unique_ptr<std::string> prefix;
204 prefix = this->createPrefix(
"DistObject", modeString);
205 std::ostringstream os;
206 os << *prefix <<
"Start" << endl;
207 std::cerr << os.str();
209 this->beginImport(source, importer, CM, restrictedMode);
210 this->endImport(source, importer, CM, restrictedMode);
212 std::ostringstream os;
213 os << *prefix <<
"Done" << endl;
214 std::cerr << os.str();
218 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
223 const bool restrictedMode) {
226 const char modeString[] =
"doExport (forward mode)";
231 const bool verbose = Behavior::verbose(
"DistObject");
232 std::unique_ptr<std::string> prefix;
234 prefix = this->createPrefix(
"DistObject", modeString);
235 std::ostringstream os;
236 os << *prefix <<
"Start" << endl;
237 std::cerr << os.str();
239 this->beginExport(source, exporter, CM, restrictedMode);
240 this->endExport(source, exporter, CM, restrictedMode);
242 std::ostringstream os;
243 os << *prefix <<
"Done" << endl;
244 std::cerr << os.str();
248 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
253 const bool restrictedMode) {
256 const char modeString[] =
"doImport (reverse mode)";
261 const bool verbose = Behavior::verbose(
"DistObject");
262 std::unique_ptr<std::string> prefix;
264 prefix = this->createPrefix(
"DistObject", modeString);
265 std::ostringstream os;
266 os << *prefix <<
"Start" << endl;
267 std::cerr << os.str();
269 this->beginImport(source, exporter, CM, restrictedMode);
270 this->endImport(source, exporter, CM, restrictedMode);
272 std::ostringstream os;
273 os << *prefix <<
"Done" << endl;
274 std::cerr << os.str();
278 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
283 const bool restrictedMode) {
286 const char modeString[] =
"doExport (reverse 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, importer, CM, restrictedMode);
300 this->endExport(source, importer, 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>
313 const bool restrictedMode) {
316 const char modeString[] =
"beginImport (forward mode)";
321 const bool verbose = Behavior::verbose(
"DistObject");
322 std::unique_ptr<std::string> prefix;
324 prefix = this->createPrefix(
"DistObject", modeString);
325 std::ostringstream os;
326 os << *prefix <<
"Start" << endl;
327 std::cerr << os.str();
329 this->beginTransfer(source, importer, modeString, DoForward, CM, restrictedMode);
331 std::ostringstream os;
332 os << *prefix <<
"Done" << endl;
333 std::cerr << os.str();
337 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
338 void DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
339 beginExport(
const SrcDistObject& source,
340 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
342 const bool restrictedMode) {
343 using Details::Behavior;
345 const char modeString[] =
"beginExport (forward mode)";
350 const bool verbose = Behavior::verbose(
"DistObject");
351 std::unique_ptr<std::string> prefix;
354 std::ostringstream os;
355 os << *prefix <<
"Start" << endl;
356 std::cerr << os.str();
358 this->beginTransfer(source, exporter, modeString, DoForward, CM, restrictedMode);
360 std::ostringstream os;
361 os << *prefix <<
"Done" << endl;
362 std::cerr << os.str();
366 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
367 void DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
368 beginImport(
const SrcDistObject& source,
369 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
371 const bool restrictedMode) {
372 using Details::Behavior;
374 const char modeString[] =
"beginImport (reverse mode)";
379 const bool verbose = Behavior::verbose(
"DistObject");
380 std::unique_ptr<std::string> prefix;
383 std::ostringstream os;
384 os << *prefix <<
"Start" << endl;
385 std::cerr << os.str();
387 this->beginTransfer(source, exporter, modeString, DoReverse, CM, restrictedMode);
389 std::ostringstream os;
390 os << *prefix <<
"Done" << endl;
391 std::cerr << os.str();
395 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
396 void DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
397 beginExport(
const SrcDistObject& source,
398 const Import<LocalOrdinal, GlobalOrdinal, Node>& importer,
400 const bool restrictedMode) {
401 using Details::Behavior;
403 const char modeString[] =
"beginExport (reverse mode)";
408 const bool verbose = Behavior::verbose(
"DistObject");
409 std::unique_ptr<std::string> prefix;
412 std::ostringstream os;
413 os << *prefix <<
"Start" << endl;
414 std::cerr << os.str();
416 this->beginTransfer(source, importer, modeString, DoReverse, CM, restrictedMode);
418 std::ostringstream os;
419 os << *prefix <<
"Done" << endl;
420 std::cerr << os.str();
424 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
425 void DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
426 endImport(
const SrcDistObject& source,
427 const Import<LocalOrdinal, GlobalOrdinal, Node>& importer,
429 const bool restrictedMode) {
430 using Details::Behavior;
432 const char modeString[] =
"endImport (forward mode)";
437 const bool verbose = Behavior::verbose(
"DistObject");
438 std::unique_ptr<std::string> prefix;
441 std::ostringstream os;
442 os << *prefix <<
"Start" << endl;
443 std::cerr << os.str();
445 this->endTransfer(source, importer, modeString, DoForward, CM, restrictedMode);
447 std::ostringstream os;
448 os << *prefix <<
"Done" << endl;
449 std::cerr << os.str();
453 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
454 void DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
455 endExport(
const SrcDistObject& source,
456 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
458 const bool restrictedMode) {
459 using Details::Behavior;
461 const char modeString[] =
"endExport (forward mode)";
466 const bool verbose = Behavior::verbose(
"DistObject");
467 std::unique_ptr<std::string> prefix;
470 std::ostringstream os;
471 os << *prefix <<
"Start" << endl;
472 std::cerr << os.str();
474 this->endTransfer(source, exporter, modeString, DoForward, CM, restrictedMode);
476 std::ostringstream os;
477 os << *prefix <<
"Done" << endl;
478 std::cerr << os.str();
482 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
483 void DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
484 endImport(
const SrcDistObject& source,
485 const Export<LocalOrdinal, GlobalOrdinal, Node>& exporter,
487 const bool restrictedMode) {
488 using Details::Behavior;
490 const char modeString[] =
"endImport (reverse 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, DoReverse, 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>
512 void DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
513 endExport(
const SrcDistObject& source,
514 const Import<LocalOrdinal, GlobalOrdinal, Node>& importer,
516 const bool restrictedMode) {
517 using Details::Behavior;
519 const char modeString[] =
"endExport (reverse mode)";
524 const bool verbose = Behavior::verbose(
"DistObject");
525 std::unique_ptr<std::string> prefix;
528 std::ostringstream os;
529 os << *prefix <<
"Start" << endl;
530 std::cerr << os.str();
532 this->endTransfer(source, importer, modeString, DoReverse, CM, restrictedMode);
534 std::ostringstream os;
535 os << *prefix <<
"Done" << endl;
536 std::cerr << os.str();
540 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
543 return distributorActor_.isReady();
546 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
549 return map_->isDistributed();
552 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
559 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
562 const ::Tpetra::Details::Transfer<local_ordinal_type, global_ordinal_type, node_type>& transfer,
563 const char modeString[],
566 bool restrictedMode) {
567 beginTransfer(src, transfer, modeString, revOp, CM, restrictedMode);
568 endTransfer(src, transfer, modeString, revOp, CM, restrictedMode);
571 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
575 const std::string* prefix,
579 std::ostringstream os;
580 os << *prefix <<
"Realloc (if needed) imports_ from "
581 << imports_.extent(0) <<
" to " << newSize << std::endl;
582 std::cerr << os.str();
585 const bool reallocated =
588 std::ostringstream os;
589 os << *prefix <<
"Finished realloc'ing imports_" << std::endl;
590 std::cerr << os.str();
595 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
598 const size_t numImportLIDs) {
607 constexpr
size_t tooBigFactor = 10;
609 const bool verbose = Behavior::verbose(
"DistObject");
610 std::unique_ptr<std::string> prefix;
612 prefix = this->createPrefix(
"DistObject",
613 "reallocArraysForNumPacketsPerLid");
614 std::ostringstream os;
616 <<
"numExportLIDs: " << numExportLIDs
617 <<
", numImportLIDs: " << numImportLIDs
619 os << *prefix <<
"DualView status before:" << endl
622 "numExportPacketsPerLID_")
626 "numImportPacketsPerLID_")
628 std::cerr << os.str();
632 const bool firstReallocated =
635 "numExportPacketsPerLID",
642 const bool needFenceBeforeNextAlloc = !firstReallocated;
643 const bool secondReallocated =
646 "numImportPacketsPerLID",
648 needFenceBeforeNextAlloc);
651 std::ostringstream os;
652 os << *prefix <<
"DualView status after:" << endl
657 std::cerr << os.str();
660 return firstReallocated || secondReallocated;
663 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
666 const ::Tpetra::Details::Transfer<local_ordinal_type, global_ordinal_type, node_type>& transfer,
667 const char modeString[],
670 bool restrictedMode) {
674 using Kokkos::Compat::create_const_view;
675 using Kokkos::Compat::getArrayView;
676 using Kokkos::Compat::getConstArrayView;
677 using Kokkos::Compat::getKokkosViewDeepCopy;
682 const bool commOnHost = !Behavior::assumeMpiIsGPUAware();
683 const char funcNameHost[] =
"Tpetra::DistObject::beginTransfer[Host]";
684 const char funcNameDevice[] =
"Tpetra::DistObject::beginTransfer[Device]";
685 const char* funcName = commOnHost ? funcNameHost : funcNameDevice;
687 ProfilingRegion region_doTransfer(funcName);
688 const bool verbose = Behavior::verbose(
"DistObject");
689 std::shared_ptr<std::string> prefix;
691 std::ostringstream os;
692 prefix = this->createPrefix(
"DistObject",
"doTransfer");
693 os << *prefix <<
"Source type: " << Teuchos::typeName(src)
694 <<
", Target type: " << Teuchos::typeName(*
this) << endl;
695 std::cerr << os.str();
708 const bool debug = Behavior::debug(
"DistObject");
710 if (!restrictedMode && revOp == DoForward) {
711 const bool myMapSameAsTransferTgtMap =
712 this->getMap()->isSameAs(*(transfer.getTargetMap()));
713 TEUCHOS_TEST_FOR_EXCEPTION(!myMapSameAsTransferTgtMap, std::invalid_argument,
714 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
715 "communication, the target DistObject's Map must be the same "
716 "(in the sense of Tpetra::Map::isSameAs) as the input "
717 "Export/Import object's target Map.");
718 }
else if (!restrictedMode && revOp == DoReverse) {
719 const bool myMapSameAsTransferSrcMap =
720 this->getMap()->isSameAs(*(transfer.getSourceMap()));
721 TEUCHOS_TEST_FOR_EXCEPTION(!myMapSameAsTransferSrcMap, std::invalid_argument,
722 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
723 "communication, the target DistObject's Map must be the same "
724 "(in the sense of Tpetra::Map::isSameAs) as the input "
725 "Export/Import object's source Map.");
726 }
else if (restrictedMode && revOp == DoForward) {
727 const bool myMapLocallyFittedTransferTgtMap =
728 this->getMap()->isLocallyFitted(*(transfer.getTargetMap()));
729 TEUCHOS_TEST_FOR_EXCEPTION(!myMapLocallyFittedTransferTgtMap, std::invalid_argument,
730 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
731 "communication using restricted mode, Export/Import object's "
732 "target Map must be locally fitted (in the sense of "
733 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
735 const bool myMapLocallyFittedTransferSrcMap =
736 this->getMap()->isLocallyFitted(*(transfer.getSourceMap()));
737 TEUCHOS_TEST_FOR_EXCEPTION(!myMapLocallyFittedTransferSrcMap, std::invalid_argument,
738 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
739 "communication using restricted mode, Export/Import object's "
740 "source Map must be locally fitted (in the sense of "
741 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
748 if (srcDistObj !=
nullptr) {
749 if (revOp == DoForward) {
750 const bool srcMapSameAsImportSrcMap =
751 srcDistObj->
getMap()->isSameAs(*(transfer.getSourceMap()));
752 TEUCHOS_TEST_FOR_EXCEPTION(!srcMapSameAsImportSrcMap, std::invalid_argument,
753 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
754 "communication, the source DistObject's Map must be the same "
755 "as the input Export/Import object's source Map.");
757 const bool srcMapSameAsImportTgtMap =
758 srcDistObj->
getMap()->isSameAs(*(transfer.getTargetMap()));
759 TEUCHOS_TEST_FOR_EXCEPTION(!srcMapSameAsImportTgtMap, std::invalid_argument,
760 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
761 "communication, the source DistObject's Map must be the same "
762 "as the input Export/Import object's target Map.");
767 const size_t numSameIDs = transfer.getNumSameIDs();
771 TEUCHOS_TEST_FOR_EXCEPTION(debug && restrictedMode &&
772 (transfer.getPermuteToLIDs_dv().extent(0) != 0 ||
773 transfer.getPermuteFromLIDs_dv().extent(0) != 0),
774 std::invalid_argument,
775 "Tpetra::DistObject::" << modeString <<
": Transfer object "
776 "cannot have permutes in restricted mode.");
780 std::ostringstream os;
781 os << *prefix <<
"doTransfer: Use new interface; "
783 << (commOnHost ?
"true" :
"false") << endl;
784 std::cerr << os.str();
787 using const_lo_dv_type =
788 Kokkos::DualView<const local_ordinal_type*, buffer_device_type>;
789 const_lo_dv_type permuteToLIDs = (revOp == DoForward) ? transfer.getPermuteToLIDs_dv() : transfer.getPermuteFromLIDs_dv();
790 const_lo_dv_type permuteFromLIDs = (revOp == DoForward) ? transfer.getPermuteFromLIDs_dv() : transfer.getPermuteToLIDs_dv();
791 const_lo_dv_type remoteLIDs = (revOp == DoForward) ? transfer.getRemoteLIDs_dv() : transfer.getExportLIDs_dv();
792 const_lo_dv_type exportLIDs = (revOp == DoForward) ? transfer.getExportLIDs_dv() : transfer.getRemoteLIDs_dv();
793 const bool canTryAliasing = (revOp == DoForward) ? transfer.areRemoteLIDsContiguous() : transfer.areExportLIDsContiguous();
796 ProfilingRegion region_dTN(funcName);
799 std::ostringstream os;
800 os << *prefix <<
"Input arguments:" << endl
802 << *prefix <<
" numSameIDs: " << numSameIDs << endl
811 << *prefix <<
" revOp: Do" << (revOp == DoReverse ?
"Reverse" :
"Forward") << endl
812 << *prefix <<
" commOnHost: " << (commOnHost ?
"true" :
"false") << endl;
813 std::cerr << os.str();
817 ProfilingRegion region_cs(
"Tpetra::DistObject::beginTransfer::checkSizes");
819 std::ostringstream os;
820 os << *prefix <<
"1. checkSizes" << endl;
821 std::cerr << os.str();
823 const bool checkSizesResult = this->checkSizes(src);
824 TEUCHOS_TEST_FOR_EXCEPTION(!checkSizesResult, std::invalid_argument,
825 "Tpetra::DistObject::doTransfer: checkSizes() indicates that the "
826 "destination object is not a legal target for redistribution from the "
827 "source object. This probably means that they do not have the same "
828 "dimensions. For example, MultiVectors must have the same number of "
829 "rows and columns.");
840 size_t constantNumPackets = this->constantNumberOfPackets();
842 std::ostringstream os;
843 os << *prefix <<
"constantNumPackets=" << constantNumPackets << endl;
844 std::cerr << os.str();
848 bool needCommunication =
true;
854 if (revOp == DoReverse && !this->isDistributed()) {
855 needCommunication =
false;
864 else if (revOp == DoForward && srcDistObj != NULL &&
866 needCommunication =
false;
870 needCommunication =
false;
929 const bool overlapTransferSteps = (constantNumPackets != 0) && Behavior::enableGranularTransfers();
932 std::ostringstream os;
933 os << *prefix <<
"overlapTransferSteps=" << overlapTransferSteps << endl;
934 std::cerr << os.str();
938 const bool thereAreIDsToCopy = (numSameIDs + permuteToLIDs.extent(0) != 0);
939 const bool needCopyAndPermute = (!restrictedMode && thereAreIDsToCopy);
941 if (!overlapTransferSteps) {
949 if (needCopyAndPermute) {
953 std::ostringstream os;
954 os << *prefix <<
"2. copyAndPermute" << endl;
955 std::cerr << os.str();
958 ProfilingRegion region_cp(
"Tpetra::DistObject::beginTransfer::copyAndPermute");
960 this->copyAndPermute(src, numSameIDs, permuteToLIDs, permuteFromLIDs, CM);
963 std::ostringstream os;
964 os << *prefix <<
"After copyAndPermute:" << endl
971 std::cerr << os.str();
975 if (!needCommunication) {
977 std::ostringstream os;
978 os << *prefix <<
"Comm not needed; skipping" << endl;
979 std::cerr << os.str();
985 if (constantNumPackets == 0) {
987 std::ostringstream os;
988 os << *prefix <<
"3. (Re)allocate num{Ex,Im}portPacketsPerLID"
990 std::cerr << os.str();
994 this->reallocArraysForNumPacketsPerLid(exportLIDs.extent(0),
995 remoteLIDs.extent(0));
999 std::ostringstream os;
1000 os << *prefix <<
"4. packAndPrepare: before, "
1003 std::cerr << os.str();
1006 doPackAndPrepare(src, exportLIDs, constantNumPackets,
execution_space());
1008 this->exports_.sync_host();
1010 this->exports_.sync_device();
1014 std::ostringstream os;
1015 os << *prefix <<
"5.1. After packAndPrepare, "
1018 std::cerr << os.str();
1023 if (constantNumPackets != 0) {
1024 ProfilingRegion region_reallocImportsIfNeeded(
"Tpetra::DistObject::beginTransfer::reallocImportsIfNeeded");
1030 const size_t rbufLen = remoteLIDs.extent(0) * constantNumPackets;
1031 reallocImportsIfNeeded(rbufLen, verbose, prefix.get(), canTryAliasing, CM);
1040 std::ostringstream os;
1041 os << *prefix <<
"7.0. "
1042 << (revOp == DoReverse ?
"Reverse" :
"Forward")
1044 std::cerr << os.str();
1047 doPostRecvs(distributorPlan, constantNumPackets, commOnHost, prefix, canTryAliasing, CM);
1052 doPostSends(distributorPlan, constantNumPackets, commOnHost, prefix);
1059 if (!needCommunication) {
1061 std::ostringstream os;
1062 os << *prefix <<
"Comm not needed; skipping" << endl;
1063 std::cerr << os.str();
1071 if (constantNumPackets != 0) {
1072 ProfilingRegion region_reallocImportsIfNeeded(
"Tpetra::DistObject::beginTransfer::reallocImportsIfNeeded");
1078 const size_t rbufLen = remoteLIDs.extent(0) * constantNumPackets;
1079 reallocImportsIfNeeded(rbufLen, verbose, prefix.get(), canTryAliasing, CM);
1085 std::ostringstream os;
1086 os << *prefix <<
"7.0. "
1087 << (revOp == DoReverse ?
"Reverse" :
"Forward")
1089 std::cerr << os.str();
1092 doPostRecvs(distributorPlan, constantNumPackets, commOnHost, prefix, canTryAliasing, CM);
1097 if (constantNumPackets == 0) {
1099 std::ostringstream os;
1100 os << *prefix <<
"3. (Re)allocate num{Ex,Im}portPacketsPerLID"
1102 std::cerr << os.str();
1106 this->reallocArraysForNumPacketsPerLid(exportLIDs.extent(0),
1107 remoteLIDs.extent(0));
1111 std::ostringstream os;
1112 os << *prefix <<
"4. packAndPrepare: before, "
1115 std::cerr << os.str();
1118 doPackAndPrepare(src, exportLIDs, constantNumPackets,
execution_space());
1121 this->exports_.sync_host();
1123 this->exports_.sync_device();
1127 std::ostringstream os;
1128 os << *prefix <<
"5.1. After packAndPrepare, "
1131 std::cerr << os.str();
1137 doPostSends(distributorPlan, constantNumPackets, commOnHost, prefix);
1148 if (needCopyAndPermute) {
1151 std::ostringstream os;
1152 os << *prefix <<
"2. copyAndPermute" << endl;
1153 std::cerr << os.str();
1157 ProfilingRegion region_cp(
"Tpetra::DistObject::beginTransfer::copyAndPermute");
1159 this->copyAndPermute(src, numSameIDs, permuteToLIDs, permuteFromLIDs, CM);
1163 std::ostringstream os;
1164 os << *prefix <<
"After copyAndPermute:" << endl
1171 std::cerr << os.str();
1177 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1180 const ::Tpetra::Details::Transfer<local_ordinal_type, global_ordinal_type, node_type>& transfer,
1181 const char modeString[],
1182 const ReverseOption revOp,
1184 bool restrictedMode) {
1188 using Kokkos::Compat::create_const_view;
1189 using Kokkos::Compat::getArrayView;
1190 using Kokkos::Compat::getConstArrayView;
1191 using Kokkos::Compat::getKokkosViewDeepCopy;
1196 const bool commOnHost = !Behavior::assumeMpiIsGPUAware();
1197 const char funcNameHost[] =
"Tpetra::DistObject::endTransfer[Host]";
1198 const char funcNameDevice[] =
"Tpetra::DistObject::endTransfer[Device]";
1199 const char* funcName = commOnHost ? funcNameHost : funcNameDevice;
1200 ProfilingRegion region_doTransfer(funcName);
1201 const bool verbose = Behavior::verbose(
"DistObject");
1202 std::shared_ptr<std::string> prefix;
1204 std::ostringstream os;
1205 prefix = this->createPrefix(
"DistObject",
"doTransfer");
1206 os << *prefix <<
"Source type: " << Teuchos::typeName(src)
1207 <<
", Target type: " << Teuchos::typeName(*
this) << endl;
1208 std::cerr << os.str();
1221 const bool debug = Behavior::debug(
"DistObject");
1223 if (!restrictedMode && revOp == DoForward) {
1224 const bool myMapSameAsTransferTgtMap =
1225 this->getMap()->isSameAs(*(transfer.getTargetMap()));
1226 TEUCHOS_TEST_FOR_EXCEPTION(!myMapSameAsTransferTgtMap, std::invalid_argument,
1227 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
1228 "communication, the target DistObject's Map must be the same "
1229 "(in the sense of Tpetra::Map::isSameAs) as the input "
1230 "Export/Import object's target Map.");
1231 }
else if (!restrictedMode && revOp == DoReverse) {
1232 const bool myMapSameAsTransferSrcMap =
1233 this->getMap()->isSameAs(*(transfer.getSourceMap()));
1234 TEUCHOS_TEST_FOR_EXCEPTION(!myMapSameAsTransferSrcMap, std::invalid_argument,
1235 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
1236 "communication, the target DistObject's Map must be the same "
1237 "(in the sense of Tpetra::Map::isSameAs) as the input "
1238 "Export/Import object's source Map.");
1239 }
else if (restrictedMode && revOp == DoForward) {
1240 const bool myMapLocallyFittedTransferTgtMap =
1241 this->getMap()->isLocallyFitted(*(transfer.getTargetMap()));
1242 TEUCHOS_TEST_FOR_EXCEPTION(!myMapLocallyFittedTransferTgtMap, std::invalid_argument,
1243 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
1244 "communication using restricted mode, Export/Import object's "
1245 "target Map must be locally fitted (in the sense of "
1246 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
1248 const bool myMapLocallyFittedTransferSrcMap =
1249 this->getMap()->isLocallyFitted(*(transfer.getSourceMap()));
1250 TEUCHOS_TEST_FOR_EXCEPTION(!myMapLocallyFittedTransferSrcMap, std::invalid_argument,
1251 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
1252 "communication using restricted mode, Export/Import object's "
1253 "source Map must be locally fitted (in the sense of "
1254 "Tpetra::Map::isLocallyFitted) to target DistObject's Map.");
1260 const this_type* srcDistObj =
dynamic_cast<const this_type*
>(&src);
1261 if (srcDistObj !=
nullptr) {
1262 if (revOp == DoForward) {
1263 const bool srcMapSameAsImportSrcMap =
1264 srcDistObj->getMap()->isSameAs(*(transfer.getSourceMap()));
1265 TEUCHOS_TEST_FOR_EXCEPTION(!srcMapSameAsImportSrcMap, std::invalid_argument,
1266 "Tpetra::DistObject::" << modeString <<
": For forward-mode "
1267 "communication, the source DistObject's Map must be the same "
1268 "as the input Export/Import object's source Map.");
1270 const bool srcMapSameAsImportTgtMap =
1271 srcDistObj->getMap()->isSameAs(*(transfer.getTargetMap()));
1272 TEUCHOS_TEST_FOR_EXCEPTION(!srcMapSameAsImportTgtMap, std::invalid_argument,
1273 "Tpetra::DistObject::" << modeString <<
": For reverse-mode "
1274 "communication, the source DistObject's Map must be the same "
1275 "as the input Export/Import object's target Map.");
1280 Distributor& distor = transfer.getDistributor();
1281 const Details::DistributorPlan& distributorPlan = (revOp == DoForward) ? distor.getPlan() : *distor.getPlan().getReversePlan();
1283 TEUCHOS_TEST_FOR_EXCEPTION(debug && restrictedMode &&
1284 (transfer.getPermuteToLIDs_dv().extent(0) != 0 ||
1285 transfer.getPermuteFromLIDs_dv().extent(0) != 0),
1286 std::invalid_argument,
1287 "Tpetra::DistObject::" << modeString <<
": Transfer object "
1288 "cannot have permutes in restricted mode.");
1292 std::ostringstream os;
1293 os << *prefix <<
"doTransfer: Use new interface; "
1295 << (commOnHost ?
"true" :
"false") << endl;
1296 std::cerr << os.str();
1299 using const_lo_dv_type =
1300 Kokkos::DualView<const local_ordinal_type*, buffer_device_type>;
1301 const_lo_dv_type remoteLIDs = (revOp == DoForward) ? transfer.getRemoteLIDs_dv() : transfer.getExportLIDs_dv();
1303 size_t constantNumPackets = this->constantNumberOfPackets();
1308 bool needCommunication =
true;
1311 const this_type* srcDistObj =
dynamic_cast<const this_type*
>(&src);
1313 if (revOp == DoReverse && !this->isDistributed()) {
1314 needCommunication =
false;
1323 else if (revOp == DoForward && srcDistObj != NULL &&
1324 !srcDistObj->isDistributed()) {
1325 needCommunication =
false;
1328 if (!needCommunication) {
1330 std::ostringstream os;
1331 os << *prefix <<
"Comm not needed; skipping" << endl;
1332 std::cerr << os.str();
1335 distributorActor_.doWaitsRecv(distributorPlan);
1338 std::ostringstream os;
1339 os << *prefix <<
"8. unpackAndCombine - remoteLIDs " << remoteLIDs.extent(0) <<
", constantNumPackets " << constantNumPackets << endl;
1340 std::cerr << os.str();
1342 doUnpackAndCombine(remoteLIDs, constantNumPackets, CM, execution_space());
1344 distributorActor_.doWaitsSend(distributorPlan);
1349 std::ostringstream os;
1350 os << *prefix <<
"9. Done!" << endl;
1351 std::cerr << os.str();
1355 std::ostringstream os;
1356 os << *prefix <<
"Tpetra::DistObject::doTransfer: Done!" << endl;
1357 std::cerr << os.str();
1361 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1362 void DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1363 doPostRecvs(
const Details::DistributorPlan& distributorPlan,
1364 size_t constantNumPackets,
1366 std::shared_ptr<std::string> prefix,
1367 const bool canTryAliasing,
1369 using Details::ProfilingRegion;
1370 using Kokkos::Compat::create_const_view;
1375 const char funcNameHost[] =
"Tpetra::DistObject::doPostRecvs[Host]";
1376 const char funcNameDevice[] =
"Tpetra::DistObject::doPostRecvs[Device]";
1377 const char* funcName = commOnHost ? funcNameHost : funcNameDevice;
1378 ProfilingRegion region_dpr(funcName);
1382 if (constantNumPackets == 0) {
1384 std::ostringstream os;
1385 os << *prefix <<
"7.1. Variable # packets / LID: first comm "
1386 <<
"(commOnHost = " << (commOnHost ?
"true" :
"false") <<
")"
1388 std::cerr << os.str();
1390 size_t totalImportPackets = 0;
1392 if (this->numExportPacketsPerLID_.need_sync_host()) {
1393 this->numExportPacketsPerLID_.sync_host();
1395 if (this->numImportPacketsPerLID_.need_sync_host()) {
1396 this->numImportPacketsPerLID_.sync_host();
1398 this->numImportPacketsPerLID_.modify_host();
1400 create_const_view(this->numExportPacketsPerLID_.view_host());
1401 auto numImp_h = this->numImportPacketsPerLID_.view_host();
1405 std::ostringstream os;
1406 os << *prefix <<
"Call doPostsAndWaits"
1408 std::cerr << os.str();
1410 distributorActor_.doPostsAndWaits(distributorPlan, numExp_h, 1, numImp_h);
1413 std::ostringstream os;
1414 os << *prefix <<
"Count totalImportPackets" << std::endl;
1415 std::cerr << os.str();
1417 using the_dev_type =
typename decltype(numImp_h)::device_type;
1418 totalImportPackets = countTotalImportPackets<the_dev_type>(numImp_h);
1420 this->numExportPacketsPerLID_.sync_device();
1421 this->numImportPacketsPerLID_.sync_device();
1422 this->numImportPacketsPerLID_.modify_device();
1423 auto numExp_d = create_const_view(this->numExportPacketsPerLID_.view_device());
1424 auto numImp_d = this->numImportPacketsPerLID_.view_device();
1428 std::ostringstream os;
1429 os << *prefix <<
"Call doPostsAndWaits"
1431 std::cerr << os.str();
1434 distributorActor_.doPostsAndWaits(distributorPlan, numExp_d, 1, numImp_d);
1437 std::ostringstream os;
1438 os << *prefix <<
"Count totalImportPackets" << std::endl;
1439 std::cerr << os.str();
1441 using the_dev_type =
typename decltype(numImp_d)::device_type;
1442 totalImportPackets = countTotalImportPackets<the_dev_type>(numImp_d);
1446 std::ostringstream os;
1447 os << *prefix <<
"totalImportPackets=" << totalImportPackets << endl;
1448 std::cerr << os.str();
1450 this->reallocImportsIfNeeded(totalImportPackets, verbose,
1451 prefix.get(), canTryAliasing, CM);
1453 std::ostringstream os;
1454 os << *prefix <<
"7.3. Second comm" << std::endl;
1455 std::cerr << os.str();
1461 this->numImportPacketsPerLID_.sync_host();
1470 auto numImportPacketsPerLID_av =
1478 this->imports_.clear_sync_state();
1481 std::ostringstream os;
1482 os << *prefix <<
"Comm on "
1483 << (commOnHost ?
"host" :
"device")
1484 <<
"; call doPostRecvs" << endl;
1485 std::cerr << os.str();
1489 this->imports_.modify_host();
1490 distributorActor_.doPostRecvs(distributorPlan,
1491 this->imports_.view_host(),
1492 numImportPacketsPerLID_av);
1494 this->imports_.modify_device();
1495 distributorActor_.doPostRecvs(distributorPlan,
1496 this->imports_.view_device(),
1497 numImportPacketsPerLID_av);
1501 std::ostringstream os;
1502 os << *prefix <<
"7.1. Const # packets per LID: " << endl
1509 std::cerr << os.str();
1516 this->imports_.clear_sync_state();
1519 std::ostringstream os;
1520 os << *prefix <<
"7.2. Comm on "
1521 << (commOnHost ?
"host" :
"device")
1522 <<
"; call doPostRecvs" << endl;
1523 std::cerr << os.str();
1526 this->imports_.modify_host();
1527 distributorActor_.doPostRecvs(distributorPlan,
1529 this->imports_.view_host());
1531 this->imports_.modify_device();
1532 distributorActor_.doPostRecvs(distributorPlan,
1534 this->imports_.view_device());
1539 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1540 void DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1541 doPostSends(
const Details::DistributorPlan& distributorPlan,
1542 size_t constantNumPackets,
1544 std::shared_ptr<std::string> prefix) {
1545 using Details::ProfilingRegion;
1546 using Kokkos::Compat::create_const_view;
1550 const char funcNameHost[] =
"Tpetra::DistObject::doPostSends[Host]";
1551 const char funcNameDevice[] =
"Tpetra::DistObject::doPostSends[Device]";
1552 const char* funcName = commOnHost ? funcNameHost : funcNameDevice;
1553 ProfilingRegion region_dps(funcName);
1557 std::ostringstream os;
1558 os << *prefix <<
"Comm on "
1559 << (commOnHost ?
"host" :
"device")
1560 <<
"; call doPostSends" << endl;
1561 std::cerr << os.str();
1564 if (constantNumPackets == 0) {
1568 this->numExportPacketsPerLID_.sync_host();
1569 this->numImportPacketsPerLID_.sync_host();
1578 auto numExportPacketsPerLID_av =
1580 auto numImportPacketsPerLID_av =
1584 distributorActor_.doPostSends(distributorPlan,
1585 create_const_view(this->exports_.view_host()),
1586 numExportPacketsPerLID_av,
1587 this->imports_.view_host(),
1588 numImportPacketsPerLID_av);
1591 Kokkos::fence(
"DistObject::doPostSends-1");
1592 distributorActor_.doPostSends(distributorPlan,
1593 create_const_view(this->exports_.view_device()),
1594 numExportPacketsPerLID_av,
1595 this->imports_.view_device(),
1596 numImportPacketsPerLID_av);
1600 distributorActor_.doPostSends(distributorPlan,
1601 create_const_view(this->exports_.view_host()),
1603 this->imports_.view_host());
1606 Kokkos::fence(
"DistObject::doPostSends-2");
1607 distributorActor_.doPostSends(distributorPlan,
1608 create_const_view(this->exports_.view_device()),
1610 this->imports_.view_device());
1615 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1616 void DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1617 doPackAndPrepare(
const SrcDistObject& src,
1618 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& exportLIDs,
1619 size_t& constantNumPackets,
1620 const execution_space& space) {
1621 using Details::ProfilingRegion;
1625 ProfilingRegion region_pp(
"Tpetra::DistObject::doPackAndPrepare");
1644 std::ostringstream lclErrStrm;
1645 bool lclSuccess =
false;
1647 this->packAndPrepare(src, exportLIDs, this->exports_,
1648 this->numExportPacketsPerLID_,
1649 constantNumPackets, space);
1651 }
catch (std::exception& e) {
1652 lclErrStrm <<
"packAndPrepare threw an exception: "
1656 lclErrStrm <<
"packAndPrepare threw an exception "
1657 "not a subclass of std::exception.";
1659 const char gblErrMsgHeader[] =
1660 "Tpetra::DistObject "
1661 "threw an exception in packAndPrepare on "
1662 "one or more processes in the DistObject's communicator.";
1663 auto comm = getMap()->getComm();
1664 Details::checkGlobalError(std::cerr, lclSuccess,
1665 lclErrStrm.str().c_str(),
1666 gblErrMsgHeader, *comm);
1668 this->packAndPrepare(src, exportLIDs, this->exports_,
1669 this->numExportPacketsPerLID_,
1670 constantNumPackets, space);
1674 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1675 void DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node>::
1676 doUnpackAndCombine(
const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& remoteLIDs,
1677 size_t constantNumPackets,
1679 const execution_space& space) {
1680 using Details::ProfilingRegion;
1684 ProfilingRegion region_uc(
"Tpetra::DistObject::doUnpackAndCombine");
1687 std::ostringstream lclErrStrm;
1688 bool lclSuccess =
false;
1690 this->unpackAndCombine(remoteLIDs, this->imports_,
1691 this->numImportPacketsPerLID_,
1692 constantNumPackets, CM, space);
1694 }
catch (std::exception& e) {
1695 lclErrStrm <<
"doUnpackAndCombine threw an exception: "
1699 lclErrStrm <<
"doUnpackAndCombine threw an exception "
1700 "not a subclass of std::exception.";
1702 const char gblErrMsgHeader[] =
1703 "Tpetra::DistObject "
1704 "threw an exception in unpackAndCombine on "
1705 "one or more processes in the DistObject's communicator.";
1706 auto comm = getMap()->getComm();
1707 Details::checkGlobalError(std::cerr, lclSuccess,
1708 lclErrStrm.str().c_str(),
1709 gblErrMsgHeader, *comm);
1711 this->unpackAndCombine(remoteLIDs, this->imports_,
1712 this->numImportPacketsPerLID_,
1713 constantNumPackets, CM, space);
1717 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1721 const Kokkos::DualView<
1724 const Kokkos::DualView<
1729 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1732 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& permuteToLIDs,
1733 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& permuteFromLIDs,
1745 space.fence(
"Tpetra::DistObject::copyAndPermute-1");
1746 copyAndPermute(source, numSameIDs, permuteToLIDs, permuteFromLIDs,
1752 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1755 const Kokkos::DualView<
1766 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1769 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& exportLIDs,
1770 Kokkos::DualView<packet_type*, buffer_device_type>& exports,
1771 Kokkos::DualView<size_t*, buffer_device_type> numPacketsPerLID,
1786 space.fence(
"Tpetra::DistObject::packAndPrepare-1");
1789 packAndPrepare(source, exportLIDs, exports, numPacketsPerLID,
1790 constantNumPackets);
1797 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1811 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1813 const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& importLIDs,
1814 Kokkos::DualView<packet_type*, buffer_device_type> imports,
1815 Kokkos::DualView<size_t*, buffer_device_type> numPacketsPerLID,
1816 const size_t constantNumPackets,
const CombineMode combineMode,
1817 const execution_space& space) {
1819 space.fence(
"Tpetra::DistObject::unpackAndCombine-1");
1821 unpackAndCombine(importLIDs, imports, numPacketsPerLID, constantNumPackets,
1825 execution_space().fence(
"Tpetra::DistObject::unpackAndCombine-2");
1829 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1831 std::ostream& os)
const {
1833 using Teuchos::FancyOStream;
1834 using Teuchos::getFancyOStream;
1836 using Teuchos::rcpFromRef;
1838 RCP<FancyOStream> out = getFancyOStream(rcpFromRef(os));
1839 this->describe(*out, Teuchos::VERB_DEFAULT);
1842 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1843 std::unique_ptr<std::string>
1845 const char className[],
const char methodName[])
const {
1846 auto map = this->getMap();
1847 auto comm = map.is_null() ? Teuchos::null : map->getComm();
1851 template <
class DistObjectType>
1853 Teuchos::RCP<DistObjectType>& input,
1854 const Teuchos::RCP<
const Map<
typename DistObjectType::local_ordinal_type,
1855 typename DistObjectType::global_ordinal_type,
1856 typename DistObjectType::node_type>>& newMap) {
1857 input->removeEmptyProcessesInPlace(newMap);
1858 if (newMap.is_null()) {
1859 input = Teuchos::null;
1863 template <
class DistObjectType>
1865 auto newMap = input->getMap()->removeEmptyProcesses();
1866 removeEmptyProcessesInPlace<DistObjectType>(input, newMap);
1870 #define TPETRA_DISTOBJECT_INSTANT(SCALAR, LO, GO, NODE) \
1871 template class DistObject<SCALAR, LO, GO, NODE>;
1875 #define TPETRA_DISTOBJECT_INSTANT_CHAR(LO, GO, NODE) \
1876 template class DistObject<char, LO, GO, NODE>;
1880 #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.