11#include "Teuchos_CommHelpers.hpp"
12#include "Teuchos_DefaultComm.hpp"
42 packStringsForSend (std::string& packedString,
43 Array<size_t>& offsets,
44 const Array<std::string>& strings)
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;
96 sendStrings (
const Comm<int>& comm,
97 const Array<std::string>& strings,
102 std::string packedString;
103 Array<size_t> offsets;
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);
132 unpackStringsAfterReceive (Array<std::string>& strings,
133 const std::string& packedString,
134 const Array<size_t> offsets)
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);
174 receiveStrings (
const Comm<int>& comm,
175 const int sourceRank,
176 Array<std::string>& strings)
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.");
189 Array<size_t> offsets (numOffsets);
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,
211 Array<std::string>& globalNames)
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);
245 broadcastStrings (
const Comm<int>& comm,
246 Array<std::string>& 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,
292 Array<std::string>& globalNames,
299 const bool debug =
false;
304 Array<string> otherNames;
305 receiveStrings (comm, mid, otherNames);
312 std::ostringstream out;
313 out <<
"Proc " << myRank <<
": in mergePair: otherNames = [";
314 for (Array<std::string>::const_iterator it = otherNames.begin();
315 it != otherNames.end(); ++it)
317 out <<
"\"" << *it <<
"\"";
318 if (it + 1 != otherNames.end())
328 Array<string> newNames;
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,
373 const Array<std::string>& localNames,
374 Array<std::string>& globalNames,
403 else if (left == right)
405 Array<string> newNames;
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) {
458 }
else if (
setOp == Intersection) {
473 "Invalid set operation enum value. Please "
474 "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)