42 #ifndef TPETRA_DISTOBJECT_DEF_HPP 43 #define TPETRA_DISTOBJECT_DEF_HPP 53 #include "Tpetra_Distributor.hpp" 57 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
62 #ifdef HAVE_TPETRA_TRANSFER_TIMERS 65 using Teuchos::TimeMonitor;
67 RCP<Time> doXferTimer =
68 TimeMonitor::lookupCounter (
"Tpetra::DistObject::doTransfer");
69 if (doXferTimer.is_null ()) {
71 TimeMonitor::getNewCounter (
"Tpetra::DistObject::doTransfer");
73 doXferTimer_ = doXferTimer;
75 RCP<Time> copyAndPermuteTimer =
76 TimeMonitor::lookupCounter (
"Tpetra::DistObject::copyAndPermute");
77 if (copyAndPermuteTimer.is_null ()) {
79 TimeMonitor::getNewCounter (
"Tpetra::DistObject::copyAndPermute");
81 copyAndPermuteTimer_ = copyAndPermuteTimer;
83 RCP<Time> packAndPrepareTimer =
84 TimeMonitor::lookupCounter (
"Tpetra::DistObject::packAndPrepare");
85 if (packAndPrepareTimer.is_null ()) {
87 TimeMonitor::getNewCounter (
"Tpetra::DistObject::packAndPrepare");
89 packAndPrepareTimer_ = packAndPrepareTimer;
91 RCP<Time> doPostsAndWaitsTimer =
92 TimeMonitor::lookupCounter (
"Tpetra::DistObject::doPostsAndWaits");
93 if (doPostsAndWaitsTimer.is_null ()) {
94 doPostsAndWaitsTimer =
95 TimeMonitor::getNewCounter (
"Tpetra::DistObject::doPostsAndWaits");
97 doPostsAndWaitsTimer_ = doPostsAndWaitsTimer;
99 RCP<Time> unpackAndCombineTimer =
100 TimeMonitor::lookupCounter (
"Tpetra::DistObject::unpackAndCombine");
101 if (unpackAndCombineTimer.is_null ()) {
102 unpackAndCombineTimer =
103 TimeMonitor::getNewCounter (
"Tpetra::DistObject::unpackAndCombine");
105 unpackAndCombineTimer_ = unpackAndCombineTimer;
106 #endif // HAVE_TPETRA_TRANSFER_TIMERS 109 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
115 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
120 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
125 using Teuchos::TypeNameTraits;
127 std::ostringstream os;
128 os <<
"\"Tpetra::DistObject\": {" 129 <<
"Packet: " << TypeNameTraits<packet_type>::name ()
130 <<
", LocalOrdinal: " << TypeNameTraits<local_ordinal_type>::name ()
131 <<
", GlobalOrdinal: " << TypeNameTraits<global_ordinal_type>::name ()
132 <<
", Node: " << TypeNameTraits<Node>::name ();
133 if (this->getObjectLabel () !=
"") {
134 os <<
"Label: \"" << this->getObjectLabel () <<
"\"";
140 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
144 const Teuchos::EVerbosityLevel verbLevel)
const 146 using Teuchos::rcpFromRef;
147 using Teuchos::TypeNameTraits;
149 const Teuchos::EVerbosityLevel vl = (verbLevel == Teuchos::VERB_DEFAULT) ?
150 Teuchos::VERB_LOW : verbLevel;
151 Teuchos::RCP<const Teuchos::Comm<int> > comm = this->getMap ()->getComm ();
152 const int myRank = comm.is_null () ? 0 : comm->getRank ();
153 const int numProcs = comm.is_null () ? 1 : comm->getSize ();
155 if (vl != Teuchos::VERB_NONE) {
156 Teuchos::OSTab tab0 (out);
158 out <<
"\"Tpetra::DistObject\":" << endl;
160 Teuchos::OSTab tab1 (out);
162 out <<
"Template parameters:" << endl;
164 Teuchos::OSTab tab2 (out);
165 out <<
"Packet: " << TypeNameTraits<packet_type>::name () << endl
166 <<
"LocalOrdinal: " << TypeNameTraits<local_ordinal_type>::name () << endl
167 <<
"GlobalOrdinal: " << TypeNameTraits<global_ordinal_type>::name () << endl
168 <<
"Node: " << TypeNameTraits<node_type>::name () << endl;
170 if (this->getObjectLabel () !=
"") {
171 out <<
"Label: \"" << this->getObjectLabel () <<
"\"" << endl;
178 out <<
"Map:" << endl;
180 Teuchos::OSTab tab2 (out);
181 map_->describe (out, vl);
185 if (vl > Teuchos::VERB_LOW) {
186 for (
int p = 0; p < numProcs; ++p) {
188 out <<
"Process " << myRank <<
":" << endl;
189 Teuchos::OSTab tab2 (out);
190 out <<
"Export buffer size (in packets): " 191 << exports_.dimension_0 ()
193 <<
"Import buffer size (in packets): " 194 << imports_.dimension_0 ()
197 if (! comm.is_null ()) {
207 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
212 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
213 "Tpetra::DistObject::removeEmptyProcessesInPlace: Not implemented");
245 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
252 #ifdef HAVE_TPETRA_DEBUG 253 TEUCHOS_TEST_FOR_EXCEPTION(*getMap() != *importer.
getTargetMap(),
254 std::invalid_argument,
"doImport: The target DistObject's Map is not " 255 "identical to the Import's target Map.");
258 TEUCHOS_TEST_FOR_EXCEPTION(
260 std::invalid_argument,
"doImport: The source is a DistObject, yet its " 261 "Map is not identical to the Import's source Map.");
263 #endif // HAVE_TPETRA_DEBUG 266 typedef Teuchos::ArrayView<const LocalOrdinal> view_type;
271 this->doTransfer (source, CM, numSameIDs, permuteToLIDs, permuteFromLIDs,
276 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
283 #ifdef HAVE_TPETRA_DEBUG 284 TEUCHOS_TEST_FOR_EXCEPTION(
285 *getMap() != *exporter.
getTargetMap(), std::invalid_argument,
286 "doExport: The target DistObject's Map is not identical to the Export's " 290 TEUCHOS_TEST_FOR_EXCEPTION(
292 std::invalid_argument,
"doExport: The source is a DistObject, yet its " 293 "Map is not identical to the Export's source Map.");
295 #endif // HAVE_TPETRA_DEBUG 298 typedef Teuchos::ArrayView<const LocalOrdinal> view_type;
303 doTransfer (source, CM, numSameIDs, permuteToLIDs, permuteFromLIDs, remoteLIDs,
307 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
314 #ifdef HAVE_TPETRA_DEBUG 315 TEUCHOS_TEST_FOR_EXCEPTION(
316 *getMap() != *exporter.
getSourceMap(), std::invalid_argument,
317 "doImport (reverse mode): The target DistObject's Map is not identical " 318 "to the Export's source Map.");
321 TEUCHOS_TEST_FOR_EXCEPTION(
323 std::invalid_argument,
324 "doImport (reverse mode): The source is a DistObject, yet its " 325 "Map is not identical to the Export's target Map.");
327 #endif // HAVE_TPETRA_DEBUG 330 typedef Teuchos::ArrayView<const LocalOrdinal> view_type;
335 doTransfer (source, CM, numSameIDs, permuteToLIDs, permuteFromLIDs, remoteLIDs,
339 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
346 #ifdef HAVE_TPETRA_DEBUG 347 TEUCHOS_TEST_FOR_EXCEPTION(
348 *getMap() != *importer.
getSourceMap(), std::invalid_argument,
349 "doExport (reverse mode): The target object's Map " 350 "is not identical to the Import's source Map.");
353 TEUCHOS_TEST_FOR_EXCEPTION(
355 std::invalid_argument,
356 "doExport (reverse mode): The source is a DistObject, yet its " 357 "Map is not identical to the Import's target Map.");
359 #endif // HAVE_TPETRA_DEBUG 362 typedef Teuchos::ArrayView<const LocalOrdinal> view_type;
367 doTransfer (source, CM, numSameIDs, permuteToLIDs, permuteFromLIDs, remoteLIDs,
371 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
378 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
385 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
391 const Teuchos::ArrayView<const LocalOrdinal>& permuteToLIDs_,
392 const Teuchos::ArrayView<const LocalOrdinal>& permuteFromLIDs_,
393 const Teuchos::ArrayView<const LocalOrdinal>& remoteLIDs_,
394 const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs_,
399 typedef LocalOrdinal LO;
402 if (this->useNewInterface ()) {
403 const bool commOnHost =
false;
413 Kokkos::DualView<LO*, DT> permuteToLIDs =
414 getDualViewCopyFromArrayView<LO, DT> (permuteToLIDs_,
417 Kokkos::DualView<LO*, DT> permuteFromLIDs =
418 getDualViewCopyFromArrayView<LO, DT> (permuteFromLIDs_,
423 Kokkos::DualView<LO*, DT> remoteLIDs =
424 getDualViewCopyFromArrayView<LO, DT> (remoteLIDs_,
427 Kokkos::DualView<LO*, DT> exportLIDs =
428 getDualViewCopyFromArrayView<LO, DT> (exportLIDs_,
432 doTransferNew (src, CM, numSameIDs, permuteToLIDs, permuteFromLIDs,
433 remoteLIDs, exportLIDs, distor, revOp, commOnHost);
436 doTransferOld (src, CM, numSameIDs, permuteToLIDs_, permuteFromLIDs_,
437 remoteLIDs_, exportLIDs_, distor, revOp);
441 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
446 if (static_cast<size_t> (imports_.dimension_0 ()) != newSize) {
448 std::ostringstream os;
449 os <<
"*** Realloc imports_ from " << imports_.dimension_0 () <<
" to " 450 << newSize << std::endl;
451 std::cerr << os.str ();
456 execution_space::fence ();
457 imports_ = decltype (imports_) (
"imports", newSize);
458 execution_space::fence ();
459 TEUCHOS_TEST_FOR_EXCEPTION
460 (static_cast<size_t> (imports_.dimension_0 ()) != newSize,
461 std::logic_error,
"DualView reallocation failed: " 462 "imports_.dimension_0() = " << imports_.dimension_0 ()
463 <<
" != " << newSize <<
".");
467 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
473 const Teuchos::ArrayView<const LocalOrdinal>& permuteToLIDs,
474 const Teuchos::ArrayView<const LocalOrdinal>& permuteFromLIDs,
475 const Teuchos::ArrayView<const LocalOrdinal>& remoteLIDs,
476 const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs,
481 const bool debug =
false;
483 #ifdef HAVE_TPETRA_TRANSFER_TIMERS 484 Teuchos::TimeMonitor doXferMon (*doXferTimer_);
485 #endif // HAVE_TPETRA_TRANSFER_TIMERS 487 TEUCHOS_TEST_FOR_EXCEPTION(
488 ! checkSizes (src), std::invalid_argument,
489 "Tpetra::DistObject::doTransfer(): checkSizes() indicates that the " 490 "destination object is not a legal target for redistribution from the " 491 "source object. This probably means that they do not have the same " 492 "dimensions. For example, MultiVectors must have the same number of " 493 "rows and columns.");
494 KokkosClassic::ReadWriteOption rwo = KokkosClassic::ReadWrite;
496 const size_t numIDsToWrite = numSameIDs +
497 static_cast<size_t> (permuteToLIDs.size ()) +
498 static_cast<size_t> (remoteLIDs.size ());
499 if (numIDsToWrite == this->getMap ()->getNodeNumElements ()) {
507 rwo = KokkosClassic::WriteOnly;
518 const this_type* srcDistObj =
dynamic_cast<const this_type*
> (&src);
519 if (srcDistObj != NULL) {
520 srcDistObj->createViews ();
535 this->createViewsNonConst (rwo);
537 if (numSameIDs + permuteToLIDs.size()) {
538 #ifdef HAVE_TPETRA_TRANSFER_TIMERS 539 Teuchos::TimeMonitor copyAndPermuteMon (*copyAndPermuteTimer_);
540 #endif // HAVE_TPETRA_TRANSFER_TIMERS 542 copyAndPermute (src, numSameIDs, permuteToLIDs, permuteFromLIDs);
553 size_t constantNumPackets = this->constantNumberOfPackets ();
560 if (constantNumPackets == 0) {
563 execution_space::fence ();
564 numExportPacketsPerLID_ =
565 decltype (numExportPacketsPerLID_) (
"numExportPacketsPerLID",
567 execution_space::fence ();
568 numImportPacketsPerLID_ =
569 decltype (numImportPacketsPerLID_) (
"numImportPacketsPerLID",
571 execution_space::fence ();
575 #ifdef HAVE_TPETRA_TRANSFER_TIMERS 576 Teuchos::TimeMonitor packAndPrepareMon (*packAndPrepareTimer_);
577 #endif // HAVE_TPETRA_TRANSFER_TIMERS 583 numExportPacketsPerLID_.template modify<Kokkos::HostSpace> ();
584 Teuchos::ArrayView<size_t> numExportPacketsPerLID =
592 Teuchos::Array<packet_type> exportsOld;
593 packAndPrepare (src, exportLIDs, exportsOld, numExportPacketsPerLID,
594 constantNumPackets, distor);
595 const size_t exportsLen =
static_cast<size_t> (exportsOld.size ());
596 if (static_cast<size_t> (exports_.dimension_0 ()) != exportsLen) {
599 execution_space::fence ();
600 exports_ = decltype (exports_) (
"exports", exportsLen);
601 execution_space::fence ();
603 Kokkos::View<
const packet_type*, Kokkos::HostSpace,
604 Kokkos::MemoryUnmanaged> exportsOldK (exportsOld.getRawPtr (),
606 exports_.template modify<Kokkos::HostSpace> ();
616 if (srcDistObj != NULL) {
617 srcDistObj->releaseViews ();
622 if (constantNumPackets != 0) {
627 const size_t rbufLen = remoteLIDs.size() * constantNumPackets;
629 std::ostringstream os;
630 os <<
"*** doTransferOld: Const # packets: imports_.dimension_0() = " 631 << imports_.dimension_0 () <<
", rbufLen = " << rbufLen
633 std::cerr << os.str ();
635 reallocImportsIfNeeded (rbufLen, debug);
639 bool needCommunication =
true;
640 if (revOp == DoReverse && ! isDistributed ()) {
641 needCommunication =
false;
650 else if (revOp == DoForward && srcDistObj != NULL &&
651 ! srcDistObj->isDistributed ()) {
652 needCommunication =
false;
655 if (needCommunication) {
656 if (revOp == DoReverse) {
657 #ifdef HAVE_TPETRA_TRANSFER_TIMERS 658 Teuchos::TimeMonitor doPostsAndWaitsMon (*doPostsAndWaitsTimer_);
659 #endif // HAVE_TPETRA_TRANSFER_TIMERS 660 if (constantNumPackets == 0) {
666 numExportPacketsPerLID_.template sync<Kokkos::HostSpace> ();
667 Teuchos::ArrayView<const size_t> numExportPacketsPerLID =
674 numImportPacketsPerLID_.template modify<Kokkos::HostSpace> ();
675 Teuchos::ArrayView<size_t> numImportPacketsPerLID =
678 numImportPacketsPerLID);
679 size_t totalImportPackets = 0;
680 for (Array_size_type i = 0; i < numImportPacketsPerLID.size (); ++i) {
681 totalImportPackets += numImportPacketsPerLID[i];
684 reallocImportsIfNeeded (totalImportPackets, debug);
690 imports_.template modify<Kokkos::HostSpace> ();
691 Teuchos::ArrayView<packet_type> hostImports =
693 exports_.template sync<Kokkos::HostSpace> ();
694 Teuchos::ArrayView<const packet_type> hostExports =
697 numExportPacketsPerLID,
699 numImportPacketsPerLID);
706 imports_.template modify<Kokkos::HostSpace> ();
707 Teuchos::ArrayView<packet_type> hostImports =
709 exports_.template sync<Kokkos::HostSpace> ();
710 Teuchos::ArrayView<const packet_type> hostExports =
718 #ifdef HAVE_TPETRA_TRANSFER_TIMERS 719 Teuchos::TimeMonitor doPostsAndWaitsMon (*doPostsAndWaitsTimer_);
720 #endif // HAVE_TPETRA_TRANSFER_TIMERS 721 if (constantNumPackets == 0) {
727 numExportPacketsPerLID_.template sync<Kokkos::HostSpace> ();
728 Teuchos::ArrayView<const size_t> numExportPacketsPerLID =
735 numImportPacketsPerLID_.template modify<Kokkos::HostSpace> ();
736 Teuchos::ArrayView<size_t> numImportPacketsPerLID =
739 numImportPacketsPerLID);
740 size_t totalImportPackets = 0;
741 for (Array_size_type i = 0; i < numImportPacketsPerLID.size (); ++i) {
742 totalImportPackets += numImportPacketsPerLID[i];
745 reallocImportsIfNeeded (totalImportPackets, debug);
751 imports_.template modify<Kokkos::HostSpace> ();
752 Teuchos::ArrayView<packet_type> hostImports =
754 exports_.template sync<Kokkos::HostSpace> ();
755 Teuchos::ArrayView<const packet_type> hostExports =
758 numExportPacketsPerLID,
760 numImportPacketsPerLID);
767 imports_.template modify<Kokkos::HostSpace> ();
768 Teuchos::ArrayView<packet_type> hostImports =
770 exports_.template sync<Kokkos::HostSpace> ();
771 Teuchos::ArrayView<const packet_type> hostExports =
779 #ifdef HAVE_TPETRA_TRANSFER_TIMERS 780 Teuchos::TimeMonitor unpackAndCombineMon (*unpackAndCombineTimer_);
781 #endif // HAVE_TPETRA_TRANSFER_TIMERS 786 imports_.template modify<Kokkos::HostSpace> ();
787 Teuchos::ArrayView<packet_type> hostImports =
792 numImportPacketsPerLID_.template sync<Kokkos::HostSpace> ();
796 Teuchos::ArrayView<size_t> numImportPacketsPerLID =
798 unpackAndCombine (remoteLIDs, hostImports, numImportPacketsPerLID,
799 constantNumPackets, distor, CM);
804 this->releaseViews ();
807 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
809 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node, classic>::
810 doTransferNew (
const SrcDistObject& src,
812 const size_t numSameIDs,
813 const Kokkos::DualView<
const local_ordinal_type*,
814 device_type>& permuteToLIDs,
815 const Kokkos::DualView<
const local_ordinal_type*,
816 device_type>& permuteFromLIDs,
817 const Kokkos::DualView<
const local_ordinal_type*,
818 device_type>& remoteLIDs,
819 const Kokkos::DualView<
const local_ordinal_type*,
820 device_type>& exportLIDs,
822 const ReverseOption revOp,
823 const bool commOnHost)
826 using Kokkos::Compat::getArrayView;
827 using Kokkos::Compat::getConstArrayView;
828 using Kokkos::Compat::getKokkosViewDeepCopy;
829 using Kokkos::Compat::create_const_view;
830 typedef LocalOrdinal LO;
831 typedef typename Kokkos::DualView<LO*,
832 device_type>::t_dev::memory_space dev_memory_space;
833 typedef typename Kokkos::DualView<LO*,
834 device_type>::t_host::memory_space host_memory_space;
835 const bool debug =
false;
838 std::ostringstream os;
839 os <<
">>> DistObject::doTransferNew: remoteLIDs.size() = " 840 << remoteLIDs.dimension_0 () << std::endl;
841 std::cerr << os.str ();
844 #ifdef HAVE_TPETRA_TRANSFER_TIMERS 845 Teuchos::TimeMonitor doXferMon (*doXferTimer_);
846 #endif // HAVE_TPETRA_TRANSFER_TIMERS 849 std::cerr <<
">>> 1. checkSizes" << std::endl;
852 TEUCHOS_TEST_FOR_EXCEPTION(
853 ! checkSizes (src), std::invalid_argument,
854 "Tpetra::DistObject::doTransfer(): checkSizes() indicates that the " 855 "destination object is not a legal target for redistribution from the " 856 "source object. This probably means that they do not have the same " 857 "dimensions. For example, MultiVectors must have the same number of " 858 "rows and columns.");
865 std::cerr <<
">>> 2. copyAndPermuteNew" << std::endl;
868 if (numSameIDs + permuteToLIDs.dimension_0 () != 0) {
870 #ifdef HAVE_TPETRA_TRANSFER_TIMERS 871 Teuchos::TimeMonitor copyAndPermuteMon (*copyAndPermuteTimer_);
872 #endif // HAVE_TPETRA_TRANSFER_TIMERS 873 copyAndPermuteNew (src, numSameIDs, permuteToLIDs, permuteFromLIDs);
884 size_t constantNumPackets = this->constantNumberOfPackets ();
891 if (constantNumPackets == 0) {
893 std::cerr <<
">>> 3. Allocate num{Ex,Im}portPacketsPerLID" << std::endl;
899 if (numExportPacketsPerLID_.dimension_0 () != exportLIDs.dimension_0 ()) {
902 execution_space::fence ();
903 numExportPacketsPerLID_ =
904 decltype (numExportPacketsPerLID_) (
"numExportPacketsPerLID",
905 exportLIDs.dimension_0 ());
906 execution_space::fence ();
908 if (numImportPacketsPerLID_.dimension_0 () != remoteLIDs.dimension_0 ()) {
911 execution_space::fence ();
912 numImportPacketsPerLID_ =
913 decltype (numImportPacketsPerLID_) (
"numImportPacketsPerLID",
914 remoteLIDs.dimension_0 ());
915 execution_space::fence ();
920 std::cerr <<
">>> 4. packAndPrepareNew" << std::endl;
924 #ifdef HAVE_TPETRA_TRANSFER_TIMERS 925 Teuchos::TimeMonitor packAndPrepareMon (*packAndPrepareTimer_);
926 #endif // HAVE_TPETRA_TRANSFER_TIMERS 929 std::ostringstream os;
930 const int myRank = this->getMap ()->getComm ()->getRank ();
931 os <<
">>> (Proc " << myRank <<
") 5.0. Before packAndPrepareNew, " 932 "exports_.dimension_0()=" << exports_.dimension_0 () << std::endl;
933 std::cerr << os.str ();
940 packAndPrepareNew (src, exportLIDs, exports_, numExportPacketsPerLID_,
941 constantNumPackets, distor);
943 std::ostringstream os;
944 const int myRank = this->getMap ()->getComm ()->getRank ();
945 os <<
">>> (Proc " << myRank <<
") 5.0. After packAndPrepareNew, " 946 "exports_.dimension_0()=" << exports_.dimension_0 () << std::endl;
947 std::cerr << os.str ();
954 if (constantNumPackets != 0) {
956 std::cerr <<
">>> 6. Realloc imports_" << std::endl;
962 const size_t rbufLen = remoteLIDs.dimension_0 () * constantNumPackets;
963 reallocImportsIfNeeded (rbufLen, debug);
967 bool needCommunication =
true;
970 const this_type* srcDistObj =
dynamic_cast<const this_type*
> (&src);
972 if (revOp == DoReverse && ! isDistributed ()) {
973 needCommunication =
false;
982 else if (revOp == DoForward && srcDistObj != NULL &&
983 ! srcDistObj->isDistributed ()) {
984 needCommunication =
false;
995 if (needCommunication) {
996 if (revOp == DoReverse) {
998 std::cerr <<
">>> 7.0. Reverse mode" << std::endl;
1001 #ifdef HAVE_TPETRA_TRANSFER_TIMERS 1002 Teuchos::TimeMonitor doPostsAndWaitsMon (*doPostsAndWaitsTimer_);
1003 #endif // HAVE_TPETRA_TRANSFER_TIMERS 1004 if (constantNumPackets == 0) {
1006 std::cerr <<
">>> 7.1. Variable # packets / LID: first comm" 1009 numExportPacketsPerLID_.template sync<host_memory_space> ();
1010 numImportPacketsPerLID_.template sync<host_memory_space> ();
1011 distor.doReversePostsAndWaits (create_const_view (numExportPacketsPerLID_.template view<host_memory_space> ()),
1013 numImportPacketsPerLID_.template view<host_memory_space> ());
1014 size_t totalImportPackets = 0;
1020 typedef decltype (numImportPacketsPerLID_) dual_view_type;
1021 typedef typename dual_view_type::t_host host_view_type;
1022 typedef typename host_view_type::const_type const_host_view_type;
1024 const_host_view_type host_numImportPacketsPerLID =
1025 numImportPacketsPerLID_.template view<host_memory_space> ();
1026 const view_size_type numLids = host_numImportPacketsPerLID.size ();
1027 for (view_size_type i = 0; i < numLids; ++i) {
1028 totalImportPackets += host_numImportPacketsPerLID[i];
1033 std::cerr <<
">>> 7.2. Realloc" << std::endl;
1036 reallocImportsIfNeeded (totalImportPackets, debug);
1039 std::cerr <<
">>> 7.3. Second comm" << std::endl;
1043 numExportPacketsPerLID_.template sync<host_memory_space> ();
1044 numImportPacketsPerLID_.template sync<host_memory_space> ();
1046 imports_.template modify<host_memory_space> ();
1047 distor.doReversePostsAndWaits (create_const_view (exports_.template view<host_memory_space> ()),
1049 imports_.template view<host_memory_space> (),
1059 numExportPacketsPerLID_.template sync<host_memory_space> ();
1060 numImportPacketsPerLID_.template sync<host_memory_space> ();
1062 imports_.template modify<dev_memory_space> ();
1063 distor.doReversePostsAndWaits (create_const_view (exports_.template view<dev_memory_space> ()),
1065 imports_.template view<dev_memory_space> (),
1071 const int myRank = this->getMap ()->getComm ()->getRank ();
1072 std::ostringstream os;
1073 os <<
">>> (Proc " << myRank <<
"): 7.1. Const # packets per " 1074 "LID: exports_.dimension_0() = " << exports_.dimension_0 ()
1075 <<
", imports_.dimension_0() = " << imports_.dimension_0 ()
1077 std::cerr << os.str ();
1081 imports_.template modify<host_memory_space> ();
1082 distor.doReversePostsAndWaits (create_const_view (exports_.template view<host_memory_space> ()),
1084 imports_.template view<host_memory_space> ());
1088 imports_.template modify<dev_memory_space> ();
1089 distor.doReversePostsAndWaits (create_const_view (exports_.template view<dev_memory_space> ()),
1091 imports_.template view<dev_memory_space> ());
1097 std::cerr <<
">>> 7.0. Forward mode" << std::endl;
1100 #ifdef HAVE_TPETRA_TRANSFER_TIMERS 1101 Teuchos::TimeMonitor doPostsAndWaitsMon (*doPostsAndWaitsTimer_);
1102 #endif // HAVE_TPETRA_TRANSFER_TIMERS 1103 if (constantNumPackets == 0) {
1105 std::cerr <<
">>> 7.1. Variable # packets / LID: first comm" << std::endl;
1108 numExportPacketsPerLID_.template sync<host_memory_space> ();
1109 numImportPacketsPerLID_.template sync<host_memory_space> ();
1110 distor.doPostsAndWaits (create_const_view (numExportPacketsPerLID_.template view<host_memory_space> ()), 1,
1111 numImportPacketsPerLID_.template view<host_memory_space> ());
1112 size_t totalImportPackets = 0;
1114 typedef decltype (numImportPacketsPerLID_) dual_view_type;
1115 typedef typename dual_view_type::t_host host_view_type;
1116 typedef typename host_view_type::const_type const_host_view_type;
1117 const_host_view_type host_numImportPacketsPerLID =
1118 numImportPacketsPerLID_.template view<host_memory_space> ();
1124 const view_size_type numLids = host_numImportPacketsPerLID.size ();
1125 for (view_size_type i = 0; i < numLids; ++i) {
1126 totalImportPackets += host_numImportPacketsPerLID[i];
1131 std::cerr <<
">>> 7.2. Realloc" << std::endl;
1134 reallocImportsIfNeeded (totalImportPackets, debug);
1137 std::cerr <<
">>> 7.3. Second comm" << std::endl;
1141 numExportPacketsPerLID_.template sync<host_memory_space> ();
1142 numImportPacketsPerLID_.template sync<host_memory_space> ();
1144 imports_.template modify<host_memory_space> ();
1145 distor.doPostsAndWaits (create_const_view (exports_.template view<host_memory_space> ()),
1147 imports_.template view<host_memory_space> (),
1156 numExportPacketsPerLID_.template sync<host_memory_space> ();
1157 numImportPacketsPerLID_.template sync<host_memory_space> ();
1159 imports_.template modify<dev_memory_space> ();
1160 distor.doPostsAndWaits (create_const_view (exports_.template view<dev_memory_space> ()),
1162 imports_.template view<dev_memory_space> (),
1168 const int myRank = this->getMap ()->getComm ()->getRank ();
1169 std::ostringstream os;
1170 os <<
">>> (Proc " << myRank <<
"): 7.1. Const # packets per " 1171 "LID: exports_.dimension_0()=" << exports_.dimension_0 ()
1172 <<
", imports_.dimension_0() = " << imports_.dimension_0 ()
1174 std::cerr << os.str ();
1179 imports_.template modify<host_memory_space> ();
1180 distor.doPostsAndWaits (create_const_view (exports_.template view<host_memory_space> ()),
1182 imports_.template view<host_memory_space> ());
1186 imports_.template modify<dev_memory_space> ();
1187 distor.doPostsAndWaits (create_const_view (exports_.template view<dev_memory_space> ()),
1189 imports_.template view<dev_memory_space> ());
1195 std::cerr <<
">>> 8. unpackAndCombineNew" << std::endl;
1199 #ifdef HAVE_TPETRA_TRANSFER_TIMERS 1200 Teuchos::TimeMonitor unpackAndCombineMon (*unpackAndCombineTimer_);
1201 #endif // HAVE_TPETRA_TRANSFER_TIMERS 1210 unpackAndCombineNew (remoteLIDs, imports_, numImportPacketsPerLID_,
1211 constantNumPackets, distor, CM);
1217 std::cerr <<
">>> 9. Done with doTransferNew" << std::endl;
1221 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1223 DistObject<Packet, LocalOrdinal, GlobalOrdinal, Node, classic>::
1224 print (std::ostream &os)
const 1226 using Teuchos::FancyOStream;
1227 using Teuchos::getFancyOStream;
1229 using Teuchos::rcpFromRef;
1232 RCP<FancyOStream> out = getFancyOStream (rcpFromRef (os));
1233 this->describe (*out, Teuchos::VERB_DEFAULT);
1236 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1242 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1248 template <
class Packet,
class LocalOrdinal,
class GlobalOrdinal,
class Node, const
bool classic>
1254 template<
class DistObjectType>
1257 const Teuchos::RCP<
const Map<
typename DistObjectType::local_ordinal_type,
1258 typename DistObjectType::global_ordinal_type,
1259 typename DistObjectType::node_type> >& newMap)
1261 input->removeEmptyProcessesInPlace (newMap);
1262 if (newMap.is_null ()) {
1263 input = Teuchos::null;
1267 template<
class DistObjectType>
1272 typedef typename DistObjectType::local_ordinal_type LO;
1273 typedef typename DistObjectType::global_ordinal_type GO;
1274 typedef typename DistObjectType::node_type NT;
1278 removeEmptyProcessesInPlace<DistObjectType> (input, newMap);
1282 #define TPETRA_DISTOBJECT_INSTANT(SCALAR, LO, GO, NODE) \ 1283 template class DistObject< SCALAR , LO , GO , NODE >; 1287 #define TPETRA_DISTOBJECT_INSTANT_CHAR(LO, GO, NODE) \ 1288 template class DistObject< char , LO , GO , NODE >; 1292 #endif // TPETRA_DISTOBJECT_DEF_HPP void doPostsAndWaits(const Teuchos::ArrayView< const Packet > &exports, size_t numPackets, const Teuchos::ArrayView< Packet > &imports)
Execute the (forward) communication plan.
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
Namespace Tpetra contains the class and methods constituting the Tpetra library.
Teuchos::ArrayView< const LocalOrdinal > getExportLIDs() const
List of entries in the source Map that will be sent to other processes.
Teuchos::ArrayView< const LocalOrdinal > getExportLIDs() const
List of entries in the source Map that will be sent to other processes.
Distributor & getDistributor() const
The Distributor that this Export object uses to move data.
Teuchos::RCP< const map_type > getSourceMap() const
The Source Map used to construct this Import object.
size_t getNumSameIDs() const
Number of initial identical IDs.
Teuchos::ArrayView< const LocalOrdinal > getPermuteFromLIDs() const
List of local IDs in the source Map that are permuted.
void deep_copy(MultiVector< DS, DL, DG, DN, dstClassic > &dst, const MultiVector< SS, SL, SG, SN, srcClassic > &src)
Copy the contents of the MultiVector src into dst.
Teuchos::RCP< const map_type > getSourceMap() const
The source Map used to construct this Export.
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.
Teuchos::ArrayView< const LocalOrdinal > getPermuteToLIDs() const
List of local IDs in the target Map that are permuted.
void doReversePostsAndWaits(const Teuchos::ArrayView< const Packet > &exports, size_t numPackets, const Teuchos::ArrayView< Packet > &imports)
Execute the reverse communication plan.
Node::device_type device_type
The Kokkos Device type.
Teuchos::ArrayView< const LocalOrdinal > getPermuteFromLIDs() const
List of local IDs in the source Map that are permuted.
Insert new values that don't currently exist.
Teuchos::ArrayView< const LocalOrdinal > getPermuteToLIDs() const
List of local IDs in the target Map that are permuted.
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...
Teuchos::ArrayView< const LocalOrdinal > getRemoteLIDs() const
List of entries in the target Map to receive from other processes.
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
Teuchos::RCP< const map_type > getTargetMap() const
The Target Map used to construct this Import object.
Sets up and executes a communication plan for a Tpetra DistObject.
CombineMode
Rule for combining data in an Import or Export.
virtual Teuchos::RCP< const map_type > getMap() const
The Map describing the parallel distribution of this object.
Abstract base class for objects that can be the source of an Import or Export operation.
Replace existing values with new values.
Replace old values with zero.
ReverseOption
Whether the data transfer should be performed in forward or reverse mode.
DistObject(const Teuchos::RCP< const map_type > &map)
Constructor.
Describes a parallel distribution of objects over processes.
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.
Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > removeEmptyProcesses() const
Return a new Map with processes with zero elements removed.
size_t getNumSameIDs() const
Number of initial identical IDs.
Distributor & getDistributor() const
The Distributor that this Import object uses to move data.
Teuchos::ArrayView< const LocalOrdinal > getRemoteLIDs() const
List of entries in the target Map to receive from other processes.
bool isDistributed() const
Whether this is a globally distributed object.
Base class for distributed Tpetra objects that support data redistribution.
Teuchos::RCP< const map_type > getTargetMap() const
The target Map used to construct this Export.