Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_CommHelpers.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Teuchos: Common Tools Package
4 //
5 // Copyright 2004 NTESS and the Teuchos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #include "Teuchos_CommHelpers.hpp"
11 #ifdef HAVE_TEUCHOS_MPI
14 #endif // HAVE_TEUCHOS_MPI
15 #ifdef HAVE_TEUCHOSCORE_CXX11
16 # include <memory>
17 #endif
18 
19 namespace Teuchos {
20 
21 #ifdef HAVE_TEUCHOS_MPI
22 namespace Details {
23 
24 std::string getMpiErrorString (const int errCode) {
25  // Space for storing the error string returned by MPI.
26  // Leave room for null termination, since I don't know if MPI does this.
27  char errString [MPI_MAX_ERROR_STRING+1];
28  int errStringLen = MPI_MAX_ERROR_STRING; // output argument
29  (void) MPI_Error_string (errCode, errString, &errStringLen);
30  // errStringLen on output is the number of characters written.
31  // I'm not sure (the MPI 3.0 Standard doesn't say) if this
32  // includes the '\0', so I'll make sure. We reserved space for
33  // the extra '\0' if needed.
34  if (errString[errStringLen-1] != '\0') {
35  errString[errStringLen] = '\0';
36  }
37  return std::string (errString); // This copies the original string.
38 }
39 
40 } // namespace Details
41 #endif // HAVE_TEUCHOS_MPI
42 
43 namespace { // (anonymous)
44 
52 template<class T>
53 void
54 reduceAllImpl (const Comm<int>& comm,
55  const EReductionType reductType,
56  const int count,
57  const T sendBuffer[],
58  T globalReducts[])
59 {
60 #ifdef HAVE_TEUCHOS_MPI
61  using Teuchos::Details::MpiTypeTraits;
62 
63  // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
64  // SerialComm or an MpiComm. If it's something else, we fall back
65  // to the most general implementation.
66  const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
67  if (mpiComm == NULL) {
68  // Is it a SerialComm?
69  const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
70  if (serialComm == NULL) {
71  // We don't know what kind of Comm we have, so fall back to the
72  // most general implementation.
73 #ifdef HAVE_TEUCHOSCORE_CXX11
74  std::unique_ptr<ValueTypeReductionOp<int, T> >
75 #else
76  std::auto_ptr<ValueTypeReductionOp<int, T> >
77 #endif
78  reductOp (createOp<int, T> (reductType));
79  reduceAll (comm, *reductOp, count, sendBuffer, globalReducts);
80  }
81  else { // It's a SerialComm; there is only 1 process, so just copy.
82  std::copy (sendBuffer, sendBuffer + count, globalReducts);
83  }
84  } else { // It's an MpiComm. Invoke MPI directly.
85  MPI_Op rawMpiOp = ::Teuchos::Details::getMpiOpForEReductionType (reductType);
86  MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
87  T t;
88  MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
89 
90  int err = MPI_SUCCESS;
91  if (sendBuffer == globalReducts) {
92  // NOTE (mfh 31 May 2017) This is only safe if the communicator
93  // is NOT an intercomm. The usual case is that communicators
94  // are intracomms.
95  err = MPI_Allreduce (MPI_IN_PLACE, globalReducts,
96  count, rawMpiType, rawMpiOp, rawMpiComm);
97  }
98  else {
99  err = MPI_Allreduce (const_cast<T*> (sendBuffer), globalReducts,
100  count, rawMpiType, rawMpiOp, rawMpiComm);
101  }
103  err != MPI_SUCCESS,
104  std::runtime_error,
105  "MPI_Allreduce failed with the following error: "
106  << ::Teuchos::Details::getMpiErrorString (err));
107  }
108 #else
109  // We've built without MPI, so just assume it's a SerialComm and copy the data.
110  std::copy (sendBuffer, sendBuffer + count, globalReducts);
111 #endif // HAVE_TEUCHOS_MPI
112 }
113 
114 
122 template<class T>
123 void
124 gatherImpl (const T sendBuf[],
125  const int sendCount,
126  T recvBuf[],
127  const int recvCount,
128  const int root,
129  const Comm<int>& comm)
130 {
131 #ifdef HAVE_TEUCHOS_MPI
132  using Teuchos::Details::MpiTypeTraits;
133 
134  // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
135  // SerialComm or an MpiComm. If it's something else, we fall back
136  // to the most general implementation.
137  const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
138  if (mpiComm == NULL) {
139  // Is it a SerialComm?
140  const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
141  if (serialComm == NULL) {
142  // We don't know what kind of Comm we have, so fall back to the
143  // most general implementation.
144  gather<int, T> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
145  }
146  else { // It's a SerialComm; there is only 1 process, so just copy.
147  std::copy (sendBuf, sendBuf + sendCount, recvBuf);
148  }
149  } else { // It's an MpiComm. Invoke MPI directly.
150  MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
151  T t;
152  MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
153  const int err = MPI_Gather (const_cast<T*> (sendBuf), sendCount, rawMpiType,
154  recvBuf, recvCount, rawMpiType,
155  root, rawMpiComm);
157  err != MPI_SUCCESS,
158  std::runtime_error,
159  "MPI_Gather failed with the following error: "
160  << ::Teuchos::Details::getMpiErrorString (err));
161  }
162 #else
163  // We've built without MPI, so just assume it's a SerialComm and copy the data.
164  std::copy (sendBuf, sendBuf + sendCount, recvBuf);
165 #endif // HAVE_TEUCHOS_MPI
166 }
167 
168 
176 template<class T>
177 void
178 scatterImpl (const T sendBuf[],
179  const int sendCount,
180  T recvBuf[],
181  const int recvCount,
182  const int root,
183  const Comm<int>& comm)
184 {
185 #ifdef HAVE_TEUCHOS_MPI
186  using Teuchos::Details::MpiTypeTraits;
187 
188  // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
189  // SerialComm or an MpiComm. If it's something else, we fall back
190  // to the most general implementation.
191  const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
192  if (mpiComm == NULL) {
193  // Is it a SerialComm?
194  const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
195  if (serialComm == NULL) {
196  // We don't know what kind of Comm we have, so fall back to the
197  // most general implementation.
198  scatter<int, T> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
199  }
200  else { // It's a SerialComm; there is only 1 process, so just copy.
201  std::copy (sendBuf, sendBuf + sendCount, recvBuf);
202  }
203  } else { // It's an MpiComm. Invoke MPI directly.
204  MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
205  T t;
206  MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
207  const int err =
208  MPI_Scatter (const_cast<T*> (sendBuf), sendCount, rawMpiType,
209  recvBuf, recvCount, rawMpiType,
210  root, rawMpiComm);
212  (err != MPI_SUCCESS, std::runtime_error,
213  "MPI_Scatter failed with the following error: "
214  << ::Teuchos::Details::getMpiErrorString (err));
215  }
216 #else
217  // We've built without MPI, so just assume it's a SerialComm and
218  // copy the data.
219  std::copy (sendBuf, sendBuf + sendCount, recvBuf);
220 #endif // HAVE_TEUCHOS_MPI
221 }
222 
223 template<class T>
224 void
225 scattervImpl (const T sendBuf[],
226  const int sendCounts[],
227  const int displs[],
228  T recvBuf[],
229  const int recvCount,
230  const int root,
231  const Comm<int>& comm)
232 {
233 #ifdef HAVE_TEUCHOS_MPI
234  using Teuchos::Details::MpiTypeTraits;
235 
236  // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
237  // SerialComm or an MpiComm. If it's something else, we fall back
238  // to the most general implementation.
239  const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
240  if (mpiComm == NULL) {
241  // Is it a SerialComm?
242  const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
243  if (serialComm == NULL) {
244  // We don't know what kind of Comm we have, so fall back to the
245  // most general implementation.
246  scatterv<int, T> (sendBuf, sendCounts, displs, recvBuf, recvCount, root, comm);
247  }
248  else { // It's a SerialComm; there is only 1 process, so just copy.
249  std::copy (sendBuf, sendBuf + sendCounts[0], recvBuf);
250  }
251  } else { // It's an MpiComm. Invoke MPI directly.
252  MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
253  T t;
254  MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
255  const int err =
256  MPI_Scatterv (const_cast<T*> (sendBuf), sendCounts, displs, rawMpiType,
257  recvBuf, recvCount, rawMpiType,
258  root, rawMpiComm);
260  (err != MPI_SUCCESS, std::runtime_error,
261  "MPI_Scatter failed with the following error: "
262  << ::Teuchos::Details::getMpiErrorString (err));
263  }
264 #else
265  // We've built without MPI, so just assume it's a SerialComm and
266  // copy the data.
267  std::copy (sendBuf, sendBuf + sendCounts[0], recvBuf);
268 #endif // HAVE_TEUCHOS_MPI
269 }
270 
271 
279 template<class T>
280 void
281 reduceImpl (const T sendBuf[],
282  T recvBuf[],
283  const int count,
284  const EReductionType reductType,
285  const int root,
286  const Comm<int>& comm)
287 {
288 #ifdef HAVE_TEUCHOS_MPI
289  using Teuchos::Details::MpiTypeTraits;
290 
291  // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
292  // SerialComm or an MpiComm. If it's something else, we fall back
293  // to the most general implementation.
294  const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
295  if (mpiComm == NULL) {
296  // Is it a SerialComm?
297  const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
298  if (serialComm == NULL) {
299  // We don't know what kind of Comm we have, so fall back to the
300  // most general implementation.
301  reduce<int, T> (sendBuf, recvBuf, count, reductType, root, comm);
302  }
303  else { // It's a SerialComm; there is only 1 process, so just copy.
304  std::copy (sendBuf, sendBuf + count, recvBuf);
305  }
306  } else { // It's an MpiComm. Invoke MPI directly.
307  MPI_Op rawMpiOp = ::Teuchos::Details::getMpiOpForEReductionType (reductType);
308  MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
309  T t;
310  MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
311  const int err = MPI_Reduce (const_cast<T*> (sendBuf), recvBuf, count,
312  rawMpiType, rawMpiOp, root, rawMpiComm);
314  (err != MPI_SUCCESS, std::runtime_error, "MPI_Reduce failed with the "
315  "following error: " << ::Teuchos::Details::getMpiErrorString (err));
316  }
317 #else
318  // We've built without MPI, so just assume it's a SerialComm and copy the data.
319  std::copy (sendBuf, sendBuf + count, recvBuf);
320 #endif // HAVE_TEUCHOS_MPI
321 }
322 
323 
331 template<class T>
332 void
333 gathervImpl (const T sendBuf[],
334  const int sendCount,
335  T recvBuf[],
336  const int recvCounts[],
337  const int displs[],
338  const int root,
339  const Comm<int>& comm)
340 {
341 #ifdef HAVE_TEUCHOS_MPI
342  using Teuchos::Details::MpiTypeTraits;
343 
344  // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
345  // SerialComm or an MpiComm. If it's something else, we fall back
346  // to the most general implementation.
347  const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
348  if (mpiComm == NULL) {
349  // Is it a SerialComm?
350  const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
351  if (serialComm == NULL) {
352  // We don't know what kind of Comm we have, so fall back to the
353  // most general implementation.
354  gatherv<int, T> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
355  }
356  else { // It's a SerialComm; there is only 1 process, so just copy.
358  recvCounts[0] > sendCount, std::invalid_argument,
359  "Teuchos::gatherv: If the input communicator contains only one "
360  "process, then you cannot receive more entries than you send. "
361  "You aim to receive " << recvCounts[0] << " entries, but to send "
362  << sendCount << " entries.");
363  // Serial communicator case: just copy. recvCounts[0] is the
364  // amount to receive, so it's the amount to copy. Start writing
365  // to recvbuf at the offset displs[0].
366  std::copy (sendBuf, sendBuf + recvCounts[0], recvBuf + displs[0]);
367  }
368  } else { // It's an MpiComm. Invoke MPI directly.
369  MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
370  T t;
371  MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
372  const int err = MPI_Gatherv (const_cast<T*> (sendBuf),
373  sendCount,
374  rawMpiType,
375  recvBuf,
376  const_cast<int*> (recvCounts),
377  const_cast<int*> (displs),
378  rawMpiType,
379  root,
380  rawMpiComm);
382  err != MPI_SUCCESS,
383  std::runtime_error,
384  "MPI_Gatherv failed with the following error: "
385  << ::Teuchos::Details::getMpiErrorString (err));
386  }
387 #else
388  // We've built without MPI, so just assume it's a SerialComm and copy the data.
390  recvCounts[0] > sendCount, std::invalid_argument,
391  "Teuchos::gatherv: If the input communicator contains only one "
392  "process, then you cannot receive more entries than you send. "
393  "You aim to receive " << recvCounts[0] << " entries, but to send "
394  << sendCount << " entries.");
395  // Serial communicator case: just copy. recvCounts[0] is the
396  // amount to receive, so it's the amount to copy. Start writing
397  // to recvbuf at the offset displs[0].
398  std::copy (sendBuf, sendBuf + recvCounts[0], recvBuf + displs[0]);
399 #endif // HAVE_TEUCHOS_MPI
400 }
401 
407 template<typename Packet>
408 RCP<Teuchos::CommRequest<int> >
409 ireceiveGeneral(const Comm<int>& comm,
410  const ArrayRCP<Packet> &recvBuffer,
411  const int sourceRank)
412 {
414  "Teuchos::ireceive<int, " << "," << TypeNameTraits<Packet>::name ()
415  << "> ( value type )"
416  );
417  ValueTypeSerializationBuffer<int, Packet>
418  charRecvBuffer (recvBuffer.size (), recvBuffer.getRawPtr ());
419  RCP<CommRequest<int> > commRequest =
420  comm.ireceive (charRecvBuffer.getCharBufferView (), sourceRank);
421  set_extra_data (recvBuffer, "buffer", inOutArg (commRequest));
422  return commRequest;
423 }
424 
427 template<typename Packet>
428 RCP<Teuchos::CommRequest<int> >
429 ireceiveGeneral (const ArrayRCP<Packet> &recvBuffer,
430  const int sourceRank,
431  const int tag,
432  const Comm<int>& comm)
433 {
435  "Teuchos::ireceive<int, " << "," << TypeNameTraits<Packet>::name ()
436  << "> ( value type )"
437  );
438  ValueTypeSerializationBuffer<int, Packet>
439  charRecvBuffer (recvBuffer.size (), recvBuffer.getRawPtr ());
440  RCP<CommRequest<int> > commRequest =
441  comm.ireceive (charRecvBuffer.getCharBufferView (), sourceRank, tag);
442  set_extra_data (recvBuffer, "buffer", inOutArg (commRequest));
443  return commRequest;
444 }
445 
458 template<class T>
459 RCP<CommRequest<int> >
460 ireceiveImpl (const Comm<int>& comm,
461  const ArrayRCP<T>& recvBuffer,
462  const int sourceRank)
463 {
464 #ifdef HAVE_TEUCHOS_MPI
465  using Teuchos::Details::MpiTypeTraits;
466 
467  // Even in an MPI build, Comm might be either a SerialComm or an
468  // MpiComm. If it's something else, we fall back to the most
469  // general implementation.
470  const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
471  if (mpiComm == NULL) {
472  // Is it a SerialComm?
473  const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
474  if (serialComm == NULL) {
475  // We don't know what kind of Comm we have, so fall back to the
476  // most general implementation.
477  return ireceiveGeneral<T> (comm, recvBuffer, sourceRank);
478  }
479  else { // SerialComm doesn't implement ireceive anyway.
481  true,
482  std::logic_error,
483  "ireceiveImpl: Not implemented for a serial communicator.");
484  }
485  }
486  else { // It's an MpiComm. Invoke MPI directly.
487  MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
488  T t;
489  MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
490  T* rawRecvBuf = recvBuffer.getRawPtr ();
491  const int count = as<int> (recvBuffer.size ());
492  const int tag = mpiComm->getTag ();
493  MPI_Request rawRequest = MPI_REQUEST_NULL;
494  const int err = MPI_Irecv (rawRecvBuf, count, rawType, sourceRank, tag,
495  rawComm, &rawRequest);
497  err != MPI_SUCCESS, std::runtime_error,
498  "MPI_Irecv failed with the following error: "
499  << ::Teuchos::Details::getMpiErrorString (err));
500 
501  ArrayRCP<const char> buf =
502  arcp_const_cast<const char> (arcp_reinterpret_cast<char> (recvBuffer));
503  RCP<Details::MpiCommRequest> req (new Details::MpiCommRequest (rawRequest, buf));
504  return rcp_implicit_cast<CommRequest<int> > (req);
505  }
506 #else
508  true,
509  std::logic_error,
510  "ireceiveImpl: Not implemented for a serial communicator.");
511 
512  // NOTE (mfh 15 Sep 2014): Most compilers have figured out that the
513  // return statement below is unreachable. Some older compilers
514  // might not realize this. That's why the return statement was put
515  // there, so that those compilers don't warn that this function
516  // doesn't return a value. If it's a choice between one warning and
517  // another, I would prefer the choice that produces less code and
518  // doesn't have unreachable code (which never gets tested).
519 
520  //return null; // Guard to avoid compiler warning about not returning a value.
521 #endif // HAVE_TEUCHOS_MPI
522 }
523 
526 template<class T>
527 RCP<CommRequest<int> >
528 ireceiveImpl (const ArrayRCP<T>& recvBuffer,
529  const int sourceRank,
530  const int tag,
531  const Comm<int>& comm)
532 {
533 #ifdef HAVE_TEUCHOS_MPI
534  using Teuchos::Details::MpiTypeTraits;
535 
536  // Even in an MPI build, Comm might be either a SerialComm or an
537  // MpiComm. If it's something else, we fall back to the most
538  // general implementation.
539  const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
540  if (mpiComm == NULL) {
541  // Is it a SerialComm?
542  const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
543  if (serialComm == NULL) {
544  // We don't know what kind of Comm we have, so fall back to the
545  // most general implementation.
546  return ireceiveGeneral<T> (recvBuffer, sourceRank, tag, comm);
547  }
548  else { // SerialComm doesn't implement ireceive anyway.
550  true,
551  std::logic_error,
552  "ireceiveImpl: Not implemented for a serial communicator.");
553  }
554  }
555  else { // It's an MpiComm. Invoke MPI directly.
556  MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
557  T t;
558  MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
559  T* rawRecvBuf = recvBuffer.getRawPtr ();
560  const int count = as<int> (recvBuffer.size ());
561  MPI_Request rawRequest = MPI_REQUEST_NULL;
562  const int err = MPI_Irecv (rawRecvBuf, count, rawType, sourceRank, tag,
563  rawComm, &rawRequest);
565  err != MPI_SUCCESS, std::runtime_error,
566  "MPI_Irecv failed with the following error: "
567  << ::Teuchos::Details::getMpiErrorString (err));
568 
569  ArrayRCP<const char> buf =
570  arcp_const_cast<const char> (arcp_reinterpret_cast<char> (recvBuffer));
571  RCP<Details::MpiCommRequest> req (new Details::MpiCommRequest (rawRequest, buf));
572  return rcp_implicit_cast<CommRequest<int> > (req);
573  }
574 #else
576  true,
577  std::logic_error,
578  "ireceiveImpl: Not implemented for a serial communicator.");
579 
580  return null; // Guard to avoid compiler warning about not returning a value.
581 #endif // HAVE_TEUCHOS_MPI
582 }
583 
589 template<class T>
590 void
591 sendGeneral (const Comm<int>& comm,
592  const int count,
593  const T sendBuffer[],
594  const int destRank)
595 {
597  "Teuchos::send<int, " << TypeNameTraits<T>::name () << ">");
598  ConstValueTypeSerializationBuffer<int,T> charSendBuffer (count, sendBuffer);
599  comm.send (charSendBuffer.getBytes (),
600  charSendBuffer.getCharBuffer (),
601  destRank);
602 }
603 
606 template<class T>
607 void
608 sendGeneral (const T sendBuffer[],
609  const int count,
610  const int destRank,
611  const int tag,
612  const Comm<int>& comm)
613 {
615  "Teuchos::send<int, " << TypeNameTraits<T>::name () << ">");
616  ConstValueTypeSerializationBuffer<int,T> charSendBuffer (count, sendBuffer);
617  comm.send (charSendBuffer.getBytes (),
618  charSendBuffer.getCharBuffer (),
619  destRank, tag);
620 }
621 
634 template<class T>
635 void
636 sendImpl (const Comm<int>& comm,
637  const int count,
638  const T sendBuffer[],
639  const int destRank)
640 {
641 #ifdef HAVE_TEUCHOS_MPI
642  using Teuchos::Details::MpiTypeTraits;
643 
644  // Even in an MPI build, Comm might be either a SerialComm or an
645  // MpiComm. If it's something else, we fall back to the most
646  // general implementation.
647  const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
648  if (mpiComm == NULL) {
649  // Is it a SerialComm?
650  const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
651  if (serialComm == NULL) {
652  // We don't know what kind of Comm we have, so fall back to the
653  // most general implementation.
654  sendGeneral<T> (comm, count, sendBuffer, destRank);
655  }
656  else { // SerialComm doesn't implement send correctly anyway.
658  true,
659  std::logic_error,
660  "sendImpl: Not implemented for a serial communicator.");
661  }
662  }
663  else { // It's an MpiComm. Invoke MPI directly.
665  "Teuchos::sendImpl<" << TypeNameTraits<T>::name () << ">");
666  MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
667  T t;
668  MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
669  T* rawBuf = const_cast<T*> (sendBuffer);
670  const int tag = mpiComm->getTag ();
671  const int err = MPI_Send (rawBuf, count, rawType, destRank, tag, rawComm);
673  err != MPI_SUCCESS,
674  std::runtime_error,
675  "MPI_Send failed with the following error: "
676  << ::Teuchos::Details::getMpiErrorString (err));
677  }
678 #else
680  true,
681  std::logic_error,
682  "sendImpl: Not implemented for a serial communicator.");
683 #endif // HAVE_TEUCHOS_MPI
684 }
685 
688 template<class T>
689 void
690 sendImpl (const T sendBuffer[],
691  const int count,
692  const int destRank,
693  const int tag,
694  const Comm<int>& comm)
695 {
696 #ifdef HAVE_TEUCHOS_MPI
697  using Teuchos::Details::MpiTypeTraits;
698 
699  // Even in an MPI build, Comm might be either a SerialComm or an
700  // MpiComm. If it's something else, we fall back to the most
701  // general implementation.
702  const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
703  if (mpiComm == NULL) {
704  // Is it a SerialComm?
705  const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
706  if (serialComm == NULL) {
707  // We don't know what kind of Comm we have, so fall back to the
708  // most general implementation.
709  sendGeneral<T> (sendBuffer, count, destRank, tag, comm);
710  }
711  else { // SerialComm doesn't implement send correctly anyway.
713  true,
714  std::logic_error,
715  "sendImpl: Not implemented for a serial communicator.");
716  }
717  }
718  else { // It's an MpiComm. Invoke MPI directly.
720  "Teuchos::sendImpl<" << TypeNameTraits<T>::name () << ">");
721  MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
722  T t;
723  MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
724  T* rawBuf = const_cast<T*> (sendBuffer);
725  const int err = MPI_Send (rawBuf, count, rawType, destRank, tag, rawComm);
727  err != MPI_SUCCESS,
728  std::runtime_error,
729  "MPI_Send failed with the following error: "
730  << ::Teuchos::Details::getMpiErrorString (err));
731  }
732 #else
734  true,
735  std::logic_error,
736  "sendImpl: Not implemented for a serial communicator.");
737 #endif // HAVE_TEUCHOS_MPI
738 }
739 
745 template<class T>
746 RCP<CommRequest<int> >
747 isendGeneral (const Comm<int>& comm,
748  const ArrayRCP<const T>& sendBuffer,
749  const int destRank)
750 {
752  "Teuchos::isend<int," << TypeNameTraits<T>::name () << ">");
753  ConstValueTypeSerializationBuffer<int, T>
754  charSendBuffer (sendBuffer.size (), sendBuffer.getRawPtr ());
755  RCP<CommRequest<int> > commRequest =
756  comm.isend (charSendBuffer.getCharBufferView (), destRank);
757  set_extra_data (sendBuffer, "buffer", inOutArg (commRequest));
758  return commRequest;
759 }
760 
767 template<class T>
768 RCP<CommRequest<int> >
769 isendGeneral (const ArrayRCP<const T>& sendBuffer,
770  const int destRank,
771  const int tag,
772  const Comm<int>& comm)
773 {
775  "Teuchos::isend<int," << TypeNameTraits<T>::name () << ">");
776  ConstValueTypeSerializationBuffer<int, T>
777  charSendBuffer (sendBuffer.size (), sendBuffer.getRawPtr ());
778  RCP<CommRequest<int> > commRequest =
779  comm.isend (charSendBuffer.getCharBufferView (), destRank, tag);
780  set_extra_data (sendBuffer, "buffer", inOutArg (commRequest));
781  return commRequest;
782 }
783 
786 template<class T>
787 RCP<Teuchos::CommRequest<int> >
788 isendImpl (const ArrayRCP<const T>& sendBuffer,
789  const int destRank,
790  const int tag,
791  const Comm<int>& comm)
792 {
793 #ifdef HAVE_TEUCHOS_MPI
794  using Teuchos::Details::MpiTypeTraits;
795 
796  // Even in an MPI build, Comm might be either a SerialComm or an
797  // MpiComm. If it's something else, we fall back to the most
798  // general implementation.
799  const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
800  if (mpiComm == NULL) {
801  // Is it a SerialComm?
802  const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
803  if (serialComm == NULL) {
804  // We don't know what kind of Comm we have, so fall back to the
805  // most general implementation.
806  return isendGeneral<T> (sendBuffer, destRank, tag, comm);
807  }
808  else { // SerialComm doesn't implement send correctly anyway.
810  true, std::logic_error,
811  "isendImpl: Not implemented for a serial communicator.");
812  }
813  }
814  else { // It's an MpiComm. Invoke MPI directly.
816  "Teuchos::isendImpl<" << TypeNameTraits<T>::name () << ">");
817 
818  MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
819  T t;
820  MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
821  // MPI promises not to modify the send buffer; the const_cast
822  // merely ensures compatibilty with C89, which does not have a
823  // "const" keyword.
824  T* rawSendBuf = const_cast<T*> (sendBuffer.getRawPtr ());
825  const int count = as<int> (sendBuffer.size ());
826  MPI_Request rawRequest = MPI_REQUEST_NULL;
827  const int err = MPI_Isend (rawSendBuf, count, rawType, destRank, tag,
828  rawComm, &rawRequest);
830  err != MPI_SUCCESS,
831  std::runtime_error,
832  "MPI_Isend failed with the following error: "
833  << ::Teuchos::Details::getMpiErrorString (err));
834 
835  ArrayRCP<const char> buf = arcp_reinterpret_cast<const char> (sendBuffer);
836  RCP<Details::MpiCommRequest> req (new Details::MpiCommRequest (rawRequest, buf));
837  return rcp_implicit_cast<CommRequest<int> > (req);
838  }
839 #else
841  true,
842  std::logic_error,
843  "isendImpl: Not implemented for a serial communicator.");
844 #endif // HAVE_TEUCHOS_MPI
845 }
846 
847 } // namespace (anonymous)
848 
849 
850 // mfh 18 Oct 2012: Note on full template specializations
851 //
852 // To make Windows builds happy, declarations of full template
853 // specializations (as found in Teuchos_CommHelpers.hpp) must use the
854 // TEUCHOSCOMM_LIB_DLL_EXPORT macro. However, _definitions_ of the
855 // specializations (as found in this file) must _not_ use the macro.
856 // That's why we don't use that macro here.
857 
858 // amb See note in .hpp file.
859 #if 0
860 #ifdef HAVE_TEUCHOS_COMPLEX
861 // Specialization for Ordinal=int and Packet=std::complex<double>.
862 template<>
863 void
864 reduceAll<int, std::complex<double> > (const Comm<int>& comm,
865  const EReductionType reductType,
866  const int count,
867  const std::complex<double> sendBuffer[],
868  std::complex<double> globalReducts[])
869 {
871  "Teuchos::reduceAll<int, std::complex<double> > (" << count << ", "
872  << toString (reductType) << ")"
873  );
874  reduceAllImpl<std::complex<double> > (comm, reductType, count, sendBuffer, globalReducts);
875 }
876 
877 template<>
878 RCP<Teuchos::CommRequest<int> >
879 ireceive<int, std::complex<double> > (const Comm<int>& comm,
880  const ArrayRCP<std::complex<double> >& recvBuffer,
881  const int sourceRank)
882 {
883  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<double> >");
884  return ireceiveImpl<std::complex<double> > (comm, recvBuffer, sourceRank);
885 }
886 
887 template<>
888 RCP<Teuchos::CommRequest<int> >
889 ireceive<int, std::complex<double> > (const ArrayRCP<std::complex<double> >& recvBuffer,
890  const int sourceRank,
891  const int tag,
892  const Comm<int>& comm)
893 {
894  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<double> >");
895  return ireceiveImpl<std::complex<double> > (recvBuffer, sourceRank, tag, comm);
896 }
897 
898 template<>
899 void
900 send<int, std::complex<double> > (const Comm<int>& comm,
901  const int count,
902  const std::complex<double> sendBuffer[],
903  const int destRank)
904 {
905  sendImpl<std::complex<double> > (comm, count, sendBuffer, destRank);
906 }
907 
908 template<>
909 void
910 send<int, std::complex<double> > (const std::complex<double> sendBuffer[],
911  const int count,
912  const int destRank,
913  const int tag,
914  const Comm<int>& comm)
915 {
916  sendImpl<std::complex<double> > (sendBuffer, count, destRank, tag, comm);
917 }
918 
919 template<>
920 RCP<Teuchos::CommRequest<int> >
921 isend (const ArrayRCP<const std::complex<double> >& sendBuffer,
922  const int destRank,
923  const int tag,
924  const Comm<int>& comm)
925 {
926  return isendImpl<std::complex<double> > (sendBuffer, destRank, tag, comm);
927 }
928 
929 // Specialization for Ordinal=int and Packet=std::complex<float>.
930 template<>
931 void
932 reduceAll<int, std::complex<float> > (const Comm<int>& comm,
933  const EReductionType reductType,
934  const int count,
935  const std::complex<float> sendBuffer[],
936  std::complex<float> globalReducts[])
937 {
939  "Teuchos::reduceAll<int, std::complex<float> > (" << count << ", "
940  << toString (reductType) << ")"
941  );
942  reduceAllImpl<std::complex<float> > (comm, reductType, count, sendBuffer, globalReducts);
943 }
944 
945 template<>
946 RCP<Teuchos::CommRequest<int> >
947 ireceive<int, std::complex<float> > (const Comm<int>& comm,
948  const ArrayRCP<std::complex<float> >& recvBuffer,
949  const int sourceRank)
950 {
951  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<float> >");
952  return ireceiveImpl<std::complex<float> > (comm, recvBuffer, sourceRank);
953 }
954 
955 template<>
956 RCP<Teuchos::CommRequest<int> >
957 ireceive<int, std::complex<float> > (const ArrayRCP<std::complex<float> >& recvBuffer,
958  const int sourceRank,
959  const int tag,
960  const Comm<int>& comm)
961 {
962  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<float> >");
963  return ireceiveImpl<std::complex<float> > (recvBuffer, sourceRank, tag, comm);
964 }
965 
966 template<>
967 void
968 send<int, std::complex<float> > (const Comm<int>& comm,
969  const int count,
970  const std::complex<float> sendBuffer[],
971  const int destRank)
972 {
973  return sendImpl<std::complex<float> > (comm, count, sendBuffer, destRank);
974 }
975 
976 template<>
977 void
978 send<int, std::complex<float> > (const std::complex<float> sendBuffer[],
979  const int count,
980  const int destRank,
981  const int tag,
982  const Comm<int>& comm)
983 {
984  return sendImpl<std::complex<float> > (sendBuffer, count, destRank, tag, comm);
985 }
986 
987 template<>
988 RCP<Teuchos::CommRequest<int> >
989 isend (const ArrayRCP<const std::complex<float> >& sendBuffer,
990  const int destRank,
991  const int tag,
992  const Comm<int>& comm)
993 {
994  return isendImpl<std::complex<float> > (sendBuffer, destRank, tag, comm);
995 }
996 #endif // HAVE_TEUCHOS_COMPLEX
997 #endif // if 0
998 
999 // Specialization for Ordinal=int and Packet=double.
1000 template<>
1001 void
1003  const EReductionType reductType,
1004  const int count,
1005  const double sendBuffer[],
1006  double globalReducts[])
1007 {
1009  "Teuchos::reduceAll<int, double> (" << count << ", "
1010  << toString (reductType) << ")"
1011  );
1012  reduceAllImpl<double> (comm, reductType, count, sendBuffer, globalReducts);
1013 }
1014 
1015 template<>
1016 RCP<Teuchos::CommRequest<int> >
1018  const ArrayRCP<double>& recvBuffer,
1019  const int sourceRank)
1020 {
1021  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, double>");
1022  return ireceiveImpl<double> (comm, recvBuffer, sourceRank);
1023 }
1024 
1025 template<>
1026 RCP<Teuchos::CommRequest<int> >
1028  const int sourceRank,
1029  const int tag,
1030  const Comm<int>& comm)
1031 {
1032  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, double>");
1033  return ireceiveImpl<double> (recvBuffer, sourceRank, tag, comm);
1034 }
1035 
1036 template<>
1037 void
1039  const int count,
1040  const double sendBuffer[],
1041  const int destRank)
1042 {
1043  return sendImpl<double> (comm, count, sendBuffer, destRank);
1044 }
1045 
1046 template<>
1047 void
1048 send<int, double> (const double sendBuffer[],
1049  const int count,
1050  const int destRank,
1051  const int tag,
1052  const Comm<int>& comm)
1053 {
1054  return sendImpl<double> (sendBuffer, count, destRank, tag, comm);
1055 }
1056 
1057 template<>
1058 RCP<Teuchos::CommRequest<int> >
1059 isend (const ArrayRCP<const double>& sendBuffer,
1060  const int destRank,
1061  const int tag,
1062  const Comm<int>& comm)
1063 {
1064  return isendImpl<double> (sendBuffer, destRank, tag, comm);
1065 }
1066 
1067 template<>
1068 void
1069 gatherv<int, double> (const double sendBuf[],
1070  const int sendCount,
1071  double recvBuf[],
1072  const int recvCounts[],
1073  const int displs[],
1074  const int root,
1075  const Comm<int>& comm)
1076 {
1077  gathervImpl<double> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1078 }
1079 
1080 
1081 // Specialization for Ordinal=int and Packet=float.
1082 template<>
1083 void
1085  const EReductionType reductType,
1086  const int count,
1087  const float sendBuffer[],
1088  float globalReducts[])
1089 {
1091  "Teuchos::reduceAll<int, float> (" << count << ", "
1092  << toString (reductType) << ")"
1093  );
1094  reduceAllImpl<float> (comm, reductType, count, sendBuffer, globalReducts);
1095 }
1096 
1097 template<>
1098 RCP<Teuchos::CommRequest<int> >
1100  const ArrayRCP<float>& recvBuffer,
1101  const int sourceRank)
1102 {
1103  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, float>");
1104  return ireceiveImpl<float> (comm, recvBuffer, sourceRank);
1105 }
1106 
1107 template<>
1108 RCP<Teuchos::CommRequest<int> >
1110  const int sourceRank,
1111  const int tag,
1112  const Comm<int>& comm)
1113 {
1114  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, float>");
1115  return ireceiveImpl<float> (recvBuffer, sourceRank, tag, comm);
1116 }
1117 
1118 template<>
1119 void
1121  const int count,
1122  const float sendBuffer[],
1123  const int destRank)
1124 {
1125  return sendImpl<float> (comm, count, sendBuffer, destRank);
1126 }
1127 
1128 template<>
1129 void
1130 send<int, float> (const float sendBuffer[],
1131  const int count,
1132  const int destRank,
1133  const int tag,
1134  const Comm<int>& comm)
1135 {
1136  return sendImpl<float> (sendBuffer, count, destRank, tag, comm);
1137 }
1138 
1139 template<>
1140 RCP<Teuchos::CommRequest<int> >
1141 isend (const ArrayRCP<const float>& sendBuffer,
1142  const int destRank,
1143  const int tag,
1144  const Comm<int>& comm)
1145 {
1146  return isendImpl<float> (sendBuffer, destRank, tag, comm);
1147 }
1148 
1149 template<>
1150 void
1151 gatherv<int,float> (const float sendBuf[],
1152  const int sendCount,
1153  float recvBuf[],
1154  const int recvCounts[],
1155  const int displs[],
1156  const int root,
1157  const Comm<int>& comm)
1158 {
1159  gathervImpl<float> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1160 }
1161 
1162 
1163 // Specialization for Ordinal=int and Packet=long long.
1164 template<>
1165 void
1166 gather<int, long long> (const long long sendBuf[],
1167  const int sendCount,
1168  long long recvBuf[],
1169  const int recvCount,
1170  const int root,
1171  const Comm<int>& comm)
1172 {
1173  gatherImpl<long long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1174 }
1175 
1176 template<>
1177 void
1178 gatherv<int, long long> (const long long sendBuf[],
1179  const int sendCount,
1180  long long recvBuf[],
1181  const int recvCounts[],
1182  const int displs[],
1183  const int root,
1184  const Comm<int>& comm)
1185 {
1186  gathervImpl<long long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1187 }
1188 
1189 template<>
1190 void
1192  const EReductionType reductType,
1193  const int count,
1194  const long long sendBuffer[],
1195  long long globalReducts[])
1196 {
1198  "Teuchos::reduceAll<int, long long> (" << count << ", "
1199  << toString (reductType) << ")"
1200  );
1201  reduceAllImpl<long long> (comm, reductType, count, sendBuffer, globalReducts);
1202 }
1203 
1204 template<>
1205 RCP<Teuchos::CommRequest<int> >
1207  const ArrayRCP<long long>& recvBuffer,
1208  const int sourceRank)
1209 {
1210  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long long>");
1211  return ireceiveImpl<long long> (comm, recvBuffer, sourceRank);
1212 }
1213 
1214 template<>
1215 RCP<Teuchos::CommRequest<int> >
1217  const int sourceRank,
1218  const int tag,
1219  const Comm<int>& comm)
1220 {
1221  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long long>");
1222  return ireceiveImpl<long long> (recvBuffer, sourceRank, tag, comm);
1223 }
1224 
1225 template<>
1226 void
1228  const int count,
1229  const long long sendBuffer[],
1230  const int destRank)
1231 {
1232  return sendImpl<long long> (comm, count, sendBuffer, destRank);
1233 }
1234 
1235 template<>
1236 void
1237 send<int, long long> (const long long sendBuffer[],
1238  const int count,
1239  const int destRank,
1240  const int tag,
1241  const Comm<int>& comm)
1242 {
1243  return sendImpl<long long> (sendBuffer, count, destRank, tag, comm);
1244 }
1245 
1246 template<>
1247 RCP<Teuchos::CommRequest<int> >
1249  const int destRank,
1250  const int tag,
1251  const Comm<int>& comm)
1252 {
1253  return isendImpl<long long> (sendBuffer, destRank, tag, comm);
1254 }
1255 
1256 // Specialization for Ordinal=int and Packet=unsigned long long.
1257 template<>
1258 void
1259 gather<int, unsigned long long> (const unsigned long long sendBuf[],
1260  const int sendCount,
1261  unsigned long long recvBuf[],
1262  const int recvCount,
1263  const int root,
1264  const Comm<int>& comm)
1265 {
1266  gatherImpl<unsigned long long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1267 }
1268 
1269 template<>
1270 void
1271 gatherv<int, unsigned long long> (const unsigned long long sendBuf[],
1272  const int sendCount,
1273  unsigned long long recvBuf[],
1274  const int recvCounts[],
1275  const int displs[],
1276  const int root,
1277  const Comm<int>& comm)
1278 {
1279  gathervImpl<unsigned long long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1280 }
1281 
1282 template<>
1283 void
1285  const EReductionType reductType,
1286  const int count,
1287  const unsigned long long sendBuffer[],
1288  unsigned long long globalReducts[])
1289 {
1291  "Teuchos::reduceAll<int, unsigned long long> (" << count << ", "
1292  << toString (reductType) << ")"
1293  );
1294  reduceAllImpl<unsigned long long> (comm, reductType, count, sendBuffer, globalReducts);
1295 }
1296 
1297 template<>
1298 RCP<Teuchos::CommRequest<int> >
1300  const ArrayRCP<unsigned long long>& recvBuffer,
1301  const int sourceRank)
1302 {
1303  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long long>");
1304  return ireceiveImpl<unsigned long long> (comm, recvBuffer, sourceRank);
1305 }
1306 
1307 template<>
1308 RCP<Teuchos::CommRequest<int> >
1310  const int sourceRank,
1311  const int tag,
1312  const Comm<int>& comm)
1313 {
1314  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long long>");
1315  return ireceiveImpl<unsigned long long> (recvBuffer, sourceRank, tag, comm);
1316 }
1317 
1318 template<>
1319 void
1321  const int count,
1322  const unsigned long long sendBuffer[],
1323  const int destRank)
1324 {
1325  return sendImpl<unsigned long long> (comm, count, sendBuffer, destRank);
1326 }
1327 
1328 template<>
1329 void
1330 send<int, unsigned long long> (const unsigned long long sendBuffer[],
1331  const int count,
1332  const int destRank,
1333  const int tag,
1334  const Comm<int>& comm)
1335 {
1336  return sendImpl<unsigned long long> (sendBuffer, count, destRank, tag, comm);
1337 }
1338 
1339 template<>
1340 RCP<Teuchos::CommRequest<int> >
1342  const int destRank,
1343  const int tag,
1344  const Comm<int>& comm)
1345 {
1346  return isendImpl<unsigned long long> (sendBuffer, destRank, tag, comm);
1347 }
1348 
1349 
1350 // Specialization for Ordinal=int and Packet=long.
1351 template<>
1352 void
1353 gather<int, long> (const long sendBuf[],
1354  const int sendCount,
1355  long recvBuf[],
1356  const int recvCount,
1357  const int root,
1358  const Comm<int>& comm)
1359 {
1360  gatherImpl<long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1361 }
1362 
1363 template<>
1364 void
1365 gatherv<int, long> (const long sendBuf[],
1366  const int sendCount,
1367  long recvBuf[],
1368  const int recvCounts[],
1369  const int displs[],
1370  const int root,
1371  const Comm<int>& comm)
1372 {
1373  gathervImpl<long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1374 }
1375 
1376 template<>
1377 void
1379  const EReductionType reductType,
1380  const int count,
1381  const long sendBuffer[],
1382  long globalReducts[])
1383 {
1385  "Teuchos::reduceAll<int, long> (" << count << ", "
1386  << toString (reductType) << ")"
1387  );
1388  reduceAllImpl<long> (comm, reductType, count, sendBuffer, globalReducts);
1389 }
1390 
1391 template<>
1392 RCP<Teuchos::CommRequest<int> >
1394  const ArrayRCP<long>& recvBuffer,
1395  const int sourceRank)
1396 {
1397  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long>");
1398  return ireceiveImpl<long> (comm, recvBuffer, sourceRank);
1399 }
1400 
1401 template<>
1402 RCP<Teuchos::CommRequest<int> >
1404  const int sourceRank,
1405  const int tag,
1406  const Comm<int>& comm)
1407 {
1408  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long>");
1409  return ireceiveImpl<long> (recvBuffer, sourceRank, tag, comm);
1410 }
1411 
1412 template<>
1413 void
1415  const int count,
1416  const long sendBuffer[],
1417  const int destRank)
1418 {
1419  return sendImpl<long> (comm, count, sendBuffer, destRank);
1420 }
1421 
1422 template<>
1423 void
1424 send<int, long> (const long sendBuffer[],
1425  const int count,
1426  const int destRank,
1427  const int tag,
1428  const Comm<int>& comm)
1429 {
1430  return sendImpl<long> (sendBuffer, count, destRank, tag, comm);
1431 }
1432 
1433 template<>
1434 RCP<Teuchos::CommRequest<int> >
1435 isend (const ArrayRCP<const long>& sendBuffer,
1436  const int destRank,
1437  const int tag,
1438  const Comm<int>& comm)
1439 {
1440  return isendImpl<long> (sendBuffer, destRank, tag, comm);
1441 }
1442 
1443 
1444 // Specialization for Ordinal=int and Packet=unsigned long.
1445 template<>
1446 void
1447 gather<int, unsigned long> (const unsigned long sendBuf[],
1448  const int sendCount,
1449  unsigned long recvBuf[],
1450  const int recvCount,
1451  const int root,
1452  const Comm<int>& comm)
1453 {
1454  gatherImpl<unsigned long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1455 }
1456 
1457 template<>
1458 void
1459 gatherv<int, unsigned long> (const unsigned long sendBuf[],
1460  const int sendCount,
1461  unsigned long recvBuf[],
1462  const int recvCounts[],
1463  const int displs[],
1464  const int root,
1465  const Comm<int>& comm)
1466 {
1467  gathervImpl<unsigned long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1468 }
1469 
1470 template<>
1471 void
1473  const EReductionType reductType,
1474  const int count,
1475  const unsigned long sendBuffer[],
1476  unsigned long globalReducts[])
1477 {
1479  "Teuchos::reduceAll<int, unsigned long> (" << count << ", "
1480  << toString (reductType) << ")"
1481  );
1482  reduceAllImpl<unsigned long> (comm, reductType, count, sendBuffer, globalReducts);
1483 }
1484 
1485 template<>
1486 RCP<Teuchos::CommRequest<int> >
1488  const ArrayRCP<unsigned long>& recvBuffer,
1489  const int sourceRank)
1490 {
1491  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long>");
1492  return ireceiveImpl<unsigned long> (comm, recvBuffer, sourceRank);
1493 }
1494 
1495 template<>
1496 RCP<Teuchos::CommRequest<int> >
1498  const int sourceRank,
1499  const int tag,
1500  const Comm<int>& comm)
1501 {
1502  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long>");
1503  return ireceiveImpl<unsigned long> (recvBuffer, sourceRank, tag, comm);
1504 }
1505 
1506 template<>
1507 void
1509  const int count,
1510  const unsigned long sendBuffer[],
1511  const int destRank)
1512 {
1513  return sendImpl<unsigned long> (comm, count, sendBuffer, destRank);
1514 }
1515 
1516 template<>
1517 void
1518 send<int, unsigned long> (const unsigned long sendBuffer[],
1519  const int count,
1520  const int destRank,
1521  const int tag,
1522  const Comm<int>& comm)
1523 {
1524  return sendImpl<unsigned long> (sendBuffer, count, destRank, tag, comm);
1525 }
1526 
1527 template<>
1528 RCP<Teuchos::CommRequest<int> >
1530  const int destRank,
1531  const int tag,
1532  const Comm<int>& comm)
1533 {
1534  return isendImpl<unsigned long> (sendBuffer, destRank, tag, comm);
1535 }
1536 
1537 // Specialization for Ordinal=int and Packet=int.
1538 template<>
1539 void
1540 gather<int, int> (const int sendBuf[],
1541  const int sendCount,
1542  int recvBuf[],
1543  const int recvCount,
1544  const int root,
1545  const Comm<int>& comm)
1546 {
1547  gatherImpl<int> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1548 }
1549 
1550 template<>
1551 void
1552 gatherv<int, int> (const int sendBuf[],
1553  const int sendCount,
1554  int recvBuf[],
1555  const int recvCounts[],
1556  const int displs[],
1557  const int root,
1558  const Comm<int>& comm)
1559 {
1560  gathervImpl<int> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1561 }
1562 
1563 template<>
1564 void
1565 scatter<int, int> (const int sendBuf[],
1566  const int sendCount,
1567  int recvBuf[],
1568  const int recvCount,
1569  const int root,
1570  const Comm<int>& comm)
1571 {
1572  scatterImpl<int> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1573 }
1574 
1575 template<>
1576 void
1577 scatterv<int, double> (const double sendBuf[],
1578  const int sendCount[],
1579  const int displs[],
1580  double recvBuf[],
1581  const int recvCount,
1582  const int root,
1583  const Comm<int>& comm)
1584 {
1585  scattervImpl<double> (sendBuf, sendCount, displs, recvBuf, recvCount, root, comm);
1586 }
1587 
1588 template<>
1589 void
1590 scatterv<int, float> (const float sendBuf[],
1591  const int sendCounts[],
1592  const int displs[],
1593  float recvBuf[],
1594  const int recvCount,
1595  const int root,
1596  const Comm<int>& comm)
1597 {
1598  scattervImpl<float> (sendBuf, sendCounts, displs, recvBuf, recvCount, root, comm);
1599 }
1600 
1601 template<>
1602 void
1603 reduce<int, int> (const int sendBuf[],
1604  int recvBuf[],
1605  const int count,
1606  const EReductionType reductType,
1607  const int root,
1608  const Comm<int>& comm)
1609 {
1611  ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1612  << ")");
1613  reduceImpl<int> (sendBuf, recvBuf, count, reductType, root, comm);
1614 }
1615 template<>
1616 void
1617 reduce<int, long> (const long sendBuf[],
1618  long recvBuf[],
1619  const int count,
1620  const EReductionType reductType,
1621  const int root,
1622  const Comm<int>& comm)
1623 {
1625  ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1626  << ")");
1627  reduceImpl<long> (sendBuf, recvBuf, count, reductType, root, comm);
1628 }
1629 
1630 template<>
1631 void
1632 reduce<int, unsigned long> (const unsigned long sendBuf[],
1633  unsigned long recvBuf[],
1634  const int count,
1635  const EReductionType reductType,
1636  const int root,
1637  const Comm<int>& comm)
1638 {
1640  ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1641  << ")");
1642  reduceImpl<unsigned long> (sendBuf, recvBuf, count, reductType, root, comm);
1643 }
1644 
1645 template<>
1646 void
1647 reduce<int, unsigned long long > (const unsigned long long sendBuf[],
1648  unsigned long long recvBuf[],
1649  const int count,
1650  const EReductionType reductType,
1651  const int root,
1652  const Comm<int>& comm)
1653 {
1655  ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1656  << ")");
1657  reduceImpl<unsigned long long> (sendBuf, recvBuf, count, reductType, root, comm);
1658 }
1659 
1660 template<>
1661 void
1662 reduce<int, double> (const double sendBuf[],
1663  double recvBuf[],
1664  const int count,
1665  const EReductionType reductType,
1666  const int root,
1667  const Comm<int>& comm)
1668 {
1670  ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1671  << ")");
1672  reduceImpl<double> (sendBuf, recvBuf, count, reductType, root, comm);
1673 }
1674 template<>
1675 void
1677  const EReductionType reductType,
1678  const int count,
1679  const int sendBuffer[],
1680  int globalReducts[])
1681 {
1683  "Teuchos::reduceAll<int, int> (" << count << ", "
1684  << toString (reductType) << ")"
1685  );
1686  reduceAllImpl<int> (comm, reductType, count, sendBuffer, globalReducts);
1687 }
1688 
1689 template<>
1690 RCP<Teuchos::CommRequest<int> >
1692  const ArrayRCP<int>& recvBuffer,
1693  const int sourceRank)
1694 {
1695  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, int>");
1696  return ireceiveImpl<int> (comm, recvBuffer, sourceRank);
1697 }
1698 
1699 template<>
1700 RCP<Teuchos::CommRequest<int> >
1702  const int sourceRank,
1703  const int tag,
1704  const Comm<int>& comm)
1705 {
1706  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, int>");
1707  return ireceiveImpl<int> (recvBuffer, sourceRank, tag, comm);
1708 }
1709 
1710 template<>
1711 void
1713  const int count,
1714  const int sendBuffer[],
1715  const int destRank)
1716 {
1717  return sendImpl<int> (comm, count, sendBuffer, destRank);
1718 }
1719 
1720 template<>
1721 void
1722 send<int, int> (const int sendBuffer[],
1723  const int count,
1724  const int destRank,
1725  const int tag,
1726  const Comm<int>& comm)
1727 {
1728  return sendImpl<int> (sendBuffer, count, destRank, tag, comm);
1729 }
1730 
1731 template<>
1732 RCP<Teuchos::CommRequest<int> >
1733 isend (const ArrayRCP<const int>& sendBuffer,
1734  const int destRank,
1735  const int tag,
1736  const Comm<int>& comm)
1737 {
1738  return isendImpl<int> (sendBuffer, destRank, tag, comm);
1739 }
1740 
1741 // Specialization for Ordinal=int and Packet=unsigned int.
1742 template<>
1743 void
1744 gather<int, unsigned int> (const unsigned int sendBuf[],
1745  const int sendCount,
1746  unsigned int recvBuf[],
1747  const int recvCount,
1748  const int root,
1749  const Comm<int>& comm)
1750 {
1751  gatherImpl<unsigned int> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1752 }
1753 
1754 template<>
1755 void
1756 gatherv<int, unsigned int> (const unsigned int sendBuf[],
1757  const int sendCount,
1758  unsigned int recvBuf[],
1759  const int recvCounts[],
1760  const int displs[],
1761  const int root,
1762  const Comm<int>& comm)
1763 {
1764  gathervImpl<unsigned int> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1765 }
1766 
1767 template<>
1768 void
1770  const EReductionType reductType,
1771  const int count,
1772  const unsigned int sendBuffer[],
1773  unsigned int globalReducts[])
1774 {
1776  "Teuchos::reduceAll<int, unsigned int> (" << count << ", "
1777  << toString (reductType) << ")"
1778  );
1779  reduceAllImpl<unsigned int> (comm, reductType, count, sendBuffer, globalReducts);
1780 }
1781 
1782 template<>
1783 RCP<Teuchos::CommRequest<int> >
1785  const ArrayRCP<unsigned int>& recvBuffer,
1786  const int sourceRank)
1787 {
1788  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned int>");
1789  return ireceiveImpl<unsigned int> (comm, recvBuffer, sourceRank);
1790 }
1791 
1792 template<>
1793 RCP<Teuchos::CommRequest<int> >
1795  const int sourceRank,
1796  const int tag,
1797  const Comm<int>& comm)
1798 {
1799  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned int>");
1800  return ireceiveImpl<unsigned int> (recvBuffer, sourceRank, tag, comm);
1801 }
1802 
1803 template<>
1804 void
1806  const int count,
1807  const unsigned int sendBuffer[],
1808  const int destRank)
1809 {
1810  return sendImpl<unsigned int> (comm, count, sendBuffer, destRank);
1811 }
1812 
1813 template<>
1814 void
1815 send<int, unsigned int> (const unsigned int sendBuffer[],
1816  const int count,
1817  const int destRank,
1818  const int tag,
1819  const Comm<int>& comm)
1820 {
1821  return sendImpl<unsigned int> (sendBuffer, count, destRank, tag, comm);
1822 }
1823 
1824 template<>
1825 RCP<Teuchos::CommRequest<int> >
1827  const int destRank,
1828  const int tag,
1829  const Comm<int>& comm)
1830 {
1831  return isendImpl<unsigned int> (sendBuffer, destRank, tag, comm);
1832 }
1833 
1834 
1835 // Specialization for Ordinal=int and Packet=short.
1836 template<>
1837 void
1838 gather<int, short> (const short sendBuf[],
1839  const int sendCount,
1840  short recvBuf[],
1841  const int recvCount,
1842  const int root,
1843  const Comm<int>& comm)
1844 {
1845  gatherImpl<short> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1846 }
1847 
1848 template<>
1849 void
1850 gatherv<int, short> (const short sendBuf[],
1851  const int sendCount,
1852  short recvBuf[],
1853  const int recvCounts[],
1854  const int displs[],
1855  const int root,
1856  const Comm<int>& comm)
1857 {
1858  gathervImpl<short> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1859 }
1860 
1861 template<>
1862 void
1864  const EReductionType reductType,
1865  const int count,
1866  const short sendBuffer[],
1867  short globalReducts[])
1868 {
1870  "Teuchos::reduceAll<int, short> (" << count << ", "
1871  << toString (reductType) << ")"
1872  );
1873  reduceAllImpl<short> (comm, reductType, count, sendBuffer, globalReducts);
1874 }
1875 
1876 template<>
1877 RCP<Teuchos::CommRequest<int> >
1879  const ArrayRCP<short>& recvBuffer,
1880  const int sourceRank)
1881 {
1882  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, short>");
1883  return ireceiveImpl<short> (comm, recvBuffer, sourceRank);
1884 }
1885 
1886 template<>
1887 RCP<Teuchos::CommRequest<int> >
1889  const int sourceRank,
1890  const int tag,
1891  const Comm<int>& comm)
1892 {
1893  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, short>");
1894  return ireceiveImpl<short> (recvBuffer, sourceRank, tag, comm);
1895 }
1896 
1897 template<>
1898 void
1900  const int count,
1901  const short sendBuffer[],
1902  const int destRank)
1903 {
1904  return sendImpl<short> (comm, count, sendBuffer, destRank);
1905 }
1906 
1907 template<>
1908 void
1909 send<int, short> (const short sendBuffer[],
1910  const int count,
1911  const int destRank,
1912  const int tag,
1913  const Comm<int>& comm)
1914 {
1915  return sendImpl<short> (sendBuffer, count, destRank, tag, comm);
1916 }
1917 
1918 template<>
1919 RCP<Teuchos::CommRequest<int> >
1920 isend (const ArrayRCP<const short>& sendBuffer,
1921  const int destRank,
1922  const int tag,
1923  const Comm<int>& comm)
1924 {
1925  return isendImpl<short> (sendBuffer, destRank, tag, comm);
1926 }
1927 
1928 // mfh 18 Oct 2012: The specialization for Packet=char seems to be
1929 // causing problems such as the following:
1930 //
1931 // http://testing.sandia.gov/cdash/testDetails.php?test=9909246&build=747699
1932 //
1933 // I am disabling it for now. This should revert back to the old
1934 // behavior for Packet=char. That should fix the Tpetra errors, since
1935 // many Tpetra objects inherit from DistObject<char, ...>.
1936 #if 0
1937 // Specialization for Ordinal=int and Packet=char.
1938 template<>
1939 void
1940 reduceAll<int, char> (const Comm<int>& comm,
1941  const EReductionType reductType,
1942  const int count,
1943  const char sendBuffer[],
1944  char globalReducts[])
1945 {
1947  "Teuchos::reduceAll<int, char> (" << count << ", "
1948  << toString (reductType) << ")"
1949  );
1950  reduceAllImpl<char> (comm, reductType, count, sendBuffer, globalReducts);
1951 }
1952 #endif // 0
1953 
1954 } // namespace Teuchos
void reduce< int, unsigned long >(const unsigned long sendBuf[], unsigned long recvBuf[], const int count, const EReductionType reductType, const int root, const Comm< int > &comm)
void reduce< int, long >(const long sendBuf[], long recvBuf[], const int count, const EReductionType reductType, const int root, const Comm< int > &comm)
RCP< Teuchos::CommRequest< int > > ireceive< int, unsigned long long >(const Comm< int > &comm, const ArrayRCP< unsigned long long > &recvBuffer, const int sourceRank)
void send< int, float >(const Comm< int > &comm, const int count, const float sendBuffer[], const int destRank)
EReductionType
Predefined reduction operations that Teuchos::Comm understands.
RCP< Teuchos::CommRequest< int > > ireceive< int, float >(const Comm< int > &comm, const ArrayRCP< float > &recvBuffer, const int sourceRank)
void gatherv< int, short >(const short sendBuf[], const int sendCount, short recvBuf[], const int recvCounts[], const int displs[], const int root, const Comm< int > &comm)
void gather< int, unsigned long long >(const unsigned long long sendBuf[], const int sendCount, unsigned long long recvBuf[], const int recvCount, const int root, const Comm< int > &comm)
void reduceAll< int, long >(const Comm< int > &comm, const EReductionType reductType, const int count, const long sendBuffer[], long globalReducts[])
void send< int, unsigned long long >(const Comm< int > &comm, const int count, const unsigned long long sendBuffer[], const int destRank)
RCP< Teuchos::CommRequest< int > > ireceive< int, double >(const Comm< int > &comm, const ArrayRCP< double > &recvBuffer, const int sourceRank)
RCP< Teuchos::CommRequest< int > > ireceive< int, short >(const Comm< int > &comm, const ArrayRCP< short > &recvBuffer, const int sourceRank)
void send< int, long >(const Comm< int > &comm, const int count, const long sendBuffer[], const int destRank)
void gather< int, unsigned int >(const unsigned int sendBuf[], const int sendCount, unsigned int recvBuf[], const int recvCount, const int root, const Comm< int > &comm)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
void reduce< int, double >(const double sendBuf[], double recvBuf[], const int count, const EReductionType reductType, const int root, const Comm< int > &comm)
void scatterv< int, double >(const double sendBuf[], const int sendCount[], const int displs[], double recvBuf[], const int recvCount, const int root, const Comm< int > &comm)
void scatter< int, int >(const int sendBuf[], const int sendCount, int recvBuf[], const int recvCount, const int root, const Comm< int > &comm)
void gatherv< int, int >(const int sendBuf[], const int sendCount, int recvBuf[], const int recvCounts[], const int displs[], const int root, const Comm< int > &comm)
void gatherv< int, long long >(const long long sendBuf[], const int sendCount, long long recvBuf[], const int recvCounts[], const int displs[], const int root, const Comm< int > &comm)
void gather< int, long >(const long sendBuf[], const int sendCount, long recvBuf[], const int recvCount, const int root, const Comm< int > &comm)
RCP< Teuchos::CommRequest< int > > ireceive< int, long long >(const Comm< int > &comm, const ArrayRCP< long long > &recvBuffer, const int sourceRank)
void send< int, int >(const Comm< int > &comm, const int count, const int sendBuffer[], const int destRank)
void send< int, double >(const Comm< int > &comm, const int count, const double sendBuffer[], const int destRank)
void gather< int, int >(const int sendBuf[], const int sendCount, int recvBuf[], const int recvCount, const int root, const Comm< int > &comm)
void gather< int, long long >(const long long sendBuf[], const int sendCount, long long recvBuf[], const int recvCount, const int root, const Comm< int > &comm)
#define TEUCHOS_COMM_TIME_MONITOR(FUNCNAME)
void scatterv< int, float >(const float sendBuf[], const int sendCounts[], const int displs[], float recvBuf[], const int recvCount, const int root, const Comm< int > &comm)
void gatherv< int, unsigned long >(const unsigned long sendBuf[], const int sendCount, unsigned long recvBuf[], const int recvCounts[], const int displs[], const int root, const Comm< int > &comm)
void reduceAll< int, unsigned int >(const Comm< int > &comm, const EReductionType reductType, const int count, const unsigned int sendBuffer[], unsigned int globalReducts[])
void send< int, long long >(const Comm< int > &comm, const int count, const long long sendBuffer[], const int destRank)
void reduceAll< int, short >(const Comm< int > &comm, const EReductionType reductType, const int count, const short sendBuffer[], short globalReducts[])
void reduce< int, unsigned long long >(const unsigned long long sendBuf[], unsigned long long recvBuf[], const int count, const EReductionType reductType, const int root, const Comm< int > &comm)
void reduce< int, int >(const int sendBuf[], int recvBuf[], const int count, const EReductionType reductType, const int root, const Comm< int > &comm)
void reduceAll< int, double >(const Comm< int > &comm, const EReductionType reductType, const int count, const double sendBuffer[], double globalReducts[])
std::string toString(const HashSet< Key > &h)
void gatherv< int, unsigned long long >(const unsigned long long sendBuf[], const int sendCount, unsigned long long recvBuf[], const int recvCounts[], const int displs[], const int root, const Comm< int > &comm)
void gatherv< int, long >(const long sendBuf[], const int sendCount, long recvBuf[], const int recvCounts[], const int displs[], const int root, const Comm< int > &comm)
void reduceAll< int, int >(const Comm< int > &comm, const EReductionType reductType, const int count, const int sendBuffer[], int globalReducts[])
void reduceAll< int, unsigned long long >(const Comm< int > &comm, const EReductionType reductType, const int count, const unsigned long long sendBuffer[], unsigned long long globalReducts[])
void gatherv< int, unsigned int >(const unsigned int sendBuf[], const int sendCount, unsigned int recvBuf[], const int recvCounts[], const int displs[], const int root, const Comm< int > &comm)
RCP< Teuchos::CommRequest< int > > ireceive< int, unsigned int >(const Comm< int > &comm, const ArrayRCP< unsigned int > &recvBuffer, const int sourceRank)
void reduceAll< int, unsigned long >(const Comm< int > &comm, const EReductionType reductType, const int count, const unsigned long sendBuffer[], unsigned long globalReducts[])
RCP< Teuchos::CommRequest< int > > ireceive< int, int >(const Comm< int > &comm, const ArrayRCP< int > &recvBuffer, const int sourceRank)
RCP< Teuchos::CommRequest< int > > ireceive< int, unsigned long >(const Comm< int > &comm, const ArrayRCP< unsigned long > &recvBuffer, const int sourceRank)
void gatherv< int, double >(const double sendBuf[], const int sendCount, double recvBuf[], const int recvCounts[], const int displs[], const int root, const Comm< int > &comm)
RCP< Teuchos::CommRequest< int > > isend(const ArrayRCP< const double > &sendBuffer, const int destRank, const int tag, const Comm< int > &comm)
void reduceAll< int, float >(const Comm< int > &comm, const EReductionType reductType, const int count, const float sendBuffer[], float globalReducts[])
Declaration of Teuchos::Details::MpiTypeTraits (only if building with MPI)
RCP< Teuchos::CommRequest< int > > ireceive< int, long >(const Comm< int > &comm, const ArrayRCP< long > &recvBuffer, const int sourceRank)
void gather< int, short >(const short sendBuf[], const int sendCount, short recvBuf[], const int recvCount, const int root, const Comm< int > &comm)
void send< int, short >(const Comm< int > &comm, const int count, const short sendBuffer[], const int destRank)
void gather< int, unsigned long >(const unsigned long sendBuf[], const int sendCount, unsigned long recvBuf[], const int recvCount, const int root, const Comm< int > &comm)
void reduceAll< int, long long >(const Comm< int > &comm, const EReductionType reductType, const int count, const long long sendBuffer[], long long globalReducts[])
void send< int, unsigned long >(const Comm< int > &comm, const int count, const unsigned long sendBuffer[], const int destRank)
Reference-counted smart pointer for managing arrays.
void send< int, unsigned int >(const Comm< int > &comm, const int count, const unsigned int sendBuffer[], const int destRank)
void gatherv< int, float >(const float sendBuf[], const int sendCount, float recvBuf[], const int recvCounts[], const int displs[], const int root, const Comm< int > &comm)