39 #include "Tpetra_Distributor.hpp"
43 #include "Tpetra_Details_makeValidVerboseStream.hpp"
44 #include "Teuchos_StandardParameterEntryValidators.hpp"
45 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
55 const bool tpetraDistributorDebugDefault =
false;
58 Teuchos::Array<std::string>
61 Teuchos::Array<std::string> sendTypes;
62 sendTypes.push_back (
"Isend");
63 sendTypes.push_back (
"Rsend");
64 sendTypes.push_back (
"Send");
65 sendTypes.push_back (
"Ssend");
70 Distributor (
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
71 const Teuchos::RCP<Teuchos::FancyOStream>& ,
72 const Teuchos::RCP<Teuchos::ParameterList>& plist)
74 , lastRoundBytesSend_ (0)
75 , lastRoundBytesRecv_ (0)
81 Distributor (
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
86 Distributor (
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
87 const Teuchos::RCP<Teuchos::FancyOStream>& out)
92 Distributor (
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
93 const Teuchos::RCP<Teuchos::ParameterList>& plist)
99 : plan_(distributor.plan_)
100 , actor_(distributor.actor_)
101 , verbose_ (distributor.verbose_)
102 , reverseDistributor_ (distributor.reverseDistributor_)
103 , lastRoundBytesSend_ (distributor.lastRoundBytesSend_)
104 , lastRoundBytesRecv_ (distributor.lastRoundBytesRecv_)
106 using Teuchos::ParameterList;
110 RCP<const ParameterList> rhsList = distributor.getParameterList ();
111 RCP<ParameterList> newList = rhsList.is_null () ? Teuchos::null :
112 Teuchos::parameterList (*rhsList);
117 using Teuchos::ParameterList;
118 using Teuchos::parameterList;
121 std::swap (plan_, rhs.plan_);
122 std::swap (actor_, rhs.actor_);
123 std::swap (verbose_, rhs.verbose_);
124 std::swap (reverseDistributor_, rhs.reverseDistributor_);
125 std::swap (lastRoundBytesSend_, rhs.lastRoundBytesSend_);
126 std::swap (lastRoundBytesRecv_, rhs.lastRoundBytesRecv_);
130 RCP<ParameterList> lhsList = this->getNonconstParameterList ();
131 RCP<ParameterList> rhsList = rhs.getNonconstParameterList ();
132 if (lhsList.getRawPtr () == rhsList.getRawPtr () && ! rhsList.is_null ()) {
133 rhsList = parameterList (*rhsList);
135 if (! rhsList.is_null ()) {
136 this->setMyParamList (rhsList);
138 if (! lhsList.is_null ()) {
139 rhs.setMyParamList (lhsList);
147 Distributor::getVerbose()
153 std::unique_ptr<std::string>
155 createPrefix(
const char methodName[])
const
158 plan_.getComm().getRawPtr(),
"Distributor", methodName);
165 using ::Tpetra::Details::Behavior;
166 using Teuchos::FancyOStream;
167 using Teuchos::getIntegralValue;
168 using Teuchos::includesVerbLevel;
169 using Teuchos::ParameterList;
170 using Teuchos::parameterList;
174 if (! plist.is_null()) {
176 plist->validateParametersAndSetDefaults (*validParams);
180 this->setMyParamList (plist);
182 RCP<ParameterList> planParams(plist);
183 planParams->remove(
"Debug",
false);
184 planParams->remove(
"VerboseObject",
false);
185 plan_.setParameterList(planParams);
189 Teuchos::RCP<const Teuchos::ParameterList>
192 using Teuchos::Array;
193 using Teuchos::ParameterList;
194 using Teuchos::parameterList;
196 using Teuchos::setStringToIntegralParameter;
198 const bool barrierBetween = Details::barrierBetween_default;
199 const bool useDistinctTags = Details::useDistinctTags_default;
200 const bool debug = tpetraDistributorDebugDefault;
203 const std::string defaultSendType (
"Send");
204 Array<Details::EDistributorSendType> sendTypeEnums;
205 sendTypeEnums.push_back (Details::DISTRIBUTOR_ISEND);
206 sendTypeEnums.push_back (Details::DISTRIBUTOR_RSEND);
207 sendTypeEnums.push_back (Details::DISTRIBUTOR_SEND);
208 sendTypeEnums.push_back (Details::DISTRIBUTOR_SSEND);
210 RCP<ParameterList> plist = parameterList (
"Tpetra::Distributor");
211 plist->set (
"Barrier between receives and sends", barrierBetween,
212 "Whether to execute a barrier between receives and sends in do"
213 "[Reverse]Posts(). Required for correctness when \"Send type\""
214 "=\"Rsend\", otherwise correct but not recommended.");
215 setStringToIntegralParameter<Details::EDistributorSendType> (
"Send type",
216 defaultSendType,
"When using MPI, the variant of send to use in "
217 "do[Reverse]Posts()", sendTypes(), sendTypeEnums(), plist.getRawPtr());
218 plist->set (
"Use distinct tags", useDistinctTags,
"Whether to use distinct "
219 "MPI message tags for different code paths. Highly recommended"
220 " to avoid message collisions.");
221 plist->set (
"Debug", debug,
"Whether to print copious debugging output on "
223 plist->set (
"Timer Label",
"",
"Label for Time Monitor output");
224 plist->set (
"Enable MPI CUDA RDMA support",
true,
"Assume that MPI can "
225 "tell whether a pointer points to host memory or CUDA device "
226 "memory. You don't need to specify this option any more; "
227 "Tpetra assumes it is always true. This is a very light "
228 "assumption on the MPI implementation, and in fact does not "
229 "actually involve hardware or system RDMA support.");
237 Teuchos::setupVerboseObjectSublist (&*plist);
238 return Teuchos::rcp_const_cast<const ParameterList> (plist);
243 {
return plan_.getTotalReceiveLength(); }
246 {
return plan_.getNumReceives(); }
249 {
return plan_.hasSelfMessage(); }
252 {
return plan_.getNumSends(); }
255 {
return plan_.getMaxSendLength(); }
258 {
return plan_.getProcsFrom(); }
261 {
return plan_.getLengthsFrom(); }
264 {
return plan_.getProcsTo(); }
267 {
return plan_.getLengthsTo(); }
269 Teuchos::RCP<Distributor>
271 if (reverseDistributor_.is_null () && create) {
272 createReverseDistributor ();
274 TEUCHOS_TEST_FOR_EXCEPTION
275 (reverseDistributor_.is_null () && create, std::logic_error,
"The reverse "
276 "Distributor is null after createReverseDistributor returned. "
277 "Please report this bug to the Tpetra developers.");
278 return reverseDistributor_;
283 Distributor::createReverseDistributor()
const
285 reverseDistributor_ = Teuchos::rcp(
new Distributor(plan_.getComm()));
286 reverseDistributor_->plan_ = *plan_.getReversePlan();
287 reverseDistributor_->verbose_ = verbose_;
296 reverseDistributor_->lastRoundBytesSend_ = 0;
297 reverseDistributor_->lastRoundBytesRecv_ = 0;
310 reverseDistributor_->reverseDistributor_ = Teuchos::null;
316 actor_.doWaits(plan_);
321 if (! reverseDistributor_.is_null()) {
322 reverseDistributor_->doWaits();
327 std::ostringstream out;
329 out <<
"\"Tpetra::Distributor\": {";
330 const std::string label = this->getObjectLabel ();
332 out <<
"Label: " << label <<
", ";
334 out <<
"How initialized: "
338 << DistributorSendTypeEnumToString (plan_.getSendType())
339 <<
", Barrier between receives and sends: "
340 << (plan_.barrierBetweenRecvSend() ?
"true" :
"false")
341 <<
", Use distinct tags: "
342 << (plan_.useDistinctTags() ?
"true" :
"false")
343 <<
", Debug: " << (verbose_ ?
"true" :
"false")
350 localDescribeToString (
const Teuchos::EVerbosityLevel vl)
const
352 using Teuchos::toString;
353 using Teuchos::VERB_HIGH;
354 using Teuchos::VERB_EXTREME;
358 if (vl <= Teuchos::VERB_LOW || plan_.getComm().is_null ()) {
359 return std::string ();
362 auto outStringP = Teuchos::rcp (
new std::ostringstream ());
363 auto outp = Teuchos::getFancyOStream (outStringP);
364 Teuchos::FancyOStream& out = *outp;
366 const int myRank = plan_.getComm()->getRank ();
367 const int numProcs = plan_.getComm()->getSize ();
368 out <<
"Process " << myRank <<
" of " << numProcs <<
":" << endl;
369 Teuchos::OSTab tab1 (out);
373 if (vl == VERB_HIGH || vl == VERB_EXTREME) {
374 out <<
"procsTo: " << toString (plan_.getProcsTo()) << endl;
375 out <<
"lengthsTo: " << toString (plan_.getLengthsTo()) << endl;
378 if (vl == VERB_EXTREME) {
379 out <<
"startsTo: " << toString (plan_.getStartsTo()) << endl;
380 out <<
"indicesTo: " << toString (plan_.getIndicesTo()) << endl;
382 if (vl == VERB_HIGH || vl == VERB_EXTREME) {
385 out <<
"lengthsFrom: " << toString (plan_.getLengthsFrom()) << endl;
386 out <<
"procsFrom: " << toString (plan_.getProcsFrom()) << endl;
390 return outStringP->str ();
395 describe (Teuchos::FancyOStream& out,
396 const Teuchos::EVerbosityLevel verbLevel)
const
399 using Teuchos::VERB_DEFAULT;
400 using Teuchos::VERB_NONE;
401 using Teuchos::VERB_LOW;
402 using Teuchos::VERB_MEDIUM;
403 using Teuchos::VERB_HIGH;
404 using Teuchos::VERB_EXTREME;
405 const Teuchos::EVerbosityLevel vl =
406 (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
408 if (vl == VERB_NONE) {
416 if (plan_.getComm().is_null ()) {
419 const int myRank = plan_.getComm()->getRank ();
420 const int numProcs = plan_.getComm()->getSize ();
429 Teuchos::RCP<Teuchos::OSTab> tab0, tab1;
435 tab0 = Teuchos::rcp (
new Teuchos::OSTab (out));
438 out <<
"\"Tpetra::Distributor\":" << endl;
439 tab1 = Teuchos::rcp (
new Teuchos::OSTab (out));
441 const std::string label = this->getObjectLabel ();
443 out <<
"Label: " << label << endl;
445 out <<
"Number of processes: " << numProcs << endl
446 <<
"How initialized: "
450 out <<
"Parameters: " << endl;
451 Teuchos::OSTab tab2 (out);
452 out <<
"\"Send type\": "
453 << DistributorSendTypeEnumToString (plan_.getSendType()) << endl
454 <<
"\"Barrier between receives and sends\": "
455 << (plan_.barrierBetweenRecvSend() ?
"true" :
"false") << endl
456 <<
"\"Use distinct tags\": "
457 << (plan_.useDistinctTags() ?
"true" :
"false") << endl
458 <<
"\"Debug\": " << (verbose_ ?
"true" :
"false") << endl;
464 const std::string lclStr = this->localDescribeToString (vl);
468 out <<
"Reverse Distributor:";
469 if (reverseDistributor_.is_null ()) {
470 out <<
" null" << endl;
474 reverseDistributor_->describe (out, vl);
482 return plan_.createFromSends(exportProcIDs);
488 const Teuchos::ArrayView<const int>& remoteProcIDs)
490 plan_.createFromSendsAndRecvs(exportProcIDs, remoteProcIDs);
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.
Declaration of a function that prints strings from each process.
Stand-alone utility functions and macros.
static bool verbose()
Whether Tpetra is in verbose mode.
Sets up and executes a communication plan for a Tpetra DistObject.
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.
Teuchos::ArrayView< const int > getProcsTo() const
Ranks of the processes to which this process will send values.
size_t getNumReceives() const
The number of processes from which we will receive data.
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.
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.
Distributor(const Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Construct using the specified communicator and default parameters.
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.
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.
std::unique_ptr< std::string > createPrefix(const int myRank, const char prefix[])
Create string prefix for each line of verbose output.
std::string DistributorHowInitializedEnumToString(EDistributorHowInitialized how)
Convert an EDistributorHowInitialized enum value to a string.
void gathervPrint(std::ostream &out, const std::string &s, const Teuchos::Comm< int > &comm)
On Process 0 in the given communicator, print strings from each process in that communicator,...
Namespace Tpetra contains the class and methods constituting the Tpetra library.
Teuchos::Array< std::string > distributorSendTypes()
Valid values for Distributor's "Send type" parameter.