10 #ifndef TPETRA_DISTRIBUTOR_HPP
11 #define TPETRA_DISTRIBUTOR_HPP
13 #include "Tpetra_Details_DistributorActor.hpp"
17 #include "Teuchos_as.hpp"
18 #include "Teuchos_Describable.hpp"
19 #include "Teuchos_ParameterListAcceptorDefaultBase.hpp"
20 #include "Teuchos_VerboseObject.hpp"
23 #include "KokkosCompat_View.hpp"
24 #include "Kokkos_Core.hpp"
25 #include "Kokkos_TeuchosCommAdapters.hpp"
26 #include "Kokkos_StdAlgorithms.hpp"
29 #include <type_traits>
104 public Teuchos::Describable,
105 public Teuchos::ParameterListAcceptorDefaultBase {
118 explicit Distributor (
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm);
131 Distributor (
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
132 const Teuchos::RCP<Teuchos::FancyOStream>& out);
147 Distributor (
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
148 const Teuchos::RCP<Teuchos::ParameterList>& plist);
166 Distributor (
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
167 const Teuchos::RCP<Teuchos::FancyOStream>& out,
168 const Teuchos::RCP<Teuchos::ParameterList>& plist);
225 size_t createFromSends (
const Teuchos::ArrayView<const int>& exportProcIDs);
260 template <
class Ordinal>
263 const Teuchos::ArrayView<const int>& remoteProcIDs,
264 Teuchos::Array<Ordinal>& exportIDs,
265 Teuchos::Array<int>& exportProcIDs);
276 const Teuchos::ArrayView<const int>& remoteProcIDs);
311 Teuchos::ArrayView<const int>
getProcsTo()
const;
336 return plan_.howInitialized();
353 Teuchos::RCP<Distributor>
getReverse(
bool create=
true)
const;
395 template <
class ExpView,
class ImpView>
396 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
398 const ExpView &exports,
400 const ImpView &imports);
423 template <
class ExpView,
class ImpView>
424 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
426 const Teuchos::ArrayView<const size_t>& numExportPacketsPerLID,
427 const ImpView &imports,
428 const Teuchos::ArrayView<const size_t>& numImportPacketsPerLID);
430 template <
class ExpView,
class ExpPacketsView,
class ImpView,
class ImpPacketsView>
431 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
432 doPostsAndWaitsKokkos (
const ExpView &exports,
433 const ExpPacketsView &numExportPacketsPerLID,
434 const ImpView &imports,
435 const ImpPacketsView &numImportPacketsPerLID);
461 template <
class ExpView,
class ImpView>
462 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
463 doPosts (
const ExpView &exports,
465 const ImpView &imports);
485 template <
class ExpView,
class ImpView>
486 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
487 doPosts (
const ExpView &exports,
488 const Teuchos::ArrayView<const size_t>& numExportPacketsPerLID,
489 const ImpView &imports,
490 const Teuchos::ArrayView<const size_t>& numImportPacketsPerLID);
492 template <
class ExpView,
class ExpPacketsView,
class ImpView,
class ImpPacketsView>
493 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
494 doPostsKokkos (
const ExpView &exports,
495 const ExpPacketsView &numExportPacketsPerLID,
496 const ImpView &imports,
497 const ImpPacketsView &numImportPacketsPerLID);
503 template <
class ExpView,
class ImpView>
504 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
507 const ImpView &imports);
513 template <
class ExpView,
class ImpView>
514 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
516 const Teuchos::ArrayView<const size_t>& numExportPacketsPerLID,
517 const ImpView &imports,
518 const Teuchos::ArrayView<const size_t>& numImportPacketsPerLID);
520 template <
class ExpView,
class ExpPacketsView,
class ImpView,
class ImpPacketsView>
521 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
522 doReversePostsAndWaitsKokkos (
const ExpView &exports,
523 const ExpPacketsView &numExportPacketsPerLID,
524 const ImpView &imports,
525 const ImpPacketsView &numImportPacketsPerLID);
531 template <
class ExpView,
class ImpView>
532 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
535 const ImpView &imports);
541 template <
class ExpView,
class ImpView>
542 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
544 const Teuchos::ArrayView<const size_t>& numExportPacketsPerLID,
545 const ImpView &imports,
546 const Teuchos::ArrayView<const size_t>& numImportPacketsPerLID);
548 template <
class ExpView,
class ExpPacketsView,
class ImpView,
class ImpPacketsView>
549 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
550 doReversePostsKokkos (
const ExpView &exports,
551 const ExpPacketsView &numExportPacketsPerLID,
552 const ImpView &imports,
553 const ImpPacketsView &numImportPacketsPerLID);
584 describe (Teuchos::FancyOStream& out,
585 const Teuchos::EVerbosityLevel verbLevel =
586 Teuchos::Describable::verbLevel_default)
const;
596 Details::DistributorActor actor_;
602 static bool getVerbose();
608 std::unique_ptr<std::string>
609 createPrefix(
const char methodName[])
const;
612 bool verbose_ = getVerbose();
619 mutable Teuchos::RCP<Distributor> reverseDistributor_;
633 template <
class Ordinal>
634 void computeSends (
const Teuchos::ArrayView<const Ordinal> &remoteGIDs,
635 const Teuchos::ArrayView<const int> &remoteProcIDs,
636 Teuchos::Array<Ordinal> &exportGIDs,
637 Teuchos::Array<int> &exportProcIDs);
640 void createReverseDistributor()
const;
648 localDescribeToString (
const Teuchos::EVerbosityLevel vl)
const;
651 template <
class ExpView,
class ImpView>
652 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
654 doPostsAndWaits (
const ExpView& exports,
656 const ImpView& imports)
658 actor_.doPostsAndWaits(plan_, exports, numPackets, imports);
661 template <
class ExpView,
class ImpView>
662 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
664 doPostsAndWaits(
const ExpView& exports,
665 const Teuchos::ArrayView<const size_t>& numExportPacketsPerLID,
666 const ImpView& imports,
667 const Teuchos::ArrayView<const size_t>& numImportPacketsPerLID)
669 actor_.
doPostsAndWaits(plan_, exports, numExportPacketsPerLID, imports, numImportPacketsPerLID);
672 template <
class ExpView,
class ExpPacketsView,
class ImpView,
class ImpPacketsView>
673 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
675 doPostsAndWaitsKokkos (
const ExpView &exports,
676 const ExpPacketsView &numExportPacketsPerLID,
677 const ImpView &imports,
678 const ImpPacketsView &numImportPacketsPerLID)
680 actor_.doPostsAndWaitsKokkos(plan_, exports, numExportPacketsPerLID, imports, numImportPacketsPerLID);
683 template <
class ExpView,
class ImpView>
684 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
686 doPosts (
const ExpView &exports,
688 const ImpView &imports)
690 actor_.doPosts(plan_, exports, numPackets, imports);
693 template <
class ExpView,
class ImpView>
694 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
696 doPosts (
const ExpView &exports,
697 const Teuchos::ArrayView<const size_t>& numExportPacketsPerLID,
698 const ImpView &imports,
699 const Teuchos::ArrayView<const size_t>& numImportPacketsPerLID)
701 actor_.
doPosts(plan_, exports, numExportPacketsPerLID, imports, numImportPacketsPerLID);
704 template <
class ExpView,
class ExpPacketsView,
class ImpView,
class ImpPacketsView>
705 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
707 doPostsKokkos (
const ExpView &exports,
708 const ExpPacketsView &numExportPacketsPerLID,
709 const ImpView &imports,
710 const ImpPacketsView &numImportPacketsPerLID)
712 actor_.doPostsKokkos(plan_, exports, numExportPacketsPerLID, imports, numImportPacketsPerLID);
715 template <
class ExpView,
class ImpView>
716 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
718 doReversePostsAndWaits (
const ExpView& exports,
720 const ImpView& imports)
722 doReversePosts (exports, numPackets, imports);
726 template <
class ExpView,
class ImpView>
727 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
729 doReversePostsAndWaits (
const ExpView& exports,
730 const Teuchos::ArrayView<const size_t>& numExportPacketsPerLID,
731 const ImpView& imports,
732 const Teuchos::ArrayView<const size_t>& numImportPacketsPerLID)
734 doReversePosts (exports, numExportPacketsPerLID, imports,
735 numImportPacketsPerLID);
739 template <
class ExpView,
class ExpPacketsView,
class ImpView,
class ImpPacketsView>
740 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
742 doReversePostsAndWaitsKokkos (
const ExpView& exports,
743 const ExpPacketsView &numExportPacketsPerLID,
744 const ImpView& imports,
745 const ImpPacketsView &numImportPacketsPerLID)
747 doReversePostsKokkos (exports, numExportPacketsPerLID, imports,
748 numImportPacketsPerLID);
752 template <
class ExpView,
class ImpView>
753 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
755 doReversePosts (
const ExpView &exports,
757 const ImpView &imports)
760 TEUCHOS_TEST_FOR_EXCEPTION(
761 ! plan_.getIndicesTo().is_null(), std::runtime_error,
762 "Tpetra::Distributor::doReversePosts(3 args): Can only do "
763 "reverse communication when original data are blocked by process.");
764 if (reverseDistributor_.is_null ()) {
765 createReverseDistributor ();
767 reverseDistributor_->doPosts (exports, numPackets, imports);
770 template <
class ExpView,
class ImpView>
771 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
773 doReversePosts (
const ExpView &exports,
774 const Teuchos::ArrayView<const size_t>& numExportPacketsPerLID,
775 const ImpView &imports,
776 const Teuchos::ArrayView<const size_t>& numImportPacketsPerLID)
779 TEUCHOS_TEST_FOR_EXCEPTION(
780 ! plan_.getIndicesTo().is_null(), std::runtime_error,
781 "Tpetra::Distributor::doReversePosts(3 args): Can only do "
782 "reverse communication when original data are blocked by process.");
783 if (reverseDistributor_.is_null ()) {
784 createReverseDistributor ();
786 reverseDistributor_->doPosts (exports, numExportPacketsPerLID,
787 imports, numImportPacketsPerLID);
790 template <
class ExpView,
class ExpPacketsView,
class ImpView,
class ImpPacketsView>
791 typename std::enable_if<(Kokkos::is_view<ExpView>::value && Kokkos::is_view<ImpView>::value)>::type
793 doReversePostsKokkos (
const ExpView &exports,
794 const ExpPacketsView &numExportPacketsPerLID,
795 const ImpView &imports,
796 const ImpPacketsView &numImportPacketsPerLID)
799 TEUCHOS_TEST_FOR_EXCEPTION(
800 ! plan_.getIndicesTo().is_null(), std::runtime_error,
801 "Tpetra::Distributor::doReversePosts(3 args): Can only do "
802 "reverse communication when original data are blocked by process.");
803 if (reverseDistributor_.is_null ()) {
804 createReverseDistributor ();
806 reverseDistributor_->doPostsKokkos (exports, numExportPacketsPerLID,
807 imports, numImportPacketsPerLID);
810 template <
class OrdinalType>
812 computeSends(
const Teuchos::ArrayView<const OrdinalType>& importGIDs,
813 const Teuchos::ArrayView<const int>& importProcIDs,
814 Teuchos::Array<OrdinalType>& exportGIDs,
815 Teuchos::Array<int>& exportProcIDs)
824 using Teuchos::ArrayView;
826 using size_type =
typename ArrayView<const OrdinalType>::size_type;
827 const char errPrefix[] =
"Tpetra::Distributor::computeSends: ";
828 const char suffix[] =
829 " Please report this bug to the Tpetra developers.";
831 const int myRank = plan_.getComm()->getRank ();
833 TEUCHOS_TEST_FOR_EXCEPTION
834 (importGIDs.size () != importProcIDs.size (),
835 std::invalid_argument, errPrefix <<
"On Process " << myRank
836 <<
": importProcIDs.size()=" << importProcIDs.size()
837 <<
" != importGIDs.size()=" << importGIDs.size() <<
".");
839 const size_type numImports = importProcIDs.size();
840 Kokkos::View<size_t*, Kokkos::HostSpace> importObjs(
"importObjs", 2*numImports);
842 for (size_type i = 0; i < numImports; ++i) {
843 importObjs[2*i] =
static_cast<size_t>(importGIDs[i]);
844 importObjs[2*i+1] =
static_cast<size_t>(myRank);
853 const size_t numExportsAsSizeT =
854 tempPlan.createFromSends(importProcIDs);
855 const size_type numExports =
856 static_cast<size_type
>(numExportsAsSizeT);
857 TEUCHOS_TEST_FOR_EXCEPTION
858 (numExports < 0, std::logic_error, errPrefix <<
859 "tempPlan.createFromSends() returned numExports="
860 << numExportsAsSizeT <<
" as a size_t, which overflows to "
861 << numExports <<
" when cast to " <<
862 Teuchos::TypeNameTraits<size_type>::name () <<
"." << suffix);
863 TEUCHOS_TEST_FOR_EXCEPTION
864 (size_type(tempPlan.getTotalReceiveLength()) != numExports,
865 std::logic_error, errPrefix <<
"tempPlan.getTotalReceiveLength()="
866 << tempPlan.getTotalReceiveLength () <<
" != numExports="
867 << numExports <<
"." << suffix);
869 if (numExports > 0) {
870 exportGIDs.resize(numExports);
871 exportProcIDs.resize(numExports);
882 static_assert(
sizeof(
size_t) >=
sizeof(OrdinalType),
883 "Tpetra::Distributor::computeSends: "
884 "sizeof(size_t) < sizeof(OrdinalType).");
886 TEUCHOS_TEST_FOR_EXCEPTION
887 (tempPlan.getTotalReceiveLength () < size_t(numExports),
889 errPrefix <<
"tempPlan.getTotalReceiveLength()="
890 << tempPlan.getTotalReceiveLength() <<
" < numExports="
891 << numExports <<
"." << suffix);
893 Kokkos::View<size_t*, Kokkos::HostSpace> exportObjs(
"exportObjs", tempPlan.getTotalReceiveLength() * 2);
894 tempPlan.doPostsAndWaits(importObjs, 2, exportObjs);
897 for (size_type i = 0; i < numExports; ++i) {
898 exportGIDs[i] =
static_cast<OrdinalType
> (exportObjs[2*i]);
899 exportProcIDs[i] =
static_cast<int> (exportObjs[2*i+1]);
903 template <
class OrdinalType>
905 createFromRecvs (
const Teuchos::ArrayView<const OrdinalType> &remoteGIDs,
906 const Teuchos::ArrayView<const int> &remoteProcIDs,
907 Teuchos::Array<OrdinalType> &exportGIDs,
908 Teuchos::Array<int> &exportProcIDs)
911 const char errPrefix[] =
"Tpetra::Distributor::createFromRecvs: ";
912 const int myRank = plan_.getComm()->getRank();
914 std::unique_ptr<std::string> prefix;
916 prefix = createPrefix(
"createFromRecvs");
917 std::ostringstream os;
918 os << *prefix <<
"Start" << endl;
919 std::cerr << os.str();
924 using Teuchos::outArg;
925 using Teuchos::REDUCE_MAX;
926 using Teuchos::reduceAll;
930 (remoteGIDs.size () != remoteProcIDs.size ()) ? myRank : -1;
932 reduceAll(*plan_.getComm(), REDUCE_MAX, errProc, outArg(maxErrProc));
933 TEUCHOS_TEST_FOR_EXCEPTION
934 (maxErrProc != -1, std::runtime_error, errPrefix <<
"Lists "
935 "of remote IDs and remote process IDs must have the same "
936 "size on all participating processes. Maximum process ID "
937 "with error: " << maxErrProc <<
".");
942 TEUCHOS_TEST_FOR_EXCEPTION
943 (remoteGIDs.size() != remoteProcIDs.size(), std::runtime_error,
944 errPrefix <<
"On Process " << myRank <<
": "
945 "remoteGIDs.size()=" << remoteGIDs.size() <<
946 " != remoteProcIDs.size()=" << remoteProcIDs.size() <<
".");
949 computeSends(remoteGIDs, remoteProcIDs, exportGIDs, exportProcIDs);
951 plan_.createFromRecvs(remoteProcIDs);
954 std::ostringstream os;
955 os << *prefix <<
"Done" << endl;
956 std::cerr << os.str();
962 #endif // TPETRA_DISTRIBUTOR_HPP
const Details::DistributorPlan & getPlan() const
Get this Distributor's DistributorPlan.
size_t getNumReceives() const
The number of processes from which we will receive data.
std::string description() const
Return a one-line description of this object.
std::enable_if<(Kokkos::is_view< ExpView >::value &&Kokkos::is_view< ImpView >::value)>::type doReversePostsAndWaits(const ExpView &exports, size_t numPackets, const ImpView &imports)
Execute the reverse communication plan.
Teuchos::RCP< Distributor > getReverse(bool create=true) const
A reverse communication plan Distributor.
EDistributorHowInitialized
Enum indicating how and whether a Distributor was initialized.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
List of valid Distributor parameters.
virtual ~Distributor()=default
Destructor (virtual for memory safety).
static bool debug()
Whether Tpetra is in debug mode.
std::enable_if<(Kokkos::is_view< ExpView >::value &&Kokkos::is_view< ImpView >::value)>::type doPosts(const ExpView &exports, size_t numPackets, const ImpView &imports)
Post the data for a forward plan, but do not execute the waits yet.
void swap(Distributor &rhs)
Swap the contents of rhs with those of *this.
Teuchos::ArrayView< const size_t > getLengthsFrom() const
Number of values this process will receive from each process.
Teuchos::ArrayView< const int > getProcsFrom() const
Ranks of the processes sending values to this process.
size_t createFromSends(const Teuchos::ArrayView< const int > &exportProcIDs)
Set up Distributor using list of process ranks to which this process will send.
Details::EDistributorHowInitialized howInitialized() const
Return an enum indicating whether and how a Distributor was initialized.
Teuchos::ArrayView< const int > getProcsTo() const
Ranks of the processes to which this process will send values.
void createFromSendsAndRecvs(const Teuchos::ArrayView< const int > &exportProcIDs, const Teuchos::ArrayView< const int > &remoteProcIDs)
Set up Distributor using list of process ranks to which to send, and list of process ranks from which...
bool hasSelfMessage() const
Whether the calling process will send or receive messages to itself.
std::enable_if<(Kokkos::is_view< ExpView >::value &&Kokkos::is_view< ImpView >::value)>::type doReversePosts(const ExpView &exports, size_t numPackets, const ImpView &imports)
Post the data for a reverse plan, but do not execute the waits yet.
Sets up and executes a communication plan for a Tpetra DistObject.
size_t getTotalReceiveLength() const
Total number of values this process will receive from other processes.
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &plist)
Set Distributor parameters.
Teuchos::ArrayView< const size_t > getLengthsTo() const
Number of values this process will send to each process.
Teuchos::Array< std::string > distributorSendTypes()
Valid values for Distributor's "Send type" parameter.
std::enable_if<(Kokkos::is_view< ExpView >::value &&Kokkos::is_view< ImpView >::value)>::type doPostsAndWaits(const ExpView &exports, size_t numPackets, const ImpView &imports)
Execute the (forward) communication plan.
Stand-alone utility functions and macros.
size_t getNumSends() const
The number of processes to which we will send data.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Describe this object in a human-readable way to the given output stream.
size_t getMaxSendLength() const
Maximum number of values this process will send to another single process.
void createFromRecvs(const Teuchos::ArrayView< const Ordinal > &remoteIDs, const Teuchos::ArrayView< const int > &remoteProcIDs, Teuchos::Array< Ordinal > &exportIDs, Teuchos::Array< int > &exportProcIDs)
Set up Distributor using list of process ranks from which to receive.
Distributor(const Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Construct using the specified communicator and default parameters.
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.