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);
323 mergeCounterNamesPair (
const Comm<int>& comm,
327 const Array<std::string>& localNames,
328 Array<std::string>& globalNames,
335 const bool debug =
false;
340 Array<string> otherNames;
341 receiveStrings (comm, mid, otherNames);
348 std::ostringstream out;
349 out <<
"Proc " << myRank <<
": in mergePair: otherNames = [";
351 it != otherNames.end(); ++it)
353 out <<
"\"" << *it <<
"\"";
354 if (it + 1 != otherNames.end())
364 Array<string> newNames;
365 if ( std::is_sorted(globalNames.begin(), globalNames.end()) &&
366 std::is_sorted(otherNames.begin(), otherNames.end())) {
367 if (setOp == Intersection)
368 std::set_intersection (globalNames.begin(), globalNames.end(),
369 otherNames.begin(), otherNames.end(),
370 std::back_inserter (newNames));
371 else if (setOp == Union)
372 std::set_union (globalNames.begin(), globalNames.end(),
373 otherNames.begin(), otherNames.end(),
374 std::back_inserter (newNames));
378 "Invalid set operation enum value. Please "
379 "report this bug to the Teuchos developers.");
380 globalNames.swap (newNames);
385 else if (myRank == mid)
386 sendStrings (comm, localNames, left);
390 "myRank=" << myRank <<
" is neither left=" << left
391 <<
" nor mid=" << mid <<
". Please report this "
392 "bug to the Teuchos developers.");
405 mergeCounterNamesHelper (
const Comm<int>& comm,
409 const Array<std::string>& localNames,
410 Array<std::string>& globalNames,
439 else if (left == right)
441 Array<string> newNames;
442 newNames.reserve (localNames.size());
443 std::copy (localNames.begin(), localNames.end(),
444 std::back_inserter (newNames));
445 globalNames.swap (newNames);
452 const int mid = left + (right - left + 1) / 2;
453 if (myRank >= left && myRank <= mid-1)
454 mergeCounterNamesHelper (comm, myRank, left, mid-1,
455 localNames, globalNames, setOp);
456 else if (myRank >= mid && myRank <= right)
457 mergeCounterNamesHelper (comm, myRank, mid, right,
458 localNames, globalNames, setOp);
463 if (myRank == left || myRank == mid)
464 mergeCounterNamesPair (comm, myRank, left, mid,
465 localNames, globalNames, setOp);
484 if (setOp == Union) {
485 for (
int i=0; i<localNames.
size();++i) {
488 for (
int j=0;j<globalNames.
size() && !found; ++j)
489 if (localNames[i] == globalNames[j])
494 }
else if (setOp == Intersection) {
495 for (
int i=0; i<globalNames.
size();++i) {
498 for (
int j=0;j<localNames.
size() && !found; ++j)
499 if (localNames[j] == globalNames[i])
509 "Invalid set operation enum value. Please "
510 "report this bug to the Teuchos developers.");
520 const int myRank = comm.
getRank();
522 const int right = comm.
getSize() - 1;
524 mergeCounterNamesHelper (comm, myRank, left, right,
525 localNames, theGlobalNames, setOp);
529 broadcastStrings (comm, theGlobalNames);
533 globalNames.
swap (theGlobalNames);