40#ifndef TPETRA_DISTRIBUTOR_HPP
41#define TPETRA_DISTRIBUTOR_HPP
43#include "Tpetra_Details_DistributorActor.hpp"
44#include "Tpetra_Details_DistributorPlan.hpp"
47#include "Teuchos_as.hpp"
48#include "Teuchos_Describable.hpp"
49#include "Teuchos_ParameterListAcceptorDefaultBase.hpp"
50#include "Teuchos_VerboseObject.hpp"
53#include "KokkosCompat_View.hpp"
54#include "Kokkos_Core.hpp"
55#include "Kokkos_TeuchosCommAdapters.hpp"
138 public Teuchos::Describable,
139 public Teuchos::ParameterListAcceptorDefaultBase {
152 explicit Distributor (
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm);
165 Distributor (
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
166 const Teuchos::RCP<Teuchos::FancyOStream>&
out);
181 Distributor (
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
182 const Teuchos::RCP<Teuchos::ParameterList>&
plist);
200 Distributor (
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
201 const Teuchos::RCP<Teuchos::FancyOStream>&
out,
202 const Teuchos::RCP<Teuchos::ParameterList>&
plist);
294 template <
class Ordinal>
345 Teuchos::ArrayView<const int>
getProcsTo()
const;
370 return plan_.howInitialized();
413 template <
class Packet>
417 const Teuchos::ArrayView<Packet> &imports);
440 template <
class Packet>
444 const Teuchos::ArrayView<Packet> &imports,
471 template <
class Packet>
473 doPosts (
const Teuchos::ArrayRCP<const Packet> &exports,
475 const Teuchos::ArrayRCP<Packet> &imports);
495 template <
class Packet>
497 doPosts (
const Teuchos::ArrayRCP<const Packet> &exports,
499 const Teuchos::ArrayRCP<Packet> &imports,
514 template <
class Packet>
518 const Teuchos::ArrayView<Packet> &imports);
524 template <
class Packet>
528 const Teuchos::ArrayView<Packet> &imports,
535 template <
class Packet>
539 const Teuchos::ArrayRCP<Packet> &imports);
545 template <
class Packet>
549 const Teuchos::ArrayRCP<Packet> &imports,
580 template <
class ExpView,
class ImpView>
581 typename std::enable_if<(Kokkos::Impl::is_view<ExpView>::value && Kokkos::Impl::is_view<ImpView>::value)>::type
608 template <
class ExpView,
class ImpView>
609 typename std::enable_if<(Kokkos::Impl::is_view<ExpView>::value && Kokkos::Impl::is_view<ImpView>::value)>::type
639 template <
class ExpView,
class ImpView>
640 typename std::enable_if<(Kokkos::Impl::is_view<ExpView>::value && Kokkos::Impl::is_view<ImpView>::value)>::type
663 template <
class ExpView,
class ImpView>
664 typename std::enable_if<(Kokkos::Impl::is_view<ExpView>::value && Kokkos::Impl::is_view<ImpView>::value)>::type
674 template <
class ExpView,
class ImpView>
675 typename std::enable_if<(Kokkos::Impl::is_view<ExpView>::value && Kokkos::Impl::is_view<ImpView>::value)>::type
684 template <
class ExpView,
class ImpView>
685 typename std::enable_if<(Kokkos::Impl::is_view<ExpView>::value && Kokkos::Impl::is_view<ImpView>::value)>::type
695 template <
class ExpView,
class ImpView>
696 typename std::enable_if<(Kokkos::Impl::is_view<ExpView>::value && Kokkos::Impl::is_view<ImpView>::value)>::type
705 template <
class ExpView,
class ImpView>
706 typename std::enable_if<(Kokkos::Impl::is_view<ExpView>::value && Kokkos::Impl::is_view<ImpView>::value)>::type
750 const Teuchos::EVerbosityLevel
verbLevel =
751 Teuchos::Describable::verbLevel_default)
const;
761 Details::DistributorActor actor_;
767 static bool getVerbose();
773 std::unique_ptr<std::string>
777 bool verbose_ = getVerbose();
784 mutable Teuchos::RCP<Distributor> reverseDistributor_;
787 size_t lastRoundBytesSend_;
790 size_t lastRoundBytesRecv_;
804 template <
class Ordinal>
805 void computeSends (
const Teuchos::ArrayView<const Ordinal> &remoteGIDs,
811 void createReverseDistributor()
const;
819 localDescribeToString (
const Teuchos::EVerbosityLevel
vl)
const;
823 template <
class Packet>
827 const Teuchos::ArrayView<Packet>& imports)
830 using Teuchos::ArrayRCP;
844 static_cast<size_type
> (0),
845 exports.size(),
false);
860 arcp<Packet> (imports.getRawPtr (), 0, imports.size (),
false));
863 lastRoundBytesSend_ = exports.size () *
sizeof (
Packet);
864 lastRoundBytesRecv_ = imports.size () *
sizeof (
Packet);
867 template <
class Packet>
871 const Teuchos::ArrayView<Packet> &imports,
875 using Teuchos::ArrayRCP;
890 static_cast<size_type
> (0),
891 exports.size (),
false);
898 arcp<Packet> (imports.getRawPtr (), 0, imports.size (),
false),
902 lastRoundBytesSend_ = exports.size () *
sizeof (
Packet);
903 lastRoundBytesRecv_ = imports.size () *
sizeof (
Packet);
907 template <
class Packet>
909 doPosts (
const Teuchos::ArrayRCP<const Packet>& exports,
911 const Teuchos::ArrayRCP<Packet>& imports)
913 Kokkos::View<const Packet*, Kokkos::HostSpace>
exportsView(exports.get(), exports.size());
914 Kokkos::View<Packet*, Kokkos::HostSpace>
importsView(imports.get(), imports.size());
918 template <
class Packet>
920 doPosts (
const Teuchos::ArrayRCP<const Packet>& exports,
922 const Teuchos::ArrayRCP<Packet>& imports,
925 Kokkos::View<const Packet*, Kokkos::HostSpace>
exportsView(exports.get(), exports.size());
926 Kokkos::View<Packet*, Kokkos::HostSpace>
importsView(imports.get(), imports.size());
930 template <
class Packet>
934 const Teuchos::ArrayView<Packet>& imports)
937 using Teuchos::ArrayRCP;
952 exports.size(),
false);
959 arcp<Packet> (imports.getRawPtr (), 0, imports.size (),
false));
962 lastRoundBytesSend_ = exports.size() *
sizeof(
Packet);
963 lastRoundBytesRecv_ = imports.size() *
sizeof(
Packet);
966 template <
class Packet>
970 const Teuchos::ArrayView<Packet> &imports,
975 using Teuchos::ArrayRCP;
990 exports.size (),
false);
993 arcp<Packet> (imports.getRawPtr (), 0, imports.size (),
false),
997 lastRoundBytesSend_ = exports.size() *
sizeof(
Packet);
998 lastRoundBytesRecv_ = imports.size() *
sizeof(
Packet);
1001 template <
class Packet>
1005 const Teuchos::ArrayRCP<Packet>& imports)
1009 ! plan_.getIndicesTo().is_null(), std::runtime_error,
1010 "Tpetra::Distributor::doReversePosts(3 args): Can only do reverse "
1011 "communication when original data are blocked by process.");
1012 if (reverseDistributor_.is_null ()) {
1013 createReverseDistributor ();
1015 reverseDistributor_->doPosts (exports,
numPackets, imports);
1018 template <
class Packet>
1022 const Teuchos::ArrayRCP<Packet>& imports,
1027 ! plan_.getIndicesTo().is_null(), std::runtime_error,
1028 "Tpetra::Distributor::doReversePosts(3 args): Can only do reverse "
1029 "communication when original data are blocked by process.");
1030 if (reverseDistributor_.is_null ()) {
1031 createReverseDistributor ();
1037 template <
class ExpView,
class ImpView>
1038 typename std::enable_if<(Kokkos::Impl::is_view<ExpView>::value && Kokkos::Impl::is_view<ImpView>::value)>::type
1044 actor_.doPostsAndWaits(plan_, exports,
numPackets, imports);
1047 template <
class ExpView,
class ImpView>
1048 typename std::enable_if<(Kokkos::Impl::is_view<ExpView>::value && Kokkos::Impl::is_view<ImpView>::value)>::type
1059 template <
class ExpView,
class ImpView>
1060 typename std::enable_if<(Kokkos::Impl::is_view<ExpView>::value && Kokkos::Impl::is_view<ImpView>::value)>::type
1066 actor_.doPosts(plan_, exports,
numPackets, imports);
1069 template <
class ExpView,
class ImpView>
1070 typename std::enable_if<(Kokkos::Impl::is_view<ExpView>::value && Kokkos::Impl::is_view<ImpView>::value)>::type
1080 template <
class ExpView,
class ImpView>
1081 typename std::enable_if<(Kokkos::Impl::is_view<ExpView>::value && Kokkos::Impl::is_view<ImpView>::value)>::type
1087 doReversePosts (exports,
numPackets, imports);
1091 template <
class ExpView,
class ImpView>
1092 typename std::enable_if<(Kokkos::Impl::is_view<ExpView>::value && Kokkos::Impl::is_view<ImpView>::value)>::type
1104 template <
class ExpView,
class ImpView>
1105 typename std::enable_if<(Kokkos::Impl::is_view<ExpView>::value && Kokkos::Impl::is_view<ImpView>::value)>::type
1113 ! plan_.getIndicesTo().is_null(), std::runtime_error,
1114 "Tpetra::Distributor::doReversePosts(3 args): Can only do "
1115 "reverse communication when original data are blocked by process.");
1116 if (reverseDistributor_.is_null ()) {
1117 createReverseDistributor ();
1119 reverseDistributor_->doPosts (exports,
numPackets, imports);
1122 template <
class ExpView,
class ImpView>
1123 typename std::enable_if<(Kokkos::Impl::is_view<ExpView>::value && Kokkos::Impl::is_view<ImpView>::value)>::type
1132 ! plan_.getIndicesTo().is_null(), std::runtime_error,
1133 "Tpetra::Distributor::doReversePosts(3 args): Can only do "
1134 "reverse communication when original data are blocked by process.");
1135 if (reverseDistributor_.is_null ()) {
1136 createReverseDistributor ();
1142 template <
class OrdinalType>
1144 computeSends(
const Teuchos::ArrayView<const OrdinalType>&
importGIDs,
1156 using Teuchos::Array;
1157 using Teuchos::ArrayView;
1160 const char errPrefix[] =
"Tpetra::Distributor::computeSends: ";
1162 " Please report this bug to the Tpetra developers.";
1164 const int myRank = plan_.getComm()->getRank ();
1170 <<
" != importGIDs.size()=" <<
importGIDs.size() <<
".");
1183 Distributor tempPlan(plan_.getComm());
1186 const size_t numExportsAsSizeT =
1187 tempPlan.createFromSends(importProcIDs);
1188 const size_type numExports =
1189 static_cast<size_type
>(numExportsAsSizeT);
1190 TEUCHOS_TEST_FOR_EXCEPTION
1191 (numExports < 0, std::logic_error, errPrefix <<
1192 "tempPlan.createFromSends() returned numExports="
1193 << numExportsAsSizeT <<
" as a size_t, which overflows to "
1194 << numExports <<
" when cast to " <<
1195 Teuchos::TypeNameTraits<size_type>::name () <<
"." << suffix);
1196 TEUCHOS_TEST_FOR_EXCEPTION
1197 (size_type(tempPlan.getTotalReceiveLength()) != numExports,
1198 std::logic_error, errPrefix <<
"tempPlan.getTotalReceiveLength()="
1199 << tempPlan.getTotalReceiveLength () <<
" != numExports="
1200 << numExports <<
"." << suffix);
1202 if (numExports > 0) {
1203 exportGIDs.resize(numExports);
1204 exportProcIDs.resize(numExports);
1215 static_assert(
sizeof(size_t) >=
sizeof(OrdinalType),
1216 "Tpetra::Distributor::computeSends: "
1217 "sizeof(size_t) < sizeof(OrdinalType).");
1219 TEUCHOS_TEST_FOR_EXCEPTION
1220 (tempPlan.getTotalReceiveLength () <
size_t(numExports),
1222 errPrefix <<
"tempPlan.getTotalReceiveLength()="
1223 << tempPlan.getTotalReceiveLength() <<
" < numExports="
1224 << numExports <<
"." << suffix);
1226 Array<size_t> exportObjs (tempPlan.getTotalReceiveLength () * 2);
1227 tempPlan.doPostsAndWaits<
size_t> (importObjs (), 2, exportObjs ());
1230 for (size_type i = 0; i < numExports; ++i) {
1231 exportGIDs[i] =
static_cast<OrdinalType
> (exportObjs[2*i]);
1232 exportProcIDs[i] =
static_cast<int> (exportObjs[2*i+1]);
1236 template <
class OrdinalType>
1238 createFromRecvs (
const Teuchos::ArrayView<const OrdinalType> &remoteGIDs,
1239 const Teuchos::ArrayView<const int> &remoteProcIDs,
1240 Teuchos::Array<OrdinalType> &exportGIDs,
1241 Teuchos::Array<int> &exportProcIDs)
1244 const char errPrefix[] =
"Tpetra::Distributor::createFromRecvs: ";
1245 const int myRank = plan_.getComm()->getRank();
1247 std::unique_ptr<std::string> prefix;
1249 prefix = createPrefix(
"createFromRecvs");
1250 std::ostringstream os;
1251 os << *prefix <<
"Start" << endl;
1252 std::cerr << os.str();
1257 using Teuchos::outArg;
1258 using Teuchos::REDUCE_MAX;
1259 using Teuchos::reduceAll;
1263 (remoteGIDs.size () != remoteProcIDs.size ()) ? myRank : -1;
1264 int maxErrProc = -1;
1265 reduceAll(*plan_.getComm(), REDUCE_MAX, errProc, outArg(maxErrProc));
1266 TEUCHOS_TEST_FOR_EXCEPTION
1267 (maxErrProc != -1, std::runtime_error, errPrefix <<
"Lists "
1268 "of remote IDs and remote process IDs must have the same "
1269 "size on all participating processes. Maximum process ID "
1270 "with error: " << maxErrProc <<
".");
1275 TEUCHOS_TEST_FOR_EXCEPTION
1276 (remoteGIDs.size() != remoteProcIDs.size(), std::runtime_error,
1277 errPrefix <<
"On Process " << myRank <<
": "
1278 "remoteGIDs.size()=" << remoteGIDs.size() <<
1279 " != remoteProcIDs.size()=" << remoteProcIDs.size() <<
".");
1282 computeSends(remoteGIDs, remoteProcIDs, exportGIDs, exportProcIDs);
1284 plan_.createFromRecvs(remoteProcIDs);
1287 std::ostringstream os;
1288 os << *prefix <<
"Done" << endl;
1289 std::cerr << os.str();
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.
Stand-alone utility functions and macros.
Struct that holds views of the contents of a CrsMatrix.
static bool debug()
Whether Tpetra is in debug mode.
Sets up and executes a communication plan for a Tpetra DistObject.
void doPostsAndWaits(const Teuchos::ArrayView< const Packet > &exports, size_t numPackets, const Teuchos::ArrayView< Packet > &imports)
Execute the (forward) communication plan.
void doReversePostsAndWaits(const Teuchos::ArrayView< const Packet > &exports, size_t numPackets, const Teuchos::ArrayView< Packet > &imports)
Execute the reverse communication plan.
const Details::DistributorPlan & getPlan() const
Get this Distributor's DistributorPlan.
size_t getMaxSendLength() const
Maximum number of values this process will send to another single process.
Teuchos::RCP< Distributor > getReverse(bool create=true) const
A reverse communication plan Distributor.
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.
Teuchos::ArrayView< const int > getProcsTo() const
Ranks of the processes to which this process will send values.
void doReversePosts(const Teuchos::ArrayRCP< const Packet > &exports, size_t numPackets, const Teuchos::ArrayRCP< Packet > &imports)
Post the data for a reverse plan, but do not execute the waits yet.
size_t getNumReceives() const
The number of processes from which we will receive data.
void doPosts(const Teuchos::ArrayRCP< const Packet > &exports, size_t numPackets, const Teuchos::ArrayRCP< Packet > &imports)
Post the data for a forward plan, but do not execute the waits yet.
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &plist)
Set Distributor parameters.
size_t getTotalReceiveLength() const
Total number of values this process will receive from other processes.
virtual ~Distributor()=default
Destructor (virtual for memory safety).
bool hasSelfMessage() const
Whether the calling process will send or receive messages to itself.
void swap(Distributor &rhs)
Swap the contents of rhs with those of *this.
Teuchos::ArrayView< const size_t > getLengthsTo() const
Number of values this process will send to each process.
Teuchos::ArrayView< const int > getProcsFrom() const
Ranks of the processes sending values to this process.
std::string description() const
Return a one-line description of this object.
size_t createFromSends(const Teuchos::ArrayView< const int > &exportProcIDs)
Set up Distributor using list of process ranks to which this process will send.
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...
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
List of valid Distributor parameters.
Teuchos::ArrayView< const size_t > getLengthsFrom() const
Number of values this process will receive from each process.
Details::EDistributorHowInitialized howInitialized() const
Return an enum indicating whether and how a Distributor was initialized.
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.
void getLastDoStatistics(size_t &bytes_sent, size_t &bytes_recvd) const
Information on the last call to do/doReverse.
EDistributorHowInitialized
Enum indicating how and whether a Distributor was initialized.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
Teuchos::Array< std::string > distributorSendTypes()
Valid values for Distributor's "Send type" parameter.