11#include "Teuchos_CommHelpers.hpp"
12#include "Teuchos_DefaultComm.hpp"
42 packStringsForSend (std::string& packedString,
50 const bool debug =
false;
53 offsets.resize (strings.size() + 1);
54 size_t totalLength = 0;
57 it != strings.end(); ++it, ++offsetsIndex)
59 offsets[offsetsIndex] = totalLength;
60 totalLength += it->size();
62 offsets[offsetsIndex] = totalLength;
65 packedString.resize (totalLength);
66 string::iterator packedStringIter = packedString.begin();
68 it != strings.end(); ++it)
69 packedStringIter = std::copy (it->begin(), it->end(), packedStringIter);
73 std::ostringstream out;
75 out <<
"Proc " << pComm->getRank() <<
": in pack: offsets = [";
77 it != offsets.end(); ++it)
80 if (it + 1 != offsets.end())
83 out <<
"], packedString = " << packedString << endl;
102 std::string packedString;
104 packStringsForSend (packedString, offsets, strings);
106 "packStringsForSend() returned a zero-length offsets "
107 "array on MPI Proc " << comm.getRank() <<
", to be "
108 "sent to Proc " << destRank <<
". The offsets array "
109 "should always have positive length. Please report "
110 "this bug to the Teuchos developers.");
113 send (comm, offsets.size(), destRank);
118 const int offsetsSendCount =
static_cast<int> (offsets.size());
119 send (comm, offsetsSendCount, &offsets[0], destRank);
126 const int stringSendCount =
static_cast<int> (packedString.size());
127 if (stringSendCount > 0)
128 send (comm, stringSendCount, &packedString[0], destRank);
133 const std::string& packedString,
136 const bool debug =
false;
142 std::ostringstream out;
144 out <<
"Proc " << pComm->getRank() <<
": in unpack: offsets = [";
146 it != offsets.end(); ++it)
149 if (it + 1 != offsets.end())
152 out <<
"], packedString = " << packedString << endl;
156 "The offsets array has length zero, which does not "
157 "make sense. Even when sending / receiving zero "
158 "strings, the offsets array should have one entry "
161 strings.resize (numStrings);
165 const size_t start = offsets[k];
166 const size_t end = offsets[k+1];
167 strings[k] = packedString.substr (start, end - start);
175 const int sourceRank,
181 receive (comm, sourceRank, &numOffsets);
183 "Invalid number of offsets numOffsets=" << numOffsets
184 <<
" received on MPI Rank " << comm.getRank()
185 <<
" from Rank " << sourceRank <<
". Please report "
186 "this bug to the Teuchos developers.");
190 const int offsetsRecvCount =
static_cast<int> (numOffsets);
191 receive (comm, sourceRank, offsetsRecvCount, &offsets[0]);
196 std::string packedString (offsets.back(),
' ');
197 const int stringRecvCount =
static_cast<int> (offsets.back());
198 if (stringRecvCount > 0)
200 receive (comm, sourceRank, stringRecvCount, &packedString[0]);
201 unpackStringsAfterReceive (strings, packedString, offsets);
207 broadcastStringsHelper (
const Comm<int>& comm,
223 const int mid = left + (right - left + 1) / 2;
229 sendStrings (comm, globalNames, mid);
230 else if (myRank == mid)
231 receiveStrings (comm, left, globalNames);
234 if (myRank >= left && myRank <= mid-1)
235 broadcastStringsHelper (comm, myRank, left, mid-1, globalNames);
236 else if (myRank >= mid && myRank <= right)
237 broadcastStringsHelper (comm, myRank, mid, right, globalNames);
248 const int myRank = comm.getRank();
250 const int right = comm.getSize() - 1;
252 broadcastStringsHelper (comm, myRank, left, right, globalNames);
288 mergeCounterNamesPair (
const Comm<int>& comm,
299 const bool debug =
false;
305 receiveStrings (comm, mid, otherNames);
312 std::ostringstream out;
313 out <<
"Proc " << myRank <<
": in mergePair: otherNames = [";
315 it != otherNames.end(); ++it)
317 out <<
"\"" << *it <<
"\"";
318 if (it + 1 != otherNames.end())
329 if ( std::is_sorted(globalNames.begin(), globalNames.end()) &&
330 std::is_sorted(otherNames.begin(), otherNames.end())) {
331 if (setOp == Intersection)
332 std::set_intersection (globalNames.begin(), globalNames.end(),
333 otherNames.begin(), otherNames.end(),
334 std::back_inserter (newNames));
335 else if (setOp == Union)
336 std::set_union (globalNames.begin(), globalNames.end(),
337 otherNames.begin(), otherNames.end(),
338 std::back_inserter (newNames));
342 "Invalid set operation enum value. Please "
343 "report this bug to the Teuchos developers.");
344 globalNames.swap (newNames);
349 else if (myRank == mid)
350 sendStrings (comm, globalNames, left);
354 "myRank=" << myRank <<
" is neither left=" << left
355 <<
" nor mid=" << mid <<
". Please report this "
356 "bug to the Teuchos developers.");
369 mergeCounterNamesHelper (
const Comm<int>& comm,
403 else if (left == right)
406 newNames.
reserve (localNames.size());
407 std::copy (localNames.begin(), localNames.end(),
408 std::back_inserter (newNames));
409 globalNames.swap (newNames);
416 const int mid = left + (right - left + 1) / 2;
417 if (myRank >= left && myRank <= mid-1)
418 mergeCounterNamesHelper (comm, myRank, left, mid-1,
419 localNames, globalNames, setOp);
420 else if (myRank >= mid && myRank <= right)
421 mergeCounterNamesHelper (comm, myRank, mid, right,
422 localNames, globalNames, setOp);
427 if (myRank == left || myRank == mid)
428 mergeCounterNamesPair (comm, myRank, left, mid,
448 if (setOp == Union) {
449 for (
int i=0; i<localNames.
size();++i) {
452 for (
int j=0;j<globalNames.
size() && !found; ++j)
453 if (localNames[i] == globalNames[j])
458 }
else if (setOp == Intersection) {
459 for (
int i=0; i<globalNames.
size();++i) {
462 for (
int j=0;j<localNames.
size() && !found; ++j)
463 if (localNames[j] == globalNames[i])
473 "Invalid set operation enum value. Please "
474 "report this bug to the Teuchos developers.");
484 const int myRank = comm.
getRank();
486 const int right = comm.
getSize() - 1;
488 mergeCounterNamesHelper (comm, myRank, left, right,
489 localNames, theGlobalNames, setOp);
493 broadcastStrings (comm, theGlobalNames);
497 globalNames.
swap (theGlobalNames);
Replacement for std::vector that is compatible with the Teuchos Memory Management classes.
void reserve(size_type n)
friend void swap(Array< T2 > &a1, Array< T2 > &a2)
Ordinal size_type
The type of Array sizes and capacities.
void remove(int i)
Remove the i-th element from the array, with optional boundschecking.
void push_back(const value_type &x)
std::vector< T >::const_iterator const_iterator
The type of a const forward iterator.
Abstract interface for distributed-memory communication.
int receive(const Comm< Ordinal > &comm, const int sourceRank, const Ordinal count, Packet recvBuffer[])
Receive objects that use values semantics from another process.
virtual int getSize() const =0
Returns the number of processes that make up this communicator.
virtual int getRank() const =0
Returns the rank of this process.
static Teuchos::RCP< const Comm< OrdinalType > > getComm()
Return the default global communicator.
Smart reference counting pointer class for automatic garbage collection.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...
ECounterSetOp
Set operation type for mergeCounterNames() to perform.
void mergeCounterNames(const Comm< int > &comm, const Array< std::string > &localNames, Array< std::string > &globalNames, const ECounterSetOp setOp)
Merge counter names over all processors.
void send(const Packet sendBuffer[], const Ordinal count, const int destRank, const int tag, const Comm< Ordinal > &comm)
Variant of send() that takes a tag (and restores the correct order of arguments).
void unsortedMergePair(const Array< std::string > &localNames, Array< std::string > &globalNames, const ECounterSetOp setOp)