43#include "Teuchos_CommHelpers.hpp"
44#include "Teuchos_DefaultComm.hpp"
74 packStringsForSend (std::string& packedString,
75 Array<size_t>& offsets,
76 const Array<std::string>& strings)
82 const bool debug =
false;
85 offsets.resize (strings.size() + 1);
86 size_t totalLength = 0;
89 it != strings.end(); ++it, ++offsetsIndex)
91 offsets[offsetsIndex] = totalLength;
92 totalLength += it->size();
94 offsets[offsetsIndex] = totalLength;
97 packedString.resize (totalLength);
98 string::iterator packedStringIter = packedString.begin();
100 it != strings.end(); ++it)
101 packedStringIter = std::copy (it->begin(), it->end(), packedStringIter);
105 std::ostringstream out;
107 out <<
"Proc " << pComm->getRank() <<
": in pack: offsets = [";
109 it != offsets.end(); ++it)
112 if (it + 1 != offsets.end())
115 out <<
"], packedString = " << packedString << endl;
128 sendStrings (
const Comm<int>& comm,
129 const Array<std::string>& strings,
134 std::string packedString;
135 Array<size_t> offsets;
136 packStringsForSend (packedString, offsets, strings);
138 "packStringsForSend() returned a zero-length offsets "
139 "array on MPI Proc " << comm.getRank() <<
", to be "
140 "sent to Proc " << destRank <<
". The offsets array "
141 "should always have positive length. Please report "
142 "this bug to the Teuchos developers.");
145 send (comm, offsets.size(), destRank);
150 const int offsetsSendCount =
static_cast<int> (offsets.size());
151 send (comm, offsetsSendCount, &offsets[0], destRank);
158 const int stringSendCount =
static_cast<int> (packedString.size());
159 if (stringSendCount > 0)
160 send (comm, stringSendCount, &packedString[0], destRank);
164 unpackStringsAfterReceive (Array<std::string>& strings,
165 const std::string& packedString,
166 const Array<size_t> offsets)
168 const bool debug =
false;
174 std::ostringstream out;
176 out <<
"Proc " << pComm->getRank() <<
": in unpack: offsets = [";
178 it != offsets.end(); ++it)
181 if (it + 1 != offsets.end())
184 out <<
"], packedString = " << packedString << endl;
188 "The offsets array has length zero, which does not "
189 "make sense. Even when sending / receiving zero "
190 "strings, the offsets array should have one entry "
193 strings.resize (numStrings);
197 const size_t start = offsets[k];
198 const size_t end = offsets[k+1];
199 strings[k] = packedString.substr (start, end - start);
206 receiveStrings (
const Comm<int>& comm,
207 const int sourceRank,
208 Array<std::string>& strings)
213 receive (comm, sourceRank, &numOffsets);
215 "Invalid number of offsets numOffsets=" << numOffsets
216 <<
" received on MPI Rank " << comm.getRank()
217 <<
" from Rank " << sourceRank <<
". Please report "
218 "this bug to the Teuchos developers.");
221 Array<size_t> offsets (numOffsets);
222 const int offsetsRecvCount =
static_cast<int> (numOffsets);
223 receive (comm, sourceRank, offsetsRecvCount, &offsets[0]);
228 std::string packedString (offsets.back(),
' ');
229 const int stringRecvCount =
static_cast<int> (offsets.back());
230 if (stringRecvCount > 0)
232 receive (comm, sourceRank, stringRecvCount, &packedString[0]);
233 unpackStringsAfterReceive (strings, packedString, offsets);
239 broadcastStringsHelper (
const Comm<int>& comm,
243 Array<std::string>& globalNames)
255 const int mid = left + (right - left + 1) / 2;
261 sendStrings (comm, globalNames, mid);
262 else if (myRank == mid)
263 receiveStrings (comm, left, globalNames);
266 if (myRank >= left && myRank <= mid-1)
267 broadcastStringsHelper (comm, myRank, left, mid-1, globalNames);
268 else if (myRank >= mid && myRank <= right)
269 broadcastStringsHelper (comm, myRank, mid, right, globalNames);
277 broadcastStrings (
const Comm<int>& comm,
278 Array<std::string>& globalNames)
280 const int myRank = comm.getRank();
282 const int right = comm.getSize() - 1;
284 broadcastStringsHelper (comm, myRank, left, right, globalNames);
320 mergeCounterNamesPair (
const Comm<int>& comm,
324 Array<std::string>& globalNames,
331 const bool debug =
false;
336 Array<string> otherNames;
337 receiveStrings (comm, mid, otherNames);
344 std::ostringstream out;
345 out <<
"Proc " << myRank <<
": in mergePair: otherNames = [";
346 for (Array<std::string>::const_iterator it = otherNames.begin();
347 it != otherNames.end(); ++it)
349 out <<
"\"" << *it <<
"\"";
350 if (it + 1 != otherNames.end())
360 Array<string> newNames;
361 if ( std::is_sorted(globalNames.begin(), globalNames.end()) &&
362 std::is_sorted(otherNames.begin(), otherNames.end())) {
363 if (setOp == Intersection)
364 std::set_intersection (globalNames.begin(), globalNames.end(),
365 otherNames.begin(), otherNames.end(),
366 std::back_inserter (newNames));
367 else if (setOp == Union)
368 std::set_union (globalNames.begin(), globalNames.end(),
369 otherNames.begin(), otherNames.end(),
370 std::back_inserter (newNames));
374 "Invalid set operation enum value. Please "
375 "report this bug to the Teuchos developers.");
376 globalNames.swap (newNames);
381 else if (myRank == mid)
382 sendStrings (comm, globalNames, left);
386 "myRank=" << myRank <<
" is neither left=" << left
387 <<
" nor mid=" << mid <<
". Please report this "
388 "bug to the Teuchos developers.");
401 mergeCounterNamesHelper (
const Comm<int>& comm,
405 const Array<std::string>& localNames,
406 Array<std::string>& globalNames,
435 else if (left == right)
437 Array<string> newNames;
438 newNames.reserve (localNames.size());
439 std::copy (localNames.begin(), localNames.end(),
440 std::back_inserter (newNames));
441 globalNames.swap (newNames);
448 const int mid = left + (right - left + 1) / 2;
449 if (myRank >= left && myRank <= mid-1)
450 mergeCounterNamesHelper (comm, myRank, left, mid-1,
451 localNames, globalNames, setOp);
452 else if (myRank >= mid && myRank <= right)
453 mergeCounterNamesHelper (comm, myRank, mid, right,
454 localNames, globalNames, setOp);
459 if (myRank == left || myRank == mid)
460 mergeCounterNamesPair (comm, myRank, left, mid,
480 if (
setOp == Union) {
490 }
else if (
setOp == Intersection) {
505 "Invalid set operation enum value. Please "
506 "report this bug to the Teuchos developers.");
Ordinal size_type
The type of Array sizes and capacities.
std::vector< T >::const_iterator const_iterator
The type of a const forward iterator.
static Teuchos::RCP< const Comm< OrdinalType > > getComm()
Return the default global communicator.
Smart reference counting pointer class for automatic garbage collection.
void swap(RCP< T > &r_ptr)
Swap the contents with some other RCP object.
#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)