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 
231 template<class T>
232 void
233 reduceImpl (const T sendBuf[],
234  T recvBuf[],
235  const int count,
236  const EReductionType reductType,
237  const int root,
238  const Comm<int>& comm)
239 {
240 #ifdef HAVE_TEUCHOS_MPI
241  using Teuchos::Details::MpiTypeTraits;
242 
243  // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
244  // SerialComm or an MpiComm. If it's something else, we fall back
245  // to the most general implementation.
246  const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
247  if (mpiComm == NULL) {
248  // Is it a SerialComm?
249  const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
250  if (serialComm == NULL) {
251  // We don't know what kind of Comm we have, so fall back to the
252  // most general implementation.
253  reduce<int, T> (sendBuf, recvBuf, count, reductType, root, comm);
254  }
255  else { // It's a SerialComm; there is only 1 process, so just copy.
256  std::copy (sendBuf, sendBuf + count, recvBuf);
257  }
258  } else { // It's an MpiComm. Invoke MPI directly.
259  MPI_Op rawMpiOp = ::Teuchos::Details::getMpiOpForEReductionType (reductType);
260  MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
261  T t;
262  MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
263  const int err = MPI_Reduce (const_cast<T*> (sendBuf), recvBuf, count,
264  rawMpiType, rawMpiOp, root, rawMpiComm);
266  (err != MPI_SUCCESS, std::runtime_error, "MPI_Reduce failed with the "
267  "following error: " << ::Teuchos::Details::getMpiErrorString (err));
268  }
269 #else
270  // We've built without MPI, so just assume it's a SerialComm and copy the data.
271  std::copy (sendBuf, sendBuf + count, recvBuf);
272 #endif // HAVE_TEUCHOS_MPI
273 }
274 
275 
283 template<class T>
284 void
285 gathervImpl (const T sendBuf[],
286  const int sendCount,
287  T recvBuf[],
288  const int recvCounts[],
289  const int displs[],
290  const int root,
291  const Comm<int>& comm)
292 {
293 #ifdef HAVE_TEUCHOS_MPI
294  using Teuchos::Details::MpiTypeTraits;
295 
296  // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
297  // SerialComm or an MpiComm. If it's something else, we fall back
298  // to the most general implementation.
299  const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
300  if (mpiComm == NULL) {
301  // Is it a SerialComm?
302  const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
303  if (serialComm == NULL) {
304  // We don't know what kind of Comm we have, so fall back to the
305  // most general implementation.
306  gatherv<int, T> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
307  }
308  else { // It's a SerialComm; there is only 1 process, so just copy.
310  recvCounts[0] > sendCount, std::invalid_argument,
311  "Teuchos::gatherv: If the input communicator contains only one "
312  "process, then you cannot receive more entries than you send. "
313  "You aim to receive " << recvCounts[0] << " entries, but to send "
314  << sendCount << " entries.");
315  // Serial communicator case: just copy. recvCounts[0] is the
316  // amount to receive, so it's the amount to copy. Start writing
317  // to recvbuf at the offset displs[0].
318  std::copy (sendBuf, sendBuf + recvCounts[0], recvBuf + displs[0]);
319  }
320  } else { // It's an MpiComm. Invoke MPI directly.
321  MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
322  T t;
323  MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
324  const int err = MPI_Gatherv (const_cast<T*> (sendBuf),
325  sendCount,
326  rawMpiType,
327  recvBuf,
328  const_cast<int*> (recvCounts),
329  const_cast<int*> (displs),
330  rawMpiType,
331  root,
332  rawMpiComm);
334  err != MPI_SUCCESS,
335  std::runtime_error,
336  "MPI_Gatherv failed with the following error: "
337  << ::Teuchos::Details::getMpiErrorString (err));
338  }
339 #else
340  // We've built without MPI, so just assume it's a SerialComm and copy the data.
342  recvCounts[0] > sendCount, std::invalid_argument,
343  "Teuchos::gatherv: If the input communicator contains only one "
344  "process, then you cannot receive more entries than you send. "
345  "You aim to receive " << recvCounts[0] << " entries, but to send "
346  << sendCount << " entries.");
347  // Serial communicator case: just copy. recvCounts[0] is the
348  // amount to receive, so it's the amount to copy. Start writing
349  // to recvbuf at the offset displs[0].
350  std::copy (sendBuf, sendBuf + recvCounts[0], recvBuf + displs[0]);
351 #endif // HAVE_TEUCHOS_MPI
352 }
353 
359 template<typename Packet>
360 RCP<Teuchos::CommRequest<int> >
361 ireceiveGeneral(const Comm<int>& comm,
362  const ArrayRCP<Packet> &recvBuffer,
363  const int sourceRank)
364 {
366  "Teuchos::ireceive<int, " << "," << TypeNameTraits<Packet>::name ()
367  << "> ( value type )"
368  );
369  ValueTypeSerializationBuffer<int, Packet>
370  charRecvBuffer (recvBuffer.size (), recvBuffer.getRawPtr ());
371  RCP<CommRequest<int> > commRequest =
372  comm.ireceive (charRecvBuffer.getCharBufferView (), sourceRank);
373  set_extra_data (recvBuffer, "buffer", inOutArg (commRequest));
374  return commRequest;
375 }
376 
379 template<typename Packet>
380 RCP<Teuchos::CommRequest<int> >
381 ireceiveGeneral (const ArrayRCP<Packet> &recvBuffer,
382  const int sourceRank,
383  const int tag,
384  const Comm<int>& comm)
385 {
387  "Teuchos::ireceive<int, " << "," << TypeNameTraits<Packet>::name ()
388  << "> ( value type )"
389  );
390  ValueTypeSerializationBuffer<int, Packet>
391  charRecvBuffer (recvBuffer.size (), recvBuffer.getRawPtr ());
392  RCP<CommRequest<int> > commRequest =
393  comm.ireceive (charRecvBuffer.getCharBufferView (), sourceRank, tag);
394  set_extra_data (recvBuffer, "buffer", inOutArg (commRequest));
395  return commRequest;
396 }
397 
410 template<class T>
411 RCP<CommRequest<int> >
412 ireceiveImpl (const Comm<int>& comm,
413  const ArrayRCP<T>& recvBuffer,
414  const int sourceRank)
415 {
416 #ifdef HAVE_TEUCHOS_MPI
417  using Teuchos::Details::MpiTypeTraits;
418 
419  // Even in an MPI build, Comm might be either a SerialComm or an
420  // MpiComm. If it's something else, we fall back to the most
421  // general implementation.
422  const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
423  if (mpiComm == NULL) {
424  // Is it a SerialComm?
425  const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
426  if (serialComm == NULL) {
427  // We don't know what kind of Comm we have, so fall back to the
428  // most general implementation.
429  return ireceiveGeneral<T> (comm, recvBuffer, sourceRank);
430  }
431  else { // SerialComm doesn't implement ireceive anyway.
433  true,
434  std::logic_error,
435  "ireceiveImpl: Not implemented for a serial communicator.");
436  }
437  }
438  else { // It's an MpiComm. Invoke MPI directly.
439  MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
440  T t;
441  MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
442  T* rawRecvBuf = recvBuffer.getRawPtr ();
443  const int count = as<int> (recvBuffer.size ());
444  const int tag = mpiComm->getTag ();
445  MPI_Request rawRequest = MPI_REQUEST_NULL;
446  const int err = MPI_Irecv (rawRecvBuf, count, rawType, sourceRank, tag,
447  rawComm, &rawRequest);
449  err != MPI_SUCCESS, std::runtime_error,
450  "MPI_Irecv failed with the following error: "
451  << ::Teuchos::Details::getMpiErrorString (err));
452 
453  ArrayRCP<const char> buf =
454  arcp_const_cast<const char> (arcp_reinterpret_cast<char> (recvBuffer));
455  RCP<Details::MpiCommRequest> req (new Details::MpiCommRequest (rawRequest, buf));
456  return rcp_implicit_cast<CommRequest<int> > (req);
457  }
458 #else
460  true,
461  std::logic_error,
462  "ireceiveImpl: Not implemented for a serial communicator.");
463 
464  // NOTE (mfh 15 Sep 2014): Most compilers have figured out that the
465  // return statement below is unreachable. Some older compilers
466  // might not realize this. That's why the return statement was put
467  // there, so that those compilers don't warn that this function
468  // doesn't return a value. If it's a choice between one warning and
469  // another, I would prefer the choice that produces less code and
470  // doesn't have unreachable code (which never gets tested).
471 
472  //return null; // Guard to avoid compiler warning about not returning a value.
473 #endif // HAVE_TEUCHOS_MPI
474 }
475 
478 template<class T>
479 RCP<CommRequest<int> >
480 ireceiveImpl (const ArrayRCP<T>& recvBuffer,
481  const int sourceRank,
482  const int tag,
483  const Comm<int>& comm)
484 {
485 #ifdef HAVE_TEUCHOS_MPI
486  using Teuchos::Details::MpiTypeTraits;
487 
488  // Even in an MPI build, Comm might be either a SerialComm or an
489  // MpiComm. If it's something else, we fall back to the most
490  // general implementation.
491  const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
492  if (mpiComm == NULL) {
493  // Is it a SerialComm?
494  const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
495  if (serialComm == NULL) {
496  // We don't know what kind of Comm we have, so fall back to the
497  // most general implementation.
498  return ireceiveGeneral<T> (recvBuffer, sourceRank, tag, comm);
499  }
500  else { // SerialComm doesn't implement ireceive anyway.
502  true,
503  std::logic_error,
504  "ireceiveImpl: Not implemented for a serial communicator.");
505  }
506  }
507  else { // It's an MpiComm. Invoke MPI directly.
508  MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
509  T t;
510  MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
511  T* rawRecvBuf = recvBuffer.getRawPtr ();
512  const int count = as<int> (recvBuffer.size ());
513  MPI_Request rawRequest = MPI_REQUEST_NULL;
514  const int err = MPI_Irecv (rawRecvBuf, count, rawType, sourceRank, tag,
515  rawComm, &rawRequest);
517  err != MPI_SUCCESS, std::runtime_error,
518  "MPI_Irecv failed with the following error: "
519  << ::Teuchos::Details::getMpiErrorString (err));
520 
521  ArrayRCP<const char> buf =
522  arcp_const_cast<const char> (arcp_reinterpret_cast<char> (recvBuffer));
523  RCP<Details::MpiCommRequest> req (new Details::MpiCommRequest (rawRequest, buf));
524  return rcp_implicit_cast<CommRequest<int> > (req);
525  }
526 #else
528  true,
529  std::logic_error,
530  "ireceiveImpl: Not implemented for a serial communicator.");
531 
532  return null; // Guard to avoid compiler warning about not returning a value.
533 #endif // HAVE_TEUCHOS_MPI
534 }
535 
541 template<class T>
542 void
543 sendGeneral (const Comm<int>& comm,
544  const int count,
545  const T sendBuffer[],
546  const int destRank)
547 {
549  "Teuchos::send<int, " << TypeNameTraits<T>::name () << ">");
550  ConstValueTypeSerializationBuffer<int,T> charSendBuffer (count, sendBuffer);
551  comm.send (charSendBuffer.getBytes (),
552  charSendBuffer.getCharBuffer (),
553  destRank);
554 }
555 
558 template<class T>
559 void
560 sendGeneral (const T sendBuffer[],
561  const int count,
562  const int destRank,
563  const int tag,
564  const Comm<int>& comm)
565 {
567  "Teuchos::send<int, " << TypeNameTraits<T>::name () << ">");
568  ConstValueTypeSerializationBuffer<int,T> charSendBuffer (count, sendBuffer);
569  comm.send (charSendBuffer.getBytes (),
570  charSendBuffer.getCharBuffer (),
571  destRank, tag);
572 }
573 
586 template<class T>
587 void
588 sendImpl (const Comm<int>& comm,
589  const int count,
590  const T sendBuffer[],
591  const int destRank)
592 {
593 #ifdef HAVE_TEUCHOS_MPI
594  using Teuchos::Details::MpiTypeTraits;
595 
596  // Even in an MPI build, Comm might be either a SerialComm or an
597  // MpiComm. If it's something else, we fall back to the most
598  // general implementation.
599  const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
600  if (mpiComm == NULL) {
601  // Is it a SerialComm?
602  const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
603  if (serialComm == NULL) {
604  // We don't know what kind of Comm we have, so fall back to the
605  // most general implementation.
606  sendGeneral<T> (comm, count, sendBuffer, destRank);
607  }
608  else { // SerialComm doesn't implement send correctly anyway.
610  true,
611  std::logic_error,
612  "sendImpl: Not implemented for a serial communicator.");
613  }
614  }
615  else { // It's an MpiComm. Invoke MPI directly.
616  MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
617  T t;
618  MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
619  T* rawBuf = const_cast<T*> (sendBuffer);
620  const int tag = mpiComm->getTag ();
621  const int err = MPI_Send (rawBuf, count, rawType, destRank, tag, rawComm);
623  err != MPI_SUCCESS,
624  std::runtime_error,
625  "MPI_Send failed with the following error: "
626  << ::Teuchos::Details::getMpiErrorString (err));
627  }
628 #else
630  true,
631  std::logic_error,
632  "sendImpl: Not implemented for a serial communicator.");
633 #endif // HAVE_TEUCHOS_MPI
634 }
635 
638 template<class T>
639 void
640 sendImpl (const T sendBuffer[],
641  const int count,
642  const int destRank,
643  const int tag,
644  const Comm<int>& comm)
645 {
646 #ifdef HAVE_TEUCHOS_MPI
647  using Teuchos::Details::MpiTypeTraits;
648 
649  // Even in an MPI build, Comm might be either a SerialComm or an
650  // MpiComm. If it's something else, we fall back to the most
651  // general implementation.
652  const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
653  if (mpiComm == NULL) {
654  // Is it a SerialComm?
655  const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
656  if (serialComm == NULL) {
657  // We don't know what kind of Comm we have, so fall back to the
658  // most general implementation.
659  sendGeneral<T> (sendBuffer, count, destRank, tag, comm);
660  }
661  else { // SerialComm doesn't implement send correctly anyway.
663  true,
664  std::logic_error,
665  "sendImpl: Not implemented for a serial communicator.");
666  }
667  }
668  else { // It's an MpiComm. Invoke MPI directly.
669  MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
670  T t;
671  MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
672  T* rawBuf = const_cast<T*> (sendBuffer);
673  const int err = MPI_Send (rawBuf, count, rawType, destRank, tag, rawComm);
675  err != MPI_SUCCESS,
676  std::runtime_error,
677  "MPI_Send failed with the following error: "
678  << ::Teuchos::Details::getMpiErrorString (err));
679  }
680 #else
682  true,
683  std::logic_error,
684  "sendImpl: Not implemented for a serial communicator.");
685 #endif // HAVE_TEUCHOS_MPI
686 }
687 
693 template<class T>
694 RCP<CommRequest<int> >
695 isendGeneral (const Comm<int>& comm,
696  const ArrayRCP<const T>& sendBuffer,
697  const int destRank)
698 {
700  "Teuchos::isend<int," << TypeNameTraits<T>::name () << ">");
701  ConstValueTypeSerializationBuffer<int, T>
702  charSendBuffer (sendBuffer.size (), sendBuffer.getRawPtr ());
703  RCP<CommRequest<int> > commRequest =
704  comm.isend (charSendBuffer.getCharBufferView (), destRank);
705  set_extra_data (sendBuffer, "buffer", inOutArg (commRequest));
706  return commRequest;
707 }
708 
715 template<class T>
716 RCP<CommRequest<int> >
717 isendGeneral (const ArrayRCP<const T>& sendBuffer,
718  const int destRank,
719  const int tag,
720  const Comm<int>& comm)
721 {
723  "Teuchos::isend<int," << TypeNameTraits<T>::name () << ">");
724  ConstValueTypeSerializationBuffer<int, T>
725  charSendBuffer (sendBuffer.size (), sendBuffer.getRawPtr ());
726  RCP<CommRequest<int> > commRequest =
727  comm.isend (charSendBuffer.getCharBufferView (), destRank, tag);
728  set_extra_data (sendBuffer, "buffer", inOutArg (commRequest));
729  return commRequest;
730 }
731 
734 template<class T>
735 RCP<Teuchos::CommRequest<int> >
736 isendImpl (const ArrayRCP<const T>& sendBuffer,
737  const int destRank,
738  const int tag,
739  const Comm<int>& comm)
740 {
741 #ifdef HAVE_TEUCHOS_MPI
742  using Teuchos::Details::MpiTypeTraits;
743 
744  // Even in an MPI build, Comm might be either a SerialComm or an
745  // MpiComm. If it's something else, we fall back to the most
746  // general implementation.
747  const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
748  if (mpiComm == NULL) {
749  // Is it a SerialComm?
750  const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
751  if (serialComm == NULL) {
752  // We don't know what kind of Comm we have, so fall back to the
753  // most general implementation.
754  return isendGeneral<T> (sendBuffer, destRank, tag, comm);
755  }
756  else { // SerialComm doesn't implement send correctly anyway.
758  true, std::logic_error,
759  "isendImpl: Not implemented for a serial communicator.");
760  }
761  }
762  else { // It's an MpiComm. Invoke MPI directly.
763  MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
764  T t;
765  MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
766  // MPI promises not to modify the send buffer; the const_cast
767  // merely ensures compatibilty with C89, which does not have a
768  // "const" keyword.
769  T* rawSendBuf = const_cast<T*> (sendBuffer.getRawPtr ());
770  const int count = as<int> (sendBuffer.size ());
771  MPI_Request rawRequest = MPI_REQUEST_NULL;
772  const int err = MPI_Isend (rawSendBuf, count, rawType, destRank, tag,
773  rawComm, &rawRequest);
775  err != MPI_SUCCESS,
776  std::runtime_error,
777  "MPI_Isend failed with the following error: "
778  << ::Teuchos::Details::getMpiErrorString (err));
779 
780  ArrayRCP<const char> buf = arcp_reinterpret_cast<const char> (sendBuffer);
781  RCP<Details::MpiCommRequest> req (new Details::MpiCommRequest (rawRequest, buf));
782  return rcp_implicit_cast<CommRequest<int> > (req);
783  }
784 #else
786  true,
787  std::logic_error,
788  "isendImpl: Not implemented for a serial communicator.");
789 #endif // HAVE_TEUCHOS_MPI
790 }
791 
792 } // namespace (anonymous)
793 
794 
795 // mfh 18 Oct 2012: Note on full template specializations
796 //
797 // To make Windows builds happy, declarations of full template
798 // specializations (as found in Teuchos_CommHelpers.hpp) must use the
799 // TEUCHOSCOMM_LIB_DLL_EXPORT macro. However, _definitions_ of the
800 // specializations (as found in this file) must _not_ use the macro.
801 // That's why we don't use that macro here.
802 
803 // amb See note in .hpp file.
804 #if 0
805 #ifdef HAVE_TEUCHOS_COMPLEX
806 // Specialization for Ordinal=int and Packet=std::complex<double>.
807 template<>
808 void
809 reduceAll<int, std::complex<double> > (const Comm<int>& comm,
810  const EReductionType reductType,
811  const int count,
812  const std::complex<double> sendBuffer[],
813  std::complex<double> globalReducts[])
814 {
816  "Teuchos::reduceAll<int, std::complex<double> > (" << count << ", "
817  << toString (reductType) << ")"
818  );
819  reduceAllImpl<std::complex<double> > (comm, reductType, count, sendBuffer, globalReducts);
820 }
821 
822 template<>
823 RCP<Teuchos::CommRequest<int> >
824 ireceive<int, std::complex<double> > (const Comm<int>& comm,
825  const ArrayRCP<std::complex<double> >& recvBuffer,
826  const int sourceRank)
827 {
828  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<double> >");
829  return ireceiveImpl<std::complex<double> > (comm, recvBuffer, sourceRank);
830 }
831 
832 template<>
833 RCP<Teuchos::CommRequest<int> >
834 ireceive<int, std::complex<double> > (const ArrayRCP<std::complex<double> >& recvBuffer,
835  const int sourceRank,
836  const int tag,
837  const Comm<int>& comm)
838 {
839  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<double> >");
840  return ireceiveImpl<std::complex<double> > (recvBuffer, sourceRank, tag, comm);
841 }
842 
843 template<>
844 void
845 send<int, std::complex<double> > (const Comm<int>& comm,
846  const int count,
847  const std::complex<double> sendBuffer[],
848  const int destRank)
849 {
850  sendImpl<std::complex<double> > (comm, count, sendBuffer, destRank);
851 }
852 
853 template<>
854 void
855 send<int, std::complex<double> > (const std::complex<double> sendBuffer[],
856  const int count,
857  const int destRank,
858  const int tag,
859  const Comm<int>& comm)
860 {
861  sendImpl<std::complex<double> > (sendBuffer, count, destRank, tag, comm);
862 }
863 
864 template<>
865 RCP<Teuchos::CommRequest<int> >
866 isend (const ArrayRCP<const std::complex<double> >& sendBuffer,
867  const int destRank,
868  const int tag,
869  const Comm<int>& comm)
870 {
871  return isendImpl<std::complex<double> > (sendBuffer, destRank, tag, comm);
872 }
873 
874 // Specialization for Ordinal=int and Packet=std::complex<float>.
875 template<>
876 void
877 reduceAll<int, std::complex<float> > (const Comm<int>& comm,
878  const EReductionType reductType,
879  const int count,
880  const std::complex<float> sendBuffer[],
881  std::complex<float> globalReducts[])
882 {
884  "Teuchos::reduceAll<int, std::complex<float> > (" << count << ", "
885  << toString (reductType) << ")"
886  );
887  reduceAllImpl<std::complex<float> > (comm, reductType, count, sendBuffer, globalReducts);
888 }
889 
890 template<>
891 RCP<Teuchos::CommRequest<int> >
892 ireceive<int, std::complex<float> > (const Comm<int>& comm,
893  const ArrayRCP<std::complex<float> >& recvBuffer,
894  const int sourceRank)
895 {
896  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<float> >");
897  return ireceiveImpl<std::complex<float> > (comm, recvBuffer, sourceRank);
898 }
899 
900 template<>
901 RCP<Teuchos::CommRequest<int> >
902 ireceive<int, std::complex<float> > (const ArrayRCP<std::complex<float> >& recvBuffer,
903  const int sourceRank,
904  const int tag,
905  const Comm<int>& comm)
906 {
907  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<float> >");
908  return ireceiveImpl<std::complex<float> > (recvBuffer, sourceRank, tag, comm);
909 }
910 
911 template<>
912 void
913 send<int, std::complex<float> > (const Comm<int>& comm,
914  const int count,
915  const std::complex<float> sendBuffer[],
916  const int destRank)
917 {
918  return sendImpl<std::complex<float> > (comm, count, sendBuffer, destRank);
919 }
920 
921 template<>
922 void
923 send<int, std::complex<float> > (const std::complex<float> sendBuffer[],
924  const int count,
925  const int destRank,
926  const int tag,
927  const Comm<int>& comm)
928 {
929  return sendImpl<std::complex<float> > (sendBuffer, count, destRank, tag, comm);
930 }
931 
932 template<>
933 RCP<Teuchos::CommRequest<int> >
934 isend (const ArrayRCP<const std::complex<float> >& sendBuffer,
935  const int destRank,
936  const int tag,
937  const Comm<int>& comm)
938 {
939  return isendImpl<std::complex<float> > (sendBuffer, destRank, tag, comm);
940 }
941 #endif // HAVE_TEUCHOS_COMPLEX
942 #endif // if 0
943 
944 
945 // Specialization for Ordinal=int and Packet=double.
946 template<>
947 void
949  const EReductionType reductType,
950  const int count,
951  const double sendBuffer[],
952  double globalReducts[])
953 {
955  "Teuchos::reduceAll<int, double> (" << count << ", "
956  << toString (reductType) << ")"
957  );
958  reduceAllImpl<double> (comm, reductType, count, sendBuffer, globalReducts);
959 }
960 
961 template<>
962 RCP<Teuchos::CommRequest<int> >
964  const ArrayRCP<double>& recvBuffer,
965  const int sourceRank)
966 {
967  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, double>");
968  return ireceiveImpl<double> (comm, recvBuffer, sourceRank);
969 }
970 
971 template<>
972 RCP<Teuchos::CommRequest<int> >
974  const int sourceRank,
975  const int tag,
976  const Comm<int>& comm)
977 {
978  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, double>");
979  return ireceiveImpl<double> (recvBuffer, sourceRank, tag, comm);
980 }
981 
982 template<>
983 void
985  const int count,
986  const double sendBuffer[],
987  const int destRank)
988 {
989  return sendImpl<double> (comm, count, sendBuffer, destRank);
990 }
991 
992 template<>
993 void
994 send<int, double> (const double sendBuffer[],
995  const int count,
996  const int destRank,
997  const int tag,
998  const Comm<int>& comm)
999 {
1000  return sendImpl<double> (sendBuffer, count, destRank, tag, comm);
1001 }
1002 
1003 template<>
1004 RCP<Teuchos::CommRequest<int> >
1005 isend (const ArrayRCP<const double>& sendBuffer,
1006  const int destRank,
1007  const int tag,
1008  const Comm<int>& comm)
1009 {
1010  return isendImpl<double> (sendBuffer, destRank, tag, comm);
1011 }
1012 
1013 // Specialization for Ordinal=int and Packet=float.
1014 template<>
1015 void
1017  const EReductionType reductType,
1018  const int count,
1019  const float sendBuffer[],
1020  float globalReducts[])
1021 {
1023  "Teuchos::reduceAll<int, float> (" << count << ", "
1024  << toString (reductType) << ")"
1025  );
1026  reduceAllImpl<float> (comm, reductType, count, sendBuffer, globalReducts);
1027 }
1028 
1029 template<>
1030 RCP<Teuchos::CommRequest<int> >
1032  const ArrayRCP<float>& recvBuffer,
1033  const int sourceRank)
1034 {
1035  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, float>");
1036  return ireceiveImpl<float> (comm, recvBuffer, sourceRank);
1037 }
1038 
1039 template<>
1040 RCP<Teuchos::CommRequest<int> >
1042  const int sourceRank,
1043  const int tag,
1044  const Comm<int>& comm)
1045 {
1046  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, float>");
1047  return ireceiveImpl<float> (recvBuffer, sourceRank, tag, comm);
1048 }
1049 
1050 template<>
1051 void
1053  const int count,
1054  const float sendBuffer[],
1055  const int destRank)
1056 {
1057  return sendImpl<float> (comm, count, sendBuffer, destRank);
1058 }
1059 
1060 template<>
1061 void
1062 send<int, float> (const float sendBuffer[],
1063  const int count,
1064  const int destRank,
1065  const int tag,
1066  const Comm<int>& comm)
1067 {
1068  return sendImpl<float> (sendBuffer, count, destRank, tag, comm);
1069 }
1070 
1071 template<>
1072 RCP<Teuchos::CommRequest<int> >
1073 isend (const ArrayRCP<const float>& sendBuffer,
1074  const int destRank,
1075  const int tag,
1076  const Comm<int>& comm)
1077 {
1078  return isendImpl<float> (sendBuffer, destRank, tag, comm);
1079 }
1080 
1081 
1082 // Specialization for Ordinal=int and Packet=long long.
1083 template<>
1084 void
1085 gather<int, long long> (const long long sendBuf[],
1086  const int sendCount,
1087  long long recvBuf[],
1088  const int recvCount,
1089  const int root,
1090  const Comm<int>& comm)
1091 {
1092  gatherImpl<long long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1093 }
1094 
1095 template<>
1096 void
1097 gatherv<int, long long> (const long long sendBuf[],
1098  const int sendCount,
1099  long long recvBuf[],
1100  const int recvCounts[],
1101  const int displs[],
1102  const int root,
1103  const Comm<int>& comm)
1104 {
1105  gathervImpl<long long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1106 }
1107 
1108 template<>
1109 void
1111  const EReductionType reductType,
1112  const int count,
1113  const long long sendBuffer[],
1114  long long globalReducts[])
1115 {
1117  "Teuchos::reduceAll<int, long long> (" << count << ", "
1118  << toString (reductType) << ")"
1119  );
1120  reduceAllImpl<long long> (comm, reductType, count, sendBuffer, globalReducts);
1121 }
1122 
1123 template<>
1124 RCP<Teuchos::CommRequest<int> >
1126  const ArrayRCP<long long>& recvBuffer,
1127  const int sourceRank)
1128 {
1129  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long long>");
1130  return ireceiveImpl<long long> (comm, recvBuffer, sourceRank);
1131 }
1132 
1133 template<>
1134 RCP<Teuchos::CommRequest<int> >
1136  const int sourceRank,
1137  const int tag,
1138  const Comm<int>& comm)
1139 {
1140  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long long>");
1141  return ireceiveImpl<long long> (recvBuffer, sourceRank, tag, comm);
1142 }
1143 
1144 template<>
1145 void
1147  const int count,
1148  const long long sendBuffer[],
1149  const int destRank)
1150 {
1151  return sendImpl<long long> (comm, count, sendBuffer, destRank);
1152 }
1153 
1154 template<>
1155 void
1156 send<int, long long> (const long long sendBuffer[],
1157  const int count,
1158  const int destRank,
1159  const int tag,
1160  const Comm<int>& comm)
1161 {
1162  return sendImpl<long long> (sendBuffer, count, destRank, tag, comm);
1163 }
1164 
1165 template<>
1166 RCP<Teuchos::CommRequest<int> >
1168  const int destRank,
1169  const int tag,
1170  const Comm<int>& comm)
1171 {
1172  return isendImpl<long long> (sendBuffer, destRank, tag, comm);
1173 }
1174 
1175 // Specialization for Ordinal=int and Packet=unsigned long long.
1176 template<>
1177 void
1178 gather<int, unsigned long long> (const unsigned long long sendBuf[],
1179  const int sendCount,
1180  unsigned long long recvBuf[],
1181  const int recvCount,
1182  const int root,
1183  const Comm<int>& comm)
1184 {
1185  gatherImpl<unsigned long long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1186 }
1187 
1188 template<>
1189 void
1190 gatherv<int, unsigned long long> (const unsigned long long sendBuf[],
1191  const int sendCount,
1192  unsigned long long recvBuf[],
1193  const int recvCounts[],
1194  const int displs[],
1195  const int root,
1196  const Comm<int>& comm)
1197 {
1198  gathervImpl<unsigned long long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1199 }
1200 
1201 template<>
1202 void
1204  const EReductionType reductType,
1205  const int count,
1206  const unsigned long long sendBuffer[],
1207  unsigned long long globalReducts[])
1208 {
1210  "Teuchos::reduceAll<int, unsigned long long> (" << count << ", "
1211  << toString (reductType) << ")"
1212  );
1213  reduceAllImpl<unsigned long long> (comm, reductType, count, sendBuffer, globalReducts);
1214 }
1215 
1216 template<>
1217 RCP<Teuchos::CommRequest<int> >
1219  const ArrayRCP<unsigned long long>& recvBuffer,
1220  const int sourceRank)
1221 {
1222  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long long>");
1223  return ireceiveImpl<unsigned long long> (comm, recvBuffer, sourceRank);
1224 }
1225 
1226 template<>
1227 RCP<Teuchos::CommRequest<int> >
1229  const int sourceRank,
1230  const int tag,
1231  const Comm<int>& comm)
1232 {
1233  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long long>");
1234  return ireceiveImpl<unsigned long long> (recvBuffer, sourceRank, tag, comm);
1235 }
1236 
1237 template<>
1238 void
1240  const int count,
1241  const unsigned long long sendBuffer[],
1242  const int destRank)
1243 {
1244  return sendImpl<unsigned long long> (comm, count, sendBuffer, destRank);
1245 }
1246 
1247 template<>
1248 void
1249 send<int, unsigned long long> (const unsigned long long sendBuffer[],
1250  const int count,
1251  const int destRank,
1252  const int tag,
1253  const Comm<int>& comm)
1254 {
1255  return sendImpl<unsigned long long> (sendBuffer, count, destRank, tag, comm);
1256 }
1257 
1258 template<>
1259 RCP<Teuchos::CommRequest<int> >
1261  const int destRank,
1262  const int tag,
1263  const Comm<int>& comm)
1264 {
1265  return isendImpl<unsigned long long> (sendBuffer, destRank, tag, comm);
1266 }
1267 
1268 
1269 // Specialization for Ordinal=int and Packet=long.
1270 template<>
1271 void
1272 gather<int, long> (const long sendBuf[],
1273  const int sendCount,
1274  long recvBuf[],
1275  const int recvCount,
1276  const int root,
1277  const Comm<int>& comm)
1278 {
1279  gatherImpl<long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1280 }
1281 
1282 template<>
1283 void
1284 gatherv<int, long> (const long sendBuf[],
1285  const int sendCount,
1286  long recvBuf[],
1287  const int recvCounts[],
1288  const int displs[],
1289  const int root,
1290  const Comm<int>& comm)
1291 {
1292  gathervImpl<long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1293 }
1294 
1295 template<>
1296 void
1298  const EReductionType reductType,
1299  const int count,
1300  const long sendBuffer[],
1301  long globalReducts[])
1302 {
1304  "Teuchos::reduceAll<int, long> (" << count << ", "
1305  << toString (reductType) << ")"
1306  );
1307  reduceAllImpl<long> (comm, reductType, count, sendBuffer, globalReducts);
1308 }
1309 
1310 template<>
1311 RCP<Teuchos::CommRequest<int> >
1313  const ArrayRCP<long>& recvBuffer,
1314  const int sourceRank)
1315 {
1316  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long>");
1317  return ireceiveImpl<long> (comm, recvBuffer, sourceRank);
1318 }
1319 
1320 template<>
1321 RCP<Teuchos::CommRequest<int> >
1323  const int sourceRank,
1324  const int tag,
1325  const Comm<int>& comm)
1326 {
1327  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long>");
1328  return ireceiveImpl<long> (recvBuffer, sourceRank, tag, comm);
1329 }
1330 
1331 template<>
1332 void
1334  const int count,
1335  const long sendBuffer[],
1336  const int destRank)
1337 {
1338  return sendImpl<long> (comm, count, sendBuffer, destRank);
1339 }
1340 
1341 template<>
1342 void
1343 send<int, long> (const long sendBuffer[],
1344  const int count,
1345  const int destRank,
1346  const int tag,
1347  const Comm<int>& comm)
1348 {
1349  return sendImpl<long> (sendBuffer, count, destRank, tag, comm);
1350 }
1351 
1352 template<>
1353 RCP<Teuchos::CommRequest<int> >
1354 isend (const ArrayRCP<const long>& sendBuffer,
1355  const int destRank,
1356  const int tag,
1357  const Comm<int>& comm)
1358 {
1359  return isendImpl<long> (sendBuffer, destRank, tag, comm);
1360 }
1361 
1362 
1363 // Specialization for Ordinal=int and Packet=unsigned long.
1364 template<>
1365 void
1366 gather<int, unsigned long> (const unsigned long sendBuf[],
1367  const int sendCount,
1368  unsigned long recvBuf[],
1369  const int recvCount,
1370  const int root,
1371  const Comm<int>& comm)
1372 {
1373  gatherImpl<unsigned long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1374 }
1375 
1376 template<>
1377 void
1378 gatherv<int, unsigned long> (const unsigned long sendBuf[],
1379  const int sendCount,
1380  unsigned long recvBuf[],
1381  const int recvCounts[],
1382  const int displs[],
1383  const int root,
1384  const Comm<int>& comm)
1385 {
1386  gathervImpl<unsigned long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1387 }
1388 
1389 template<>
1390 void
1392  const EReductionType reductType,
1393  const int count,
1394  const unsigned long sendBuffer[],
1395  unsigned long globalReducts[])
1396 {
1398  "Teuchos::reduceAll<int, unsigned long> (" << count << ", "
1399  << toString (reductType) << ")"
1400  );
1401  reduceAllImpl<unsigned long> (comm, reductType, count, sendBuffer, globalReducts);
1402 }
1403 
1404 template<>
1405 RCP<Teuchos::CommRequest<int> >
1407  const ArrayRCP<unsigned long>& recvBuffer,
1408  const int sourceRank)
1409 {
1410  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long>");
1411  return ireceiveImpl<unsigned long> (comm, recvBuffer, sourceRank);
1412 }
1413 
1414 template<>
1415 RCP<Teuchos::CommRequest<int> >
1417  const int sourceRank,
1418  const int tag,
1419  const Comm<int>& comm)
1420 {
1421  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long>");
1422  return ireceiveImpl<unsigned long> (recvBuffer, sourceRank, tag, comm);
1423 }
1424 
1425 template<>
1426 void
1428  const int count,
1429  const unsigned long sendBuffer[],
1430  const int destRank)
1431 {
1432  return sendImpl<unsigned long> (comm, count, sendBuffer, destRank);
1433 }
1434 
1435 template<>
1436 void
1437 send<int, unsigned long> (const unsigned long sendBuffer[],
1438  const int count,
1439  const int destRank,
1440  const int tag,
1441  const Comm<int>& comm)
1442 {
1443  return sendImpl<unsigned long> (sendBuffer, count, destRank, tag, comm);
1444 }
1445 
1446 template<>
1447 RCP<Teuchos::CommRequest<int> >
1449  const int destRank,
1450  const int tag,
1451  const Comm<int>& comm)
1452 {
1453  return isendImpl<unsigned long> (sendBuffer, destRank, tag, comm);
1454 }
1455 
1456 // Specialization for Ordinal=int and Packet=int.
1457 template<>
1458 void
1459 gather<int, int> (const int sendBuf[],
1460  const int sendCount,
1461  int recvBuf[],
1462  const int recvCount,
1463  const int root,
1464  const Comm<int>& comm)
1465 {
1466  gatherImpl<int> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1467 }
1468 
1469 template<>
1470 void
1471 gatherv<int, int> (const int sendBuf[],
1472  const int sendCount,
1473  int recvBuf[],
1474  const int recvCounts[],
1475  const int displs[],
1476  const int root,
1477  const Comm<int>& comm)
1478 {
1479  gathervImpl<int> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1480 }
1481 
1482 template<>
1483 void
1484 scatter<int, int> (const int sendBuf[],
1485  const int sendCount,
1486  int recvBuf[],
1487  const int recvCount,
1488  const int root,
1489  const Comm<int>& comm)
1490 {
1491  scatterImpl<int> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1492 }
1493 
1494 template<>
1495 void
1496 reduce<int, int> (const int sendBuf[],
1497  int recvBuf[],
1498  const int count,
1499  const EReductionType reductType,
1500  const int root,
1501  const Comm<int>& comm)
1502 {
1504  ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1505  << ")");
1506  reduceImpl<int> (sendBuf, recvBuf, count, reductType, root, comm);
1507 }
1508 template<>
1509 void
1510 reduce<int, long> (const long sendBuf[],
1511  long recvBuf[],
1512  const int count,
1513  const EReductionType reductType,
1514  const int root,
1515  const Comm<int>& comm)
1516 {
1518  ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1519  << ")");
1520  reduceImpl<long> (sendBuf, recvBuf, count, reductType, root, comm);
1521 }
1522 
1523 template<>
1524 void
1525 reduce<int, unsigned long> (const unsigned long sendBuf[],
1526  unsigned long recvBuf[],
1527  const int count,
1528  const EReductionType reductType,
1529  const int root,
1530  const Comm<int>& comm)
1531 {
1533  ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1534  << ")");
1535  reduceImpl<unsigned long> (sendBuf, recvBuf, count, reductType, root, comm);
1536 }
1537 
1538 template<>
1539 void
1540 reduce<int, unsigned long long > (const unsigned long long sendBuf[],
1541  unsigned long long recvBuf[],
1542  const int count,
1543  const EReductionType reductType,
1544  const int root,
1545  const Comm<int>& comm)
1546 {
1548  ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1549  << ")");
1550  reduceImpl<unsigned long long> (sendBuf, recvBuf, count, reductType, root, comm);
1551 }
1552 
1553 template<>
1554 void
1555 reduce<int, double> (const double sendBuf[],
1556  double recvBuf[],
1557  const int count,
1558  const EReductionType reductType,
1559  const int root,
1560  const Comm<int>& comm)
1561 {
1563  ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1564  << ")");
1565  reduceImpl<double> (sendBuf, recvBuf, count, reductType, root, comm);
1566 }
1567 template<>
1568 void
1570  const EReductionType reductType,
1571  const int count,
1572  const int sendBuffer[],
1573  int globalReducts[])
1574 {
1576  "Teuchos::reduceAll<int, int> (" << count << ", "
1577  << toString (reductType) << ")"
1578  );
1579  reduceAllImpl<int> (comm, reductType, count, sendBuffer, globalReducts);
1580 }
1581 
1582 template<>
1583 RCP<Teuchos::CommRequest<int> >
1585  const ArrayRCP<int>& recvBuffer,
1586  const int sourceRank)
1587 {
1588  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, int>");
1589  return ireceiveImpl<int> (comm, recvBuffer, sourceRank);
1590 }
1591 
1592 template<>
1593 RCP<Teuchos::CommRequest<int> >
1595  const int sourceRank,
1596  const int tag,
1597  const Comm<int>& comm)
1598 {
1599  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, int>");
1600  return ireceiveImpl<int> (recvBuffer, sourceRank, tag, comm);
1601 }
1602 
1603 template<>
1604 void
1606  const int count,
1607  const int sendBuffer[],
1608  const int destRank)
1609 {
1610  return sendImpl<int> (comm, count, sendBuffer, destRank);
1611 }
1612 
1613 template<>
1614 void
1615 send<int, int> (const int sendBuffer[],
1616  const int count,
1617  const int destRank,
1618  const int tag,
1619  const Comm<int>& comm)
1620 {
1621  return sendImpl<int> (sendBuffer, count, destRank, tag, comm);
1622 }
1623 
1624 template<>
1625 RCP<Teuchos::CommRequest<int> >
1626 isend (const ArrayRCP<const int>& sendBuffer,
1627  const int destRank,
1628  const int tag,
1629  const Comm<int>& comm)
1630 {
1631  return isendImpl<int> (sendBuffer, destRank, tag, comm);
1632 }
1633 
1634 // Specialization for Ordinal=int and Packet=unsigned int.
1635 template<>
1636 void
1637 gather<int, unsigned int> (const unsigned int sendBuf[],
1638  const int sendCount,
1639  unsigned int recvBuf[],
1640  const int recvCount,
1641  const int root,
1642  const Comm<int>& comm)
1643 {
1644  gatherImpl<unsigned int> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1645 }
1646 
1647 template<>
1648 void
1649 gatherv<int, unsigned int> (const unsigned int sendBuf[],
1650  const int sendCount,
1651  unsigned int recvBuf[],
1652  const int recvCounts[],
1653  const int displs[],
1654  const int root,
1655  const Comm<int>& comm)
1656 {
1657  gathervImpl<unsigned int> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1658 }
1659 
1660 template<>
1661 void
1663  const EReductionType reductType,
1664  const int count,
1665  const unsigned int sendBuffer[],
1666  unsigned int globalReducts[])
1667 {
1669  "Teuchos::reduceAll<int, unsigned int> (" << count << ", "
1670  << toString (reductType) << ")"
1671  );
1672  reduceAllImpl<unsigned int> (comm, reductType, count, sendBuffer, globalReducts);
1673 }
1674 
1675 template<>
1676 RCP<Teuchos::CommRequest<int> >
1678  const ArrayRCP<unsigned int>& recvBuffer,
1679  const int sourceRank)
1680 {
1681  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned int>");
1682  return ireceiveImpl<unsigned int> (comm, recvBuffer, sourceRank);
1683 }
1684 
1685 template<>
1686 RCP<Teuchos::CommRequest<int> >
1688  const int sourceRank,
1689  const int tag,
1690  const Comm<int>& comm)
1691 {
1692  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned int>");
1693  return ireceiveImpl<unsigned int> (recvBuffer, sourceRank, tag, comm);
1694 }
1695 
1696 template<>
1697 void
1699  const int count,
1700  const unsigned int sendBuffer[],
1701  const int destRank)
1702 {
1703  return sendImpl<unsigned int> (comm, count, sendBuffer, destRank);
1704 }
1705 
1706 template<>
1707 void
1708 send<int, unsigned int> (const unsigned int sendBuffer[],
1709  const int count,
1710  const int destRank,
1711  const int tag,
1712  const Comm<int>& comm)
1713 {
1714  return sendImpl<unsigned int> (sendBuffer, count, destRank, tag, comm);
1715 }
1716 
1717 template<>
1718 RCP<Teuchos::CommRequest<int> >
1720  const int destRank,
1721  const int tag,
1722  const Comm<int>& comm)
1723 {
1724  return isendImpl<unsigned int> (sendBuffer, destRank, tag, comm);
1725 }
1726 
1727 
1728 // Specialization for Ordinal=int and Packet=short.
1729 template<>
1730 void
1731 gather<int, short> (const short sendBuf[],
1732  const int sendCount,
1733  short recvBuf[],
1734  const int recvCount,
1735  const int root,
1736  const Comm<int>& comm)
1737 {
1738  gatherImpl<short> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1739 }
1740 
1741 template<>
1742 void
1743 gatherv<int, short> (const short sendBuf[],
1744  const int sendCount,
1745  short recvBuf[],
1746  const int recvCounts[],
1747  const int displs[],
1748  const int root,
1749  const Comm<int>& comm)
1750 {
1751  gathervImpl<short> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1752 }
1753 
1754 template<>
1755 void
1757  const EReductionType reductType,
1758  const int count,
1759  const short sendBuffer[],
1760  short globalReducts[])
1761 {
1763  "Teuchos::reduceAll<int, short> (" << count << ", "
1764  << toString (reductType) << ")"
1765  );
1766  reduceAllImpl<short> (comm, reductType, count, sendBuffer, globalReducts);
1767 }
1768 
1769 template<>
1770 RCP<Teuchos::CommRequest<int> >
1772  const ArrayRCP<short>& recvBuffer,
1773  const int sourceRank)
1774 {
1775  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, short>");
1776  return ireceiveImpl<short> (comm, recvBuffer, sourceRank);
1777 }
1778 
1779 template<>
1780 RCP<Teuchos::CommRequest<int> >
1782  const int sourceRank,
1783  const int tag,
1784  const Comm<int>& comm)
1785 {
1786  TEUCHOS_COMM_TIME_MONITOR("ireceive<int, short>");
1787  return ireceiveImpl<short> (recvBuffer, sourceRank, tag, comm);
1788 }
1789 
1790 template<>
1791 void
1793  const int count,
1794  const short sendBuffer[],
1795  const int destRank)
1796 {
1797  return sendImpl<short> (comm, count, sendBuffer, destRank);
1798 }
1799 
1800 template<>
1801 void
1802 send<int, short> (const short sendBuffer[],
1803  const int count,
1804  const int destRank,
1805  const int tag,
1806  const Comm<int>& comm)
1807 {
1808  return sendImpl<short> (sendBuffer, count, destRank, tag, comm);
1809 }
1810 
1811 template<>
1812 RCP<Teuchos::CommRequest<int> >
1813 isend (const ArrayRCP<const short>& sendBuffer,
1814  const int destRank,
1815  const int tag,
1816  const Comm<int>& comm)
1817 {
1818  return isendImpl<short> (sendBuffer, destRank, tag, comm);
1819 }
1820 
1821 // mfh 18 Oct 2012: The specialization for Packet=char seems to be
1822 // causing problems such as the following:
1823 //
1824 // http://testing.sandia.gov/cdash/testDetails.php?test=9909246&build=747699
1825 //
1826 // I am disabling it for now. This should revert back to the old
1827 // behavior for Packet=char. That should fix the Tpetra errors, since
1828 // many Tpetra objects inherit from DistObject<char, ...>.
1829 #if 0
1830 // Specialization for Ordinal=int and Packet=char.
1831 template<>
1832 void
1833 reduceAll<int, char> (const Comm<int>& comm,
1834  const EReductionType reductType,
1835  const int count,
1836  const char sendBuffer[],
1837  char globalReducts[])
1838 {
1840  "Teuchos::reduceAll<int, char> (" << count << ", "
1841  << toString (reductType) << ")"
1842  );
1843  reduceAllImpl<char> (comm, reductType, count, sendBuffer, globalReducts);
1844 }
1845 #endif // 0
1846 
1847 } // 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 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 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)
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)