Teuchos - Trilinos Tools Package Version of the Day
Loading...
Searching...
No Matches
Teuchos_CommHelpers.cpp
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
12# include "Teuchos_Details_MpiCommRequest.hpp"
14#endif // HAVE_TEUCHOS_MPI
15#ifdef HAVE_TEUCHOSCORE_CXX11
16# include <memory>
17#endif
18
19namespace Teuchos {
20
21#ifdef HAVE_TEUCHOS_MPI
22namespace Details {
23
24std::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
43namespace { // (anonymous)
44
45template<class T>
46void
47alltoAllImpl (const T sendBuf[],
48 const int sendCount,
49 T recvBuf[],
50 const int recvCount,
51 const Comm<int>& comm)
52{
53#ifdef HAVE_TEUCHOS_MPI
54 using Teuchos::Details::MpiTypeTraits;
55
56 // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
57 // SerialComm or an MpiComm. If it's something else, we fall back
58 // to the most general implementation.
59 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
60 if (mpiComm == NULL) {
61 // Is it a SerialComm?
62 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
63 if (serialComm == NULL) {
64 // We don't know what kind of Comm we have, so fall back to the
65 // most general implementation.
66 alltoAll (sendBuf, sendCount, recvBuf, recvCount, comm);
67 }
68 else { // It's a SerialComm; there is only 1 process, so just copy.
69 std::copy (sendBuf, sendBuf + sendCount, recvBuf);
70 }
71 } else { // It's an MpiComm. Invoke MPI directly.
72 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
73 T t;
74 MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
75
76 int err = MPI_SUCCESS;
77 err = MPI_Alltoall(sendBuf, sendCount, rawMpiType,
78 recvBuf, recvCount, rawMpiType,
79 rawMpiComm);
80
82 err != MPI_SUCCESS,
83 std::runtime_error,
84 "MPI_Alltoall failed with the following error: "
85 << ::Teuchos::Details::getMpiErrorString (err));
86 }
87#else
88 // We've built without MPI, so just assume it's a SerialComm and copy the data.
89 std::copy (sendBuf, sendBuf + sendCount, recvBuf);
90#endif // HAVE_TEUCHOS_MPI
91}
92
93template<class T>
94void
95alltoAllvImpl (const T sendBuf[],
96 const int sendCounts[],
97 const int sendDispls[],
98 T recvBuf[],
99 const int recvCounts[],
100 const int recvDispls[],
101 const Comm<int>& comm)
102{
103#ifdef HAVE_TEUCHOS_MPI
104 using Teuchos::Details::MpiTypeTraits;
105
106 // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
107 // SerialComm or an MpiComm. If it's something else, we fall back
108 // to the most general implementation.
109 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
110 if (mpiComm == NULL) {
111 // Is it a SerialComm?
112 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
113 if (serialComm == NULL) {
114 // We don't know what kind of Comm we have, so fall back to the
115 // most general implementation.
116 alltoAllv (sendBuf, sendCounts, sendDispls, recvBuf, recvCounts, recvDispls, comm);
117 }
118 else { // It's a SerialComm; there is only 1 process, so just copy.
119 std::copy (sendBuf, sendBuf + sendCounts[0], recvBuf);
120 }
121 } else { // It's an MpiComm. Invoke MPI directly.
122 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
123 T t;
124 MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
125
126 int err = MPI_SUCCESS;
127 err = MPI_Alltoallv(sendBuf, sendCounts, sendDispls, rawMpiType,
128 recvBuf, recvCounts, recvDispls, rawMpiType,
129 rawMpiComm);
130
132 err != MPI_SUCCESS,
133 std::runtime_error,
134 "MPI_Alltoallv failed with the following error: "
135 << ::Teuchos::Details::getMpiErrorString (err));
136 }
137#else
138 // We've built without MPI, so just assume it's a SerialComm and copy the data.
139 std::copy (sendBuf, sendBuf + sendCounts[0], recvBuf);
140#endif
141}
142
150template<class T>
151void
152reduceAllImpl (const Comm<int>& comm,
153 const EReductionType reductType,
154 const int count,
155 const T sendBuffer[],
156 T globalReducts[])
157{
158#ifdef HAVE_TEUCHOS_MPI
159 using Teuchos::Details::MpiTypeTraits;
160
161 // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
162 // SerialComm or an MpiComm. If it's something else, we fall back
163 // to the most general implementation.
164 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
165 if (mpiComm == NULL) {
166 // Is it a SerialComm?
167 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
168 if (serialComm == NULL) {
169 // We don't know what kind of Comm we have, so fall back to the
170 // most general implementation.
171#ifdef HAVE_TEUCHOSCORE_CXX11
172 std::unique_ptr<ValueTypeReductionOp<int, T> >
173#else
174 std::auto_ptr<ValueTypeReductionOp<int, T> >
175#endif
176 reductOp (createOp<int, T> (reductType));
177 reduceAll (comm, *reductOp, count, sendBuffer, globalReducts);
178 }
179 else { // It's a SerialComm; there is only 1 process, so just copy.
180 std::copy (sendBuffer, sendBuffer + count, globalReducts);
181 }
182 } else { // It's an MpiComm. Invoke MPI directly.
183 MPI_Op rawMpiOp = ::Teuchos::Details::getMpiOpForEReductionType (reductType);
184 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
185 T t;
186 MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
187
188 int err = MPI_SUCCESS;
189 if (sendBuffer == globalReducts) {
190 // NOTE (mfh 31 May 2017) This is only safe if the communicator
191 // is NOT an intercomm. The usual case is that communicators
192 // are intracomms.
193 err = MPI_Allreduce (MPI_IN_PLACE, globalReducts,
194 count, rawMpiType, rawMpiOp, rawMpiComm);
195 }
196 else {
197 err = MPI_Allreduce (const_cast<T*> (sendBuffer), globalReducts,
198 count, rawMpiType, rawMpiOp, rawMpiComm);
199 }
201 err != MPI_SUCCESS,
202 std::runtime_error,
203 "MPI_Allreduce failed with the following error: "
204 << ::Teuchos::Details::getMpiErrorString (err));
205 }
206#else
207 // We've built without MPI, so just assume it's a SerialComm and copy the data.
208 std::copy (sendBuffer, sendBuffer + count, globalReducts);
209#endif // HAVE_TEUCHOS_MPI
210}
211
212
220template<class T>
221void
222gatherImpl (const T sendBuf[],
223 const int sendCount,
224 T recvBuf[],
225 const int recvCount,
226 const int root,
227 const Comm<int>& comm)
228{
229#ifdef HAVE_TEUCHOS_MPI
230 using Teuchos::Details::MpiTypeTraits;
231
232 // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
233 // SerialComm or an MpiComm. If it's something else, we fall back
234 // to the most general implementation.
235 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
236 if (mpiComm == NULL) {
237 // Is it a SerialComm?
238 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
239 if (serialComm == NULL) {
240 // We don't know what kind of Comm we have, so fall back to the
241 // most general implementation.
242 gather<int, T> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
243 }
244 else { // It's a SerialComm; there is only 1 process, so just copy.
245 std::copy (sendBuf, sendBuf + sendCount, recvBuf);
246 }
247 } else { // It's an MpiComm. Invoke MPI directly.
248 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
249 T t;
250 MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
251 const int err = MPI_Gather (const_cast<T*> (sendBuf), sendCount, rawMpiType,
252 recvBuf, recvCount, rawMpiType,
253 root, rawMpiComm);
255 err != MPI_SUCCESS,
256 std::runtime_error,
257 "MPI_Gather failed with the following error: "
258 << ::Teuchos::Details::getMpiErrorString (err));
259 }
260#else
261 // We've built without MPI, so just assume it's a SerialComm and copy the data.
262 std::copy (sendBuf, sendBuf + sendCount, recvBuf);
263#endif // HAVE_TEUCHOS_MPI
264}
265
266
274template<class T>
275void
276scatterImpl (const T sendBuf[],
277 const int sendCount,
278 T recvBuf[],
279 const int recvCount,
280 const int root,
281 const Comm<int>& comm)
282{
283#ifdef HAVE_TEUCHOS_MPI
284 using Teuchos::Details::MpiTypeTraits;
285
286 // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
287 // SerialComm or an MpiComm. If it's something else, we fall back
288 // to the most general implementation.
289 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
290 if (mpiComm == NULL) {
291 // Is it a SerialComm?
292 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
293 if (serialComm == NULL) {
294 // We don't know what kind of Comm we have, so fall back to the
295 // most general implementation.
296 scatter<int, T> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
297 }
298 else { // It's a SerialComm; there is only 1 process, so just copy.
299 std::copy (sendBuf, sendBuf + sendCount, recvBuf);
300 }
301 } else { // It's an MpiComm. Invoke MPI directly.
302 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
303 T t;
304 MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
305 const int err =
306 MPI_Scatter (const_cast<T*> (sendBuf), sendCount, rawMpiType,
307 recvBuf, recvCount, rawMpiType,
308 root, rawMpiComm);
310 (err != MPI_SUCCESS, std::runtime_error,
311 "MPI_Scatter failed with the following error: "
312 << ::Teuchos::Details::getMpiErrorString (err));
313 }
314#else
315 // We've built without MPI, so just assume it's a SerialComm and
316 // copy the data.
317 std::copy (sendBuf, sendBuf + sendCount, recvBuf);
318#endif // HAVE_TEUCHOS_MPI
319}
320
321template<class T>
322void
323scattervImpl (const T sendBuf[],
324 const int sendCounts[],
325 const int displs[],
326 T recvBuf[],
327 const int recvCount,
328 const int root,
329 const Comm<int>& comm)
330{
331#ifdef HAVE_TEUCHOS_MPI
332 using Teuchos::Details::MpiTypeTraits;
333
334 // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
335 // SerialComm or an MpiComm. If it's something else, we fall back
336 // to the most general implementation.
337 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
338 if (mpiComm == NULL) {
339 // Is it a SerialComm?
340 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
341 if (serialComm == NULL) {
342 // We don't know what kind of Comm we have, so fall back to the
343 // most general implementation.
344 scatterv<int, T> (sendBuf, sendCounts, displs, recvBuf, recvCount, root, comm);
345 }
346 else { // It's a SerialComm; there is only 1 process, so just copy.
347 std::copy (sendBuf, sendBuf + sendCounts[0], recvBuf);
348 }
349 } else { // It's an MpiComm. Invoke MPI directly.
350 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
351 T t;
352 MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
353 const int err =
354 MPI_Scatterv (const_cast<T*> (sendBuf), sendCounts, displs, rawMpiType,
355 recvBuf, recvCount, rawMpiType,
356 root, rawMpiComm);
358 (err != MPI_SUCCESS, std::runtime_error,
359 "MPI_Scatter failed with the following error: "
360 << ::Teuchos::Details::getMpiErrorString (err));
361 }
362#else
363 // We've built without MPI, so just assume it's a SerialComm and
364 // copy the data.
365 std::copy (sendBuf, sendBuf + sendCounts[0], recvBuf);
366#endif // HAVE_TEUCHOS_MPI
367}
368
369
377template<class T>
378void
379reduceImpl (const T sendBuf[],
380 T recvBuf[],
381 const int count,
382 const EReductionType reductType,
383 const int root,
384 const Comm<int>& comm)
385{
386#ifdef HAVE_TEUCHOS_MPI
387 using Teuchos::Details::MpiTypeTraits;
388
389 // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
390 // SerialComm or an MpiComm. If it's something else, we fall back
391 // to the most general implementation.
392 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
393 if (mpiComm == NULL) {
394 // Is it a SerialComm?
395 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
396 if (serialComm == NULL) {
397 // We don't know what kind of Comm we have, so fall back to the
398 // most general implementation.
399 reduce<int, T> (sendBuf, recvBuf, count, reductType, root, comm);
400 }
401 else { // It's a SerialComm; there is only 1 process, so just copy.
402 std::copy (sendBuf, sendBuf + count, recvBuf);
403 }
404 } else { // It's an MpiComm. Invoke MPI directly.
405 MPI_Op rawMpiOp = ::Teuchos::Details::getMpiOpForEReductionType (reductType);
406 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
407 T t;
408 MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
409 const int err = MPI_Reduce (const_cast<T*> (sendBuf), recvBuf, count,
410 rawMpiType, rawMpiOp, root, rawMpiComm);
412 (err != MPI_SUCCESS, std::runtime_error, "MPI_Reduce failed with the "
413 "following error: " << ::Teuchos::Details::getMpiErrorString (err));
414 }
415#else
416 // We've built without MPI, so just assume it's a SerialComm and copy the data.
417 std::copy (sendBuf, sendBuf + count, recvBuf);
418#endif // HAVE_TEUCHOS_MPI
419}
420
421
429template<class T>
430void
431gathervImpl (const T sendBuf[],
432 const int sendCount,
433 T recvBuf[],
434 const int recvCounts[],
435 const int displs[],
436 const int root,
437 const Comm<int>& comm)
438{
439#ifdef HAVE_TEUCHOS_MPI
440 using Teuchos::Details::MpiTypeTraits;
441
442 // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
443 // SerialComm or an MpiComm. If it's something else, we fall back
444 // to the most general implementation.
445 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
446 if (mpiComm == NULL) {
447 // Is it a SerialComm?
448 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
449 if (serialComm == NULL) {
450 // We don't know what kind of Comm we have, so fall back to the
451 // most general implementation.
452 gatherv<int, T> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
453 }
454 else { // It's a SerialComm; there is only 1 process, so just copy.
456 recvCounts[0] > sendCount, std::invalid_argument,
457 "Teuchos::gatherv: If the input communicator contains only one "
458 "process, then you cannot receive more entries than you send. "
459 "You aim to receive " << recvCounts[0] << " entries, but to send "
460 << sendCount << " entries.");
461 // Serial communicator case: just copy. recvCounts[0] is the
462 // amount to receive, so it's the amount to copy. Start writing
463 // to recvbuf at the offset displs[0].
464 std::copy (sendBuf, sendBuf + recvCounts[0], recvBuf + displs[0]);
465 }
466 } else { // It's an MpiComm. Invoke MPI directly.
467 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
468 T t;
469 MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
470 const int err = MPI_Gatherv (const_cast<T*> (sendBuf),
471 sendCount,
472 rawMpiType,
473 recvBuf,
474 const_cast<int*> (recvCounts),
475 const_cast<int*> (displs),
476 rawMpiType,
477 root,
478 rawMpiComm);
480 err != MPI_SUCCESS,
481 std::runtime_error,
482 "MPI_Gatherv failed with the following error: "
483 << ::Teuchos::Details::getMpiErrorString (err));
484 }
485#else
486 // We've built without MPI, so just assume it's a SerialComm and copy the data.
488 recvCounts[0] > sendCount, std::invalid_argument,
489 "Teuchos::gatherv: If the input communicator contains only one "
490 "process, then you cannot receive more entries than you send. "
491 "You aim to receive " << recvCounts[0] << " entries, but to send "
492 << sendCount << " entries.");
493 // Serial communicator case: just copy. recvCounts[0] is the
494 // amount to receive, so it's the amount to copy. Start writing
495 // to recvbuf at the offset displs[0].
496 std::copy (sendBuf, sendBuf + recvCounts[0], recvBuf + displs[0]);
497#endif // HAVE_TEUCHOS_MPI
498}
499
505template<typename Packet>
506RCP<Teuchos::CommRequest<int> >
507ireceiveGeneral(const Comm<int>& comm,
508 const ArrayRCP<Packet> &recvBuffer,
509 const int sourceRank)
510{
511 TEUCHOS_COMM_TIME_MONITOR(
512 "Teuchos::ireceive<int, " << "," << TypeNameTraits<Packet>::name ()
513 << "> ( value type )"
514 );
515 ValueTypeSerializationBuffer<int, Packet>
516 charRecvBuffer (recvBuffer.size (), recvBuffer.getRawPtr ());
517 RCP<CommRequest<int> > commRequest =
518 comm.ireceive (charRecvBuffer.getCharBufferView (), sourceRank);
519 set_extra_data (recvBuffer, "buffer", inOutArg (commRequest));
520 return commRequest;
521}
522
525template<typename Packet>
526RCP<Teuchos::CommRequest<int> >
527ireceiveGeneral (const ArrayRCP<Packet> &recvBuffer,
528 const int sourceRank,
529 const int tag,
530 const Comm<int>& comm)
531{
532 TEUCHOS_COMM_TIME_MONITOR(
533 "Teuchos::ireceive<int, " << "," << TypeNameTraits<Packet>::name ()
534 << "> ( value type )"
535 );
536 ValueTypeSerializationBuffer<int, Packet>
537 charRecvBuffer (recvBuffer.size (), recvBuffer.getRawPtr ());
538 RCP<CommRequest<int> > commRequest =
539 comm.ireceive (charRecvBuffer.getCharBufferView (), sourceRank, tag);
540 set_extra_data (recvBuffer, "buffer", inOutArg (commRequest));
541 return commRequest;
542}
543
556template<class T>
557RCP<CommRequest<int> >
558ireceiveImpl (const Comm<int>& comm,
559 const ArrayRCP<T>& recvBuffer,
560 const int sourceRank)
561{
562#ifdef HAVE_TEUCHOS_MPI
563 using Teuchos::Details::MpiTypeTraits;
564
565 // Even in an MPI build, Comm might be either a SerialComm or an
566 // MpiComm. If it's something else, we fall back to the most
567 // general implementation.
568 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
569 if (mpiComm == NULL) {
570 // Is it a SerialComm?
571 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
572 if (serialComm == NULL) {
573 // We don't know what kind of Comm we have, so fall back to the
574 // most general implementation.
575 return ireceiveGeneral<T> (comm, recvBuffer, sourceRank);
576 }
577 else { // SerialComm doesn't implement ireceive anyway.
579 true,
580 std::logic_error,
581 "ireceiveImpl: Not implemented for a serial communicator.");
582 }
583 }
584 else { // It's an MpiComm. Invoke MPI directly.
585 MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
586 T t;
587 MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
588 T* rawRecvBuf = recvBuffer.getRawPtr ();
589 const int count = as<int> (recvBuffer.size ());
590 const int tag = mpiComm->getTag ();
591 MPI_Request rawRequest = MPI_REQUEST_NULL;
592 const int err = MPI_Irecv (rawRecvBuf, count, rawType, sourceRank, tag,
593 rawComm, &rawRequest);
595 err != MPI_SUCCESS, std::runtime_error,
596 "MPI_Irecv failed with the following error: "
597 << ::Teuchos::Details::getMpiErrorString (err));
598
599 ArrayRCP<const char> buf =
600 arcp_const_cast<const char> (arcp_reinterpret_cast<char> (recvBuffer));
601 RCP<Details::MpiCommRequest> req (new Details::MpiCommRequest (rawRequest, buf));
602 return rcp_implicit_cast<CommRequest<int> > (req);
603 }
604#else
606 true,
607 std::logic_error,
608 "ireceiveImpl: Not implemented for a serial communicator.");
609
610 // NOTE (mfh 15 Sep 2014): Most compilers have figured out that the
611 // return statement below is unreachable. Some older compilers
612 // might not realize this. That's why the return statement was put
613 // there, so that those compilers don't warn that this function
614 // doesn't return a value. If it's a choice between one warning and
615 // another, I would prefer the choice that produces less code and
616 // doesn't have unreachable code (which never gets tested).
617
618 //return null; // Guard to avoid compiler warning about not returning a value.
619#endif // HAVE_TEUCHOS_MPI
620}
621
624template<class T>
625RCP<CommRequest<int> >
626ireceiveImpl (const ArrayRCP<T>& recvBuffer,
627 const int sourceRank,
628 const int tag,
629 const Comm<int>& comm)
630{
631#ifdef HAVE_TEUCHOS_MPI
632 using Teuchos::Details::MpiTypeTraits;
633
634 // Even in an MPI build, Comm might be either a SerialComm or an
635 // MpiComm. If it's something else, we fall back to the most
636 // general implementation.
637 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
638 if (mpiComm == NULL) {
639 // Is it a SerialComm?
640 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
641 if (serialComm == NULL) {
642 // We don't know what kind of Comm we have, so fall back to the
643 // most general implementation.
644 return ireceiveGeneral<T> (recvBuffer, sourceRank, tag, comm);
645 }
646 else { // SerialComm doesn't implement ireceive anyway.
648 true,
649 std::logic_error,
650 "ireceiveImpl: Not implemented for a serial communicator.");
651 }
652 }
653 else { // It's an MpiComm. Invoke MPI directly.
654 MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
655 T t;
656 MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
657 T* rawRecvBuf = recvBuffer.getRawPtr ();
658 const int count = as<int> (recvBuffer.size ());
659 MPI_Request rawRequest = MPI_REQUEST_NULL;
660 const int err = MPI_Irecv (rawRecvBuf, count, rawType, sourceRank, tag,
661 rawComm, &rawRequest);
663 err != MPI_SUCCESS, std::runtime_error,
664 "MPI_Irecv failed with the following error: "
665 << ::Teuchos::Details::getMpiErrorString (err));
666
667 ArrayRCP<const char> buf =
668 arcp_const_cast<const char> (arcp_reinterpret_cast<char> (recvBuffer));
669 RCP<Details::MpiCommRequest> req (new Details::MpiCommRequest (rawRequest, buf));
670 return rcp_implicit_cast<CommRequest<int> > (req);
671 }
672#else
674 true,
675 std::logic_error,
676 "ireceiveImpl: Not implemented for a serial communicator.");
677
678 return null; // Guard to avoid compiler warning about not returning a value.
679#endif // HAVE_TEUCHOS_MPI
680}
681
687template<class T>
688void
689sendGeneral (const Comm<int>& comm,
690 const int count,
691 const T sendBuffer[],
692 const int destRank)
693{
694 TEUCHOS_COMM_TIME_MONITOR(
695 "Teuchos::send<int, " << TypeNameTraits<T>::name () << ">");
696 ConstValueTypeSerializationBuffer<int,T> charSendBuffer (count, sendBuffer);
697 comm.send (charSendBuffer.getBytes (),
698 charSendBuffer.getCharBuffer (),
699 destRank);
700}
701
704template<class T>
705void
706sendGeneral (const T sendBuffer[],
707 const int count,
708 const int destRank,
709 const int tag,
710 const Comm<int>& comm)
711{
712 TEUCHOS_COMM_TIME_MONITOR(
713 "Teuchos::send<int, " << TypeNameTraits<T>::name () << ">");
714 ConstValueTypeSerializationBuffer<int,T> charSendBuffer (count, sendBuffer);
715 comm.send (charSendBuffer.getBytes (),
716 charSendBuffer.getCharBuffer (),
717 destRank, tag);
718}
719
732template<class T>
733void
734sendImpl (const Comm<int>& comm,
735 const int count,
736 const T sendBuffer[],
737 const int destRank)
738{
739#ifdef HAVE_TEUCHOS_MPI
740 using Teuchos::Details::MpiTypeTraits;
741
742 // Even in an MPI build, Comm might be either a SerialComm or an
743 // MpiComm. If it's something else, we fall back to the most
744 // general implementation.
745 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
746 if (mpiComm == NULL) {
747 // Is it a SerialComm?
748 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
749 if (serialComm == NULL) {
750 // We don't know what kind of Comm we have, so fall back to the
751 // most general implementation.
752 sendGeneral<T> (comm, count, sendBuffer, destRank);
753 }
754 else { // SerialComm doesn't implement send correctly anyway.
756 true,
757 std::logic_error,
758 "sendImpl: Not implemented for a serial communicator.");
759 }
760 }
761 else { // It's an MpiComm. Invoke MPI directly.
762 TEUCHOS_COMM_TIME_MONITOR(
763 "Teuchos::sendImpl<" << TypeNameTraits<T>::name () << ">");
764 MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
765 T t;
766 MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
767 T* rawBuf = const_cast<T*> (sendBuffer);
768 const int tag = mpiComm->getTag ();
769 const int err = MPI_Send (rawBuf, count, rawType, destRank, tag, rawComm);
771 err != MPI_SUCCESS,
772 std::runtime_error,
773 "MPI_Send failed with the following error: "
774 << ::Teuchos::Details::getMpiErrorString (err));
775 }
776#else
778 true,
779 std::logic_error,
780 "sendImpl: Not implemented for a serial communicator.");
781#endif // HAVE_TEUCHOS_MPI
782}
783
786template<class T>
787void
788sendImpl (const T sendBuffer[],
789 const int count,
790 const int destRank,
791 const int tag,
792 const Comm<int>& comm)
793{
794#ifdef HAVE_TEUCHOS_MPI
795 using Teuchos::Details::MpiTypeTraits;
796
797 // Even in an MPI build, Comm might be either a SerialComm or an
798 // MpiComm. If it's something else, we fall back to the most
799 // general implementation.
800 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
801 if (mpiComm == NULL) {
802 // Is it a SerialComm?
803 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
804 if (serialComm == NULL) {
805 // We don't know what kind of Comm we have, so fall back to the
806 // most general implementation.
807 sendGeneral<T> (sendBuffer, count, destRank, tag, comm);
808 }
809 else { // SerialComm doesn't implement send correctly anyway.
811 true,
812 std::logic_error,
813 "sendImpl: Not implemented for a serial communicator.");
814 }
815 }
816 else { // It's an MpiComm. Invoke MPI directly.
817 TEUCHOS_COMM_TIME_MONITOR(
818 "Teuchos::sendImpl<" << TypeNameTraits<T>::name () << ">");
819 MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
820 T t;
821 MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
822 T* rawBuf = const_cast<T*> (sendBuffer);
823 const int err = MPI_Send (rawBuf, count, rawType, destRank, tag, rawComm);
825 err != MPI_SUCCESS,
826 std::runtime_error,
827 "MPI_Send failed with the following error: "
828 << ::Teuchos::Details::getMpiErrorString (err));
829 }
830#else
832 true,
833 std::logic_error,
834 "sendImpl: Not implemented for a serial communicator.");
835#endif // HAVE_TEUCHOS_MPI
836}
837
843template<class T>
844RCP<CommRequest<int> >
845isendGeneral (const Comm<int>& comm,
846 const ArrayRCP<const T>& sendBuffer,
847 const int destRank)
848{
849 TEUCHOS_COMM_TIME_MONITOR(
850 "Teuchos::isend<int," << TypeNameTraits<T>::name () << ">");
851 ConstValueTypeSerializationBuffer<int, T>
852 charSendBuffer (sendBuffer.size (), sendBuffer.getRawPtr ());
853 RCP<CommRequest<int> > commRequest =
854 comm.isend (charSendBuffer.getCharBufferView (), destRank);
855 set_extra_data (sendBuffer, "buffer", inOutArg (commRequest));
856 return commRequest;
857}
858
865template<class T>
866RCP<CommRequest<int> >
867isendGeneral (const ArrayRCP<const T>& sendBuffer,
868 const int destRank,
869 const int tag,
870 const Comm<int>& comm)
871{
872 TEUCHOS_COMM_TIME_MONITOR(
873 "Teuchos::isend<int," << TypeNameTraits<T>::name () << ">");
874 ConstValueTypeSerializationBuffer<int, T>
875 charSendBuffer (sendBuffer.size (), sendBuffer.getRawPtr ());
876 RCP<CommRequest<int> > commRequest =
877 comm.isend (charSendBuffer.getCharBufferView (), destRank, tag);
878 set_extra_data (sendBuffer, "buffer", inOutArg (commRequest));
879 return commRequest;
880}
881
884template<class T>
885RCP<Teuchos::CommRequest<int> >
886isendImpl (const ArrayRCP<const T>& sendBuffer,
887 const int destRank,
888 const int tag,
889 const Comm<int>& comm)
890{
891#ifdef HAVE_TEUCHOS_MPI
892 using Teuchos::Details::MpiTypeTraits;
893
894 // Even in an MPI build, Comm might be either a SerialComm or an
895 // MpiComm. If it's something else, we fall back to the most
896 // general implementation.
897 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
898 if (mpiComm == NULL) {
899 // Is it a SerialComm?
900 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
901 if (serialComm == NULL) {
902 // We don't know what kind of Comm we have, so fall back to the
903 // most general implementation.
904 return isendGeneral<T> (sendBuffer, destRank, tag, comm);
905 }
906 else { // SerialComm doesn't implement send correctly anyway.
908 true, std::logic_error,
909 "isendImpl: Not implemented for a serial communicator.");
910 }
911 }
912 else { // It's an MpiComm. Invoke MPI directly.
913 TEUCHOS_COMM_TIME_MONITOR(
914 "Teuchos::isendImpl<" << TypeNameTraits<T>::name () << ">");
915
916 MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
917 T t;
918 MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
919 // MPI promises not to modify the send buffer; the const_cast
920 // merely ensures compatibilty with C89, which does not have a
921 // "const" keyword.
922 T* rawSendBuf = const_cast<T*> (sendBuffer.getRawPtr ());
923 const int count = as<int> (sendBuffer.size ());
924 MPI_Request rawRequest = MPI_REQUEST_NULL;
925 const int err = MPI_Isend (rawSendBuf, count, rawType, destRank, tag,
926 rawComm, &rawRequest);
928 err != MPI_SUCCESS,
929 std::runtime_error,
930 "MPI_Isend failed with the following error: "
931 << ::Teuchos::Details::getMpiErrorString (err));
932
933 ArrayRCP<const char> buf = arcp_reinterpret_cast<const char> (sendBuffer);
934 RCP<Details::MpiCommRequest> req (new Details::MpiCommRequest (rawRequest, buf));
935 return rcp_implicit_cast<CommRequest<int> > (req);
936 }
937#else
939 true,
940 std::logic_error,
941 "isendImpl: Not implemented for a serial communicator.");
942#endif // HAVE_TEUCHOS_MPI
943}
944
945} // namespace (anonymous)
946
947
948// mfh 18 Oct 2012: Note on full template specializations
949//
950// To make Windows builds happy, declarations of full template
951// specializations (as found in Teuchos_CommHelpers.hpp) must use the
952// TEUCHOSCOMM_LIB_DLL_EXPORT macro. However, _definitions_ of the
953// specializations (as found in this file) must _not_ use the macro.
954// That's why we don't use that macro here.
955
956// amb See note in .hpp file.
957#if 0
958#ifdef HAVE_TEUCHOS_COMPLEX
959// Specialization for Ordinal=int and Packet=std::complex<double>.
960template<>
961void
962reduceAll<int, std::complex<double> > (const Comm<int>& comm,
963 const EReductionType reductType,
964 const int count,
965 const std::complex<double> sendBuffer[],
966 std::complex<double> globalReducts[])
967{
968 TEUCHOS_COMM_TIME_MONITOR(
969 "Teuchos::reduceAll<int, std::complex<double> > (" << count << ", "
970 << toString (reductType) << ")"
971 );
972 reduceAllImpl<std::complex<double> > (comm, reductType, count, sendBuffer, globalReducts);
973}
974
975template<>
976RCP<Teuchos::CommRequest<int> >
977ireceive<int, std::complex<double> > (const Comm<int>& comm,
978 const ArrayRCP<std::complex<double> >& recvBuffer,
979 const int sourceRank)
980{
981 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<double> >");
982 return ireceiveImpl<std::complex<double> > (comm, recvBuffer, sourceRank);
983}
984
985template<>
986RCP<Teuchos::CommRequest<int> >
987ireceive<int, std::complex<double> > (const ArrayRCP<std::complex<double> >& recvBuffer,
988 const int sourceRank,
989 const int tag,
990 const Comm<int>& comm)
991{
992 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<double> >");
993 return ireceiveImpl<std::complex<double> > (recvBuffer, sourceRank, tag, comm);
994}
995
996template<>
997void
998send<int, std::complex<double> > (const Comm<int>& comm,
999 const int count,
1000 const std::complex<double> sendBuffer[],
1001 const int destRank)
1002{
1003 sendImpl<std::complex<double> > (comm, count, sendBuffer, destRank);
1004}
1005
1006template<>
1007void
1008send<int, std::complex<double> > (const std::complex<double> sendBuffer[],
1009 const int count,
1010 const int destRank,
1011 const int tag,
1012 const Comm<int>& comm)
1013{
1014 sendImpl<std::complex<double> > (sendBuffer, count, destRank, tag, comm);
1015}
1016
1017template<>
1018RCP<Teuchos::CommRequest<int> >
1019isend (const ArrayRCP<const std::complex<double> >& sendBuffer,
1020 const int destRank,
1021 const int tag,
1022 const Comm<int>& comm)
1023{
1024 return isendImpl<std::complex<double> > (sendBuffer, destRank, tag, comm);
1025}
1026
1027// Specialization for Ordinal=int and Packet=std::complex<float>.
1028template<>
1029void
1030reduceAll<int, std::complex<float> > (const Comm<int>& comm,
1031 const EReductionType reductType,
1032 const int count,
1033 const std::complex<float> sendBuffer[],
1034 std::complex<float> globalReducts[])
1035{
1036 TEUCHOS_COMM_TIME_MONITOR(
1037 "Teuchos::reduceAll<int, std::complex<float> > (" << count << ", "
1038 << toString (reductType) << ")"
1039 );
1040 reduceAllImpl<std::complex<float> > (comm, reductType, count, sendBuffer, globalReducts);
1041}
1042
1043template<>
1044RCP<Teuchos::CommRequest<int> >
1045ireceive<int, std::complex<float> > (const Comm<int>& comm,
1046 const ArrayRCP<std::complex<float> >& recvBuffer,
1047 const int sourceRank)
1048{
1049 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<float> >");
1050 return ireceiveImpl<std::complex<float> > (comm, recvBuffer, sourceRank);
1051}
1052
1053template<>
1054RCP<Teuchos::CommRequest<int> >
1055ireceive<int, std::complex<float> > (const ArrayRCP<std::complex<float> >& recvBuffer,
1056 const int sourceRank,
1057 const int tag,
1058 const Comm<int>& comm)
1059{
1060 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<float> >");
1061 return ireceiveImpl<std::complex<float> > (recvBuffer, sourceRank, tag, comm);
1062}
1063
1064template<>
1065void
1066send<int, std::complex<float> > (const Comm<int>& comm,
1067 const int count,
1068 const std::complex<float> sendBuffer[],
1069 const int destRank)
1070{
1071 return sendImpl<std::complex<float> > (comm, count, sendBuffer, destRank);
1072}
1073
1074template<>
1075void
1076send<int, std::complex<float> > (const std::complex<float> sendBuffer[],
1077 const int count,
1078 const int destRank,
1079 const int tag,
1080 const Comm<int>& comm)
1081{
1082 return sendImpl<std::complex<float> > (sendBuffer, count, destRank, tag, comm);
1083}
1084
1085template<>
1086RCP<Teuchos::CommRequest<int> >
1087isend (const ArrayRCP<const std::complex<float> >& sendBuffer,
1088 const int destRank,
1089 const int tag,
1090 const Comm<int>& comm)
1091{
1092 return isendImpl<std::complex<float> > (sendBuffer, destRank, tag, comm);
1093}
1094#endif // HAVE_TEUCHOS_COMPLEX
1095#endif // if 0
1096
1097// Specialization for Ordinal=int and Packet=double.
1098template<>
1099void
1100alltoAllv<int, double> (const double sendBuf[],
1101 const int sendCounts[],
1102 const int sendDispls[],
1103 double recvBuf[],
1104 const int recvCounts[],
1105 const int recvDispls[],
1106 const Comm<int>& comm)
1107{
1108 alltoAllvImpl<double> (sendBuf, sendCounts, sendDispls,
1109 recvBuf, recvCounts, recvDispls, comm);
1110}
1111
1112template<>
1113void
1114reduceAll<int, double> (const Comm<int>& comm,
1115 const EReductionType reductType,
1116 const int count,
1117 const double sendBuffer[],
1118 double globalReducts[])
1119{
1120 TEUCHOS_COMM_TIME_MONITOR(
1121 "Teuchos::reduceAll<int, double> (" << count << ", "
1122 << toString (reductType) << ")"
1123 );
1124 reduceAllImpl<double> (comm, reductType, count, sendBuffer, globalReducts);
1125}
1126
1127template<>
1128RCP<Teuchos::CommRequest<int> >
1129ireceive<int, double> (const Comm<int>& comm,
1130 const ArrayRCP<double>& recvBuffer,
1131 const int sourceRank)
1132{
1133 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, double>");
1134 return ireceiveImpl<double> (comm, recvBuffer, sourceRank);
1135}
1136
1137template<>
1138RCP<Teuchos::CommRequest<int> >
1139ireceive<int, double> (const ArrayRCP<double>& recvBuffer,
1140 const int sourceRank,
1141 const int tag,
1142 const Comm<int>& comm)
1143{
1144 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, double>");
1145 return ireceiveImpl<double> (recvBuffer, sourceRank, tag, comm);
1146}
1147
1148template<>
1149void
1150send<int, double> (const Comm<int>& comm,
1151 const int count,
1152 const double sendBuffer[],
1153 const int destRank)
1154{
1155 return sendImpl<double> (comm, count, sendBuffer, destRank);
1156}
1157
1158template<>
1159void
1160send<int, double> (const double sendBuffer[],
1161 const int count,
1162 const int destRank,
1163 const int tag,
1164 const Comm<int>& comm)
1165{
1166 return sendImpl<double> (sendBuffer, count, destRank, tag, comm);
1167}
1168
1169template<>
1170RCP<Teuchos::CommRequest<int> >
1171isend (const ArrayRCP<const double>& sendBuffer,
1172 const int destRank,
1173 const int tag,
1174 const Comm<int>& comm)
1175{
1176 return isendImpl<double> (sendBuffer, destRank, tag, comm);
1177}
1178
1179template<>
1180void
1181gatherv<int, double> (const double sendBuf[],
1182 const int sendCount,
1183 double recvBuf[],
1184 const int recvCounts[],
1185 const int displs[],
1186 const int root,
1187 const Comm<int>& comm)
1188{
1189 gathervImpl<double> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1190}
1191
1192
1193// Specialization for Ordinal=int and Packet=float.
1194template<>
1195void
1196reduceAll<int, float> (const Comm<int>& comm,
1197 const EReductionType reductType,
1198 const int count,
1199 const float sendBuffer[],
1200 float globalReducts[])
1201{
1202 TEUCHOS_COMM_TIME_MONITOR(
1203 "Teuchos::reduceAll<int, float> (" << count << ", "
1204 << toString (reductType) << ")"
1205 );
1206 reduceAllImpl<float> (comm, reductType, count, sendBuffer, globalReducts);
1207}
1208
1209template<>
1210RCP<Teuchos::CommRequest<int> >
1211ireceive<int, float> (const Comm<int>& comm,
1212 const ArrayRCP<float>& recvBuffer,
1213 const int sourceRank)
1214{
1215 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, float>");
1216 return ireceiveImpl<float> (comm, recvBuffer, sourceRank);
1217}
1218
1219template<>
1220RCP<Teuchos::CommRequest<int> >
1221ireceive<int, float> (const ArrayRCP<float>& recvBuffer,
1222 const int sourceRank,
1223 const int tag,
1224 const Comm<int>& comm)
1225{
1226 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, float>");
1227 return ireceiveImpl<float> (recvBuffer, sourceRank, tag, comm);
1228}
1229
1230template<>
1231void
1232send<int, float> (const Comm<int>& comm,
1233 const int count,
1234 const float sendBuffer[],
1235 const int destRank)
1236{
1237 return sendImpl<float> (comm, count, sendBuffer, destRank);
1238}
1239
1240template<>
1241void
1242send<int, float> (const float sendBuffer[],
1243 const int count,
1244 const int destRank,
1245 const int tag,
1246 const Comm<int>& comm)
1247{
1248 return sendImpl<float> (sendBuffer, count, destRank, tag, comm);
1249}
1250
1251template<>
1252RCP<Teuchos::CommRequest<int> >
1253isend (const ArrayRCP<const float>& sendBuffer,
1254 const int destRank,
1255 const int tag,
1256 const Comm<int>& comm)
1257{
1258 return isendImpl<float> (sendBuffer, destRank, tag, comm);
1259}
1260
1261template<>
1262void
1263gatherv<int,float> (const float sendBuf[],
1264 const int sendCount,
1265 float recvBuf[],
1266 const int recvCounts[],
1267 const int displs[],
1268 const int root,
1269 const Comm<int>& comm)
1270{
1271 gathervImpl<float> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1272}
1273
1274
1275// Specialization for Ordinal=int and Packet=long long.
1276template<>
1277void
1278gather<int, long long> (const long long sendBuf[],
1279 const int sendCount,
1280 long long recvBuf[],
1281 const int recvCount,
1282 const int root,
1283 const Comm<int>& comm)
1284{
1285 gatherImpl<long long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1286}
1287
1288template<>
1289void
1290gatherv<int, long long> (const long long sendBuf[],
1291 const int sendCount,
1292 long long recvBuf[],
1293 const int recvCounts[],
1294 const int displs[],
1295 const int root,
1296 const Comm<int>& comm)
1297{
1298 gathervImpl<long long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1299}
1300
1301template<>
1302void
1303reduceAll<int, long long> (const Comm<int>& comm,
1304 const EReductionType reductType,
1305 const int count,
1306 const long long sendBuffer[],
1307 long long globalReducts[])
1308{
1309 TEUCHOS_COMM_TIME_MONITOR(
1310 "Teuchos::reduceAll<int, long long> (" << count << ", "
1311 << toString (reductType) << ")"
1312 );
1313 reduceAllImpl<long long> (comm, reductType, count, sendBuffer, globalReducts);
1314}
1315
1316template<>
1317RCP<Teuchos::CommRequest<int> >
1318ireceive<int, long long> (const Comm<int>& comm,
1319 const ArrayRCP<long long>& recvBuffer,
1320 const int sourceRank)
1321{
1322 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long long>");
1323 return ireceiveImpl<long long> (comm, recvBuffer, sourceRank);
1324}
1325
1326template<>
1327RCP<Teuchos::CommRequest<int> >
1328ireceive<int, long long> (const ArrayRCP<long long>& recvBuffer,
1329 const int sourceRank,
1330 const int tag,
1331 const Comm<int>& comm)
1332{
1333 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long long>");
1334 return ireceiveImpl<long long> (recvBuffer, sourceRank, tag, comm);
1335}
1336
1337template<>
1338void
1339send<int, long long> (const Comm<int>& comm,
1340 const int count,
1341 const long long sendBuffer[],
1342 const int destRank)
1343{
1344 return sendImpl<long long> (comm, count, sendBuffer, destRank);
1345}
1346
1347template<>
1348void
1349send<int, long long> (const long long sendBuffer[],
1350 const int count,
1351 const int destRank,
1352 const int tag,
1353 const Comm<int>& comm)
1354{
1355 return sendImpl<long long> (sendBuffer, count, destRank, tag, comm);
1356}
1357
1358template<>
1359RCP<Teuchos::CommRequest<int> >
1360isend (const ArrayRCP<const long long>& sendBuffer,
1361 const int destRank,
1362 const int tag,
1363 const Comm<int>& comm)
1364{
1365 return isendImpl<long long> (sendBuffer, destRank, tag, comm);
1366}
1367
1368// Specialization for Ordinal=int and Packet=unsigned long long.
1369template<>
1370void
1371gather<int, unsigned long long> (const unsigned long long sendBuf[],
1372 const int sendCount,
1373 unsigned long long recvBuf[],
1374 const int recvCount,
1375 const int root,
1376 const Comm<int>& comm)
1377{
1378 gatherImpl<unsigned long long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1379}
1380
1381template<>
1382void
1383gatherv<int, unsigned long long> (const unsigned long long sendBuf[],
1384 const int sendCount,
1385 unsigned long long recvBuf[],
1386 const int recvCounts[],
1387 const int displs[],
1388 const int root,
1389 const Comm<int>& comm)
1390{
1391 gathervImpl<unsigned long long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1392}
1393
1394template<>
1395void
1396reduceAll<int, unsigned long long> (const Comm<int>& comm,
1397 const EReductionType reductType,
1398 const int count,
1399 const unsigned long long sendBuffer[],
1400 unsigned long long globalReducts[])
1401{
1402 TEUCHOS_COMM_TIME_MONITOR(
1403 "Teuchos::reduceAll<int, unsigned long long> (" << count << ", "
1404 << toString (reductType) << ")"
1405 );
1406 reduceAllImpl<unsigned long long> (comm, reductType, count, sendBuffer, globalReducts);
1407}
1408
1409template<>
1410RCP<Teuchos::CommRequest<int> >
1411ireceive<int, unsigned long long> (const Comm<int>& comm,
1412 const ArrayRCP<unsigned long long>& recvBuffer,
1413 const int sourceRank)
1414{
1415 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long long>");
1416 return ireceiveImpl<unsigned long long> (comm, recvBuffer, sourceRank);
1417}
1418
1419template<>
1420RCP<Teuchos::CommRequest<int> >
1421ireceive<int, unsigned long long> (const ArrayRCP<unsigned long long>& recvBuffer,
1422 const int sourceRank,
1423 const int tag,
1424 const Comm<int>& comm)
1425{
1426 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long long>");
1427 return ireceiveImpl<unsigned long long> (recvBuffer, sourceRank, tag, comm);
1428}
1429
1430template<>
1431void
1432send<int, unsigned long long> (const Comm<int>& comm,
1433 const int count,
1434 const unsigned long long sendBuffer[],
1435 const int destRank)
1436{
1437 return sendImpl<unsigned long long> (comm, count, sendBuffer, destRank);
1438}
1439
1440template<>
1441void
1442send<int, unsigned long long> (const unsigned long long sendBuffer[],
1443 const int count,
1444 const int destRank,
1445 const int tag,
1446 const Comm<int>& comm)
1447{
1448 return sendImpl<unsigned long long> (sendBuffer, count, destRank, tag, comm);
1449}
1450
1451template<>
1452RCP<Teuchos::CommRequest<int> >
1453isend (const ArrayRCP<const unsigned long long>& sendBuffer,
1454 const int destRank,
1455 const int tag,
1456 const Comm<int>& comm)
1457{
1458 return isendImpl<unsigned long long> (sendBuffer, destRank, tag, comm);
1459}
1460
1461
1462// Specialization for Ordinal=int and Packet=long.
1463template<>
1464void
1465gather<int, long> (const long sendBuf[],
1466 const int sendCount,
1467 long recvBuf[],
1468 const int recvCount,
1469 const int root,
1470 const Comm<int>& comm)
1471{
1472 gatherImpl<long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1473}
1474
1475template<>
1476void
1477gatherv<int, long> (const long sendBuf[],
1478 const int sendCount,
1479 long recvBuf[],
1480 const int recvCounts[],
1481 const int displs[],
1482 const int root,
1483 const Comm<int>& comm)
1484{
1485 gathervImpl<long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1486}
1487
1488template<>
1489void
1490reduceAll<int, long> (const Comm<int>& comm,
1491 const EReductionType reductType,
1492 const int count,
1493 const long sendBuffer[],
1494 long globalReducts[])
1495{
1496 TEUCHOS_COMM_TIME_MONITOR(
1497 "Teuchos::reduceAll<int, long> (" << count << ", "
1498 << toString (reductType) << ")"
1499 );
1500 reduceAllImpl<long> (comm, reductType, count, sendBuffer, globalReducts);
1501}
1502
1503template<>
1504RCP<Teuchos::CommRequest<int> >
1505ireceive<int, long> (const Comm<int>& comm,
1506 const ArrayRCP<long>& recvBuffer,
1507 const int sourceRank)
1508{
1509 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long>");
1510 return ireceiveImpl<long> (comm, recvBuffer, sourceRank);
1511}
1512
1513template<>
1514RCP<Teuchos::CommRequest<int> >
1515ireceive<int, long> (const ArrayRCP<long>& recvBuffer,
1516 const int sourceRank,
1517 const int tag,
1518 const Comm<int>& comm)
1519{
1520 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long>");
1521 return ireceiveImpl<long> (recvBuffer, sourceRank, tag, comm);
1522}
1523
1524template<>
1525void
1526send<int, long> (const Comm<int>& comm,
1527 const int count,
1528 const long sendBuffer[],
1529 const int destRank)
1530{
1531 return sendImpl<long> (comm, count, sendBuffer, destRank);
1532}
1533
1534template<>
1535void
1536send<int, long> (const long sendBuffer[],
1537 const int count,
1538 const int destRank,
1539 const int tag,
1540 const Comm<int>& comm)
1541{
1542 return sendImpl<long> (sendBuffer, count, destRank, tag, comm);
1543}
1544
1545template<>
1546RCP<Teuchos::CommRequest<int> >
1547isend (const ArrayRCP<const long>& sendBuffer,
1548 const int destRank,
1549 const int tag,
1550 const Comm<int>& comm)
1551{
1552 return isendImpl<long> (sendBuffer, destRank, tag, comm);
1553}
1554
1555
1556// Specialization for Ordinal=int and Packet=unsigned long.
1557template<>
1558void
1559gather<int, unsigned long> (const unsigned long sendBuf[],
1560 const int sendCount,
1561 unsigned long recvBuf[],
1562 const int recvCount,
1563 const int root,
1564 const Comm<int>& comm)
1565{
1566 gatherImpl<unsigned long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1567}
1568
1569template<>
1570void
1571gatherv<int, unsigned long> (const unsigned long sendBuf[],
1572 const int sendCount,
1573 unsigned long recvBuf[],
1574 const int recvCounts[],
1575 const int displs[],
1576 const int root,
1577 const Comm<int>& comm)
1578{
1579 gathervImpl<unsigned long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1580}
1581
1582template<>
1583void
1584reduceAll<int, unsigned long> (const Comm<int>& comm,
1585 const EReductionType reductType,
1586 const int count,
1587 const unsigned long sendBuffer[],
1588 unsigned long globalReducts[])
1589{
1590 TEUCHOS_COMM_TIME_MONITOR(
1591 "Teuchos::reduceAll<int, unsigned long> (" << count << ", "
1592 << toString (reductType) << ")"
1593 );
1594 reduceAllImpl<unsigned long> (comm, reductType, count, sendBuffer, globalReducts);
1595}
1596
1597template<>
1598RCP<Teuchos::CommRequest<int> >
1599ireceive<int, unsigned long> (const Comm<int>& comm,
1600 const ArrayRCP<unsigned long>& recvBuffer,
1601 const int sourceRank)
1602{
1603 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long>");
1604 return ireceiveImpl<unsigned long> (comm, recvBuffer, sourceRank);
1605}
1606
1607template<>
1608RCP<Teuchos::CommRequest<int> >
1609ireceive<int, unsigned long> (const ArrayRCP<unsigned long>& recvBuffer,
1610 const int sourceRank,
1611 const int tag,
1612 const Comm<int>& comm)
1613{
1614 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long>");
1615 return ireceiveImpl<unsigned long> (recvBuffer, sourceRank, tag, comm);
1616}
1617
1618template<>
1619void
1620send<int, unsigned long> (const Comm<int>& comm,
1621 const int count,
1622 const unsigned long sendBuffer[],
1623 const int destRank)
1624{
1625 return sendImpl<unsigned long> (comm, count, sendBuffer, destRank);
1626}
1627
1628template<>
1629void
1630send<int, unsigned long> (const unsigned long sendBuffer[],
1631 const int count,
1632 const int destRank,
1633 const int tag,
1634 const Comm<int>& comm)
1635{
1636 return sendImpl<unsigned long> (sendBuffer, count, destRank, tag, comm);
1637}
1638
1639template<>
1640RCP<Teuchos::CommRequest<int> >
1641isend (const ArrayRCP<const unsigned long>& sendBuffer,
1642 const int destRank,
1643 const int tag,
1644 const Comm<int>& comm)
1645{
1646 return isendImpl<unsigned long> (sendBuffer, destRank, tag, comm);
1647}
1648
1649// Specialization for Ordinal=int and Packet=int.
1650template<>
1651void
1652alltoAll<int, int> (const int sendBuf[],
1653 const int sendCount,
1654 int recvBuf[],
1655 const int recvCount,
1656 const Comm<int>& comm)
1657{
1658 alltoAllImpl<int> (sendBuf, sendCount, recvBuf, recvCount, comm);
1659}
1660
1661template<>
1662void
1663alltoAllv<int, int> (const int sendBuf[],
1664 const int sendCounts[],
1665 const int sendDispls[],
1666 int recvBuf[],
1667 const int recvCounts[],
1668 const int recvDispls[],
1669 const Comm<int>& comm)
1670{
1671 alltoAllvImpl<int> (sendBuf, sendCounts, sendDispls,
1672 recvBuf, recvCounts, recvDispls, comm);
1673}
1674
1675template<>
1676void
1677gather<int, int> (const int sendBuf[],
1678 const int sendCount,
1679 int recvBuf[],
1680 const int recvCount,
1681 const int root,
1682 const Comm<int>& comm)
1683{
1684 gatherImpl<int> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1685}
1686
1687template<>
1688void
1689gatherv<int, int> (const int sendBuf[],
1690 const int sendCount,
1691 int recvBuf[],
1692 const int recvCounts[],
1693 const int displs[],
1694 const int root,
1695 const Comm<int>& comm)
1696{
1697 gathervImpl<int> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1698}
1699
1700template<>
1701void
1702scatter<int, int> (const int sendBuf[],
1703 const int sendCount,
1704 int recvBuf[],
1705 const int recvCount,
1706 const int root,
1707 const Comm<int>& comm)
1708{
1709 scatterImpl<int> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1710}
1711
1712template<>
1713void
1714scatterv<int, int> (const int sendBuf[],
1715 const int sendCount[],
1716 const int displs[],
1717 int recvBuf[],
1718 const int recvCount,
1719 const int root,
1720 const Comm<int>& comm)
1721{
1722 scattervImpl<int> (sendBuf, sendCount, displs, recvBuf, recvCount, root, comm);
1723}
1724
1725template<>
1726void
1727scatterv<int, double> (const double sendBuf[],
1728 const int sendCount[],
1729 const int displs[],
1730 double recvBuf[],
1731 const int recvCount,
1732 const int root,
1733 const Comm<int>& comm)
1734{
1735 scattervImpl<double> (sendBuf, sendCount, displs, recvBuf, recvCount, root, comm);
1736}
1737
1738template<>
1739void
1740scatterv<int, float> (const float sendBuf[],
1741 const int sendCounts[],
1742 const int displs[],
1743 float recvBuf[],
1744 const int recvCount,
1745 const int root,
1746 const Comm<int>& comm)
1747{
1748 scattervImpl<float> (sendBuf, sendCounts, displs, recvBuf, recvCount, root, comm);
1749}
1750
1751template<>
1752void
1753reduce<int, int> (const int sendBuf[],
1754 int recvBuf[],
1755 const int count,
1756 const EReductionType reductType,
1757 const int root,
1758 const Comm<int>& comm)
1759{
1760 TEUCHOS_COMM_TIME_MONITOR
1761 ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1762 << ")");
1763 reduceImpl<int> (sendBuf, recvBuf, count, reductType, root, comm);
1764}
1765template<>
1766void
1767reduce<int, long> (const long sendBuf[],
1768 long recvBuf[],
1769 const int count,
1770 const EReductionType reductType,
1771 const int root,
1772 const Comm<int>& comm)
1773{
1774 TEUCHOS_COMM_TIME_MONITOR
1775 ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1776 << ")");
1777 reduceImpl<long> (sendBuf, recvBuf, count, reductType, root, comm);
1778}
1779
1780template<>
1781void
1782reduce<int, unsigned long> (const unsigned long sendBuf[],
1783 unsigned long recvBuf[],
1784 const int count,
1785 const EReductionType reductType,
1786 const int root,
1787 const Comm<int>& comm)
1788{
1789 TEUCHOS_COMM_TIME_MONITOR
1790 ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1791 << ")");
1792 reduceImpl<unsigned long> (sendBuf, recvBuf, count, reductType, root, comm);
1793}
1794
1795template<>
1796void
1797reduce<int, unsigned long long > (const unsigned long long sendBuf[],
1798 unsigned long long recvBuf[],
1799 const int count,
1800 const EReductionType reductType,
1801 const int root,
1802 const Comm<int>& comm)
1803{
1804 TEUCHOS_COMM_TIME_MONITOR
1805 ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1806 << ")");
1807 reduceImpl<unsigned long long> (sendBuf, recvBuf, count, reductType, root, comm);
1808}
1809
1810template<>
1811void
1812reduce<int, double> (const double sendBuf[],
1813 double recvBuf[],
1814 const int count,
1815 const EReductionType reductType,
1816 const int root,
1817 const Comm<int>& comm)
1818{
1819 TEUCHOS_COMM_TIME_MONITOR
1820 ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1821 << ")");
1822 reduceImpl<double> (sendBuf, recvBuf, count, reductType, root, comm);
1823}
1824template<>
1825void
1826reduceAll<int, int> (const Comm<int>& comm,
1827 const EReductionType reductType,
1828 const int count,
1829 const int sendBuffer[],
1830 int globalReducts[])
1831{
1832 TEUCHOS_COMM_TIME_MONITOR(
1833 "Teuchos::reduceAll<int, int> (" << count << ", "
1834 << toString (reductType) << ")"
1835 );
1836 reduceAllImpl<int> (comm, reductType, count, sendBuffer, globalReducts);
1837}
1838
1839template<>
1840RCP<Teuchos::CommRequest<int> >
1841ireceive<int, int> (const Comm<int>& comm,
1842 const ArrayRCP<int>& recvBuffer,
1843 const int sourceRank)
1844{
1845 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, int>");
1846 return ireceiveImpl<int> (comm, recvBuffer, sourceRank);
1847}
1848
1849template<>
1850RCP<Teuchos::CommRequest<int> >
1851ireceive<int, int> (const ArrayRCP<int>& recvBuffer,
1852 const int sourceRank,
1853 const int tag,
1854 const Comm<int>& comm)
1855{
1856 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, int>");
1857 return ireceiveImpl<int> (recvBuffer, sourceRank, tag, comm);
1858}
1859
1860template<>
1861void
1862send<int, int> (const Comm<int>& comm,
1863 const int count,
1864 const int sendBuffer[],
1865 const int destRank)
1866{
1867 return sendImpl<int> (comm, count, sendBuffer, destRank);
1868}
1869
1870template<>
1871void
1872send<int, int> (const int sendBuffer[],
1873 const int count,
1874 const int destRank,
1875 const int tag,
1876 const Comm<int>& comm)
1877{
1878 return sendImpl<int> (sendBuffer, count, destRank, tag, comm);
1879}
1880
1881template<>
1882RCP<Teuchos::CommRequest<int> >
1883isend (const ArrayRCP<const int>& sendBuffer,
1884 const int destRank,
1885 const int tag,
1886 const Comm<int>& comm)
1887{
1888 return isendImpl<int> (sendBuffer, destRank, tag, comm);
1889}
1890
1891// Specialization for Ordinal=int and Packet=unsigned int.
1892template<>
1893void
1894gather<int, unsigned int> (const unsigned int sendBuf[],
1895 const int sendCount,
1896 unsigned int recvBuf[],
1897 const int recvCount,
1898 const int root,
1899 const Comm<int>& comm)
1900{
1901 gatherImpl<unsigned int> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1902}
1903
1904template<>
1905void
1906gatherv<int, unsigned int> (const unsigned int sendBuf[],
1907 const int sendCount,
1908 unsigned int recvBuf[],
1909 const int recvCounts[],
1910 const int displs[],
1911 const int root,
1912 const Comm<int>& comm)
1913{
1914 gathervImpl<unsigned int> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1915}
1916
1917template<>
1918void
1919reduceAll<int, unsigned int> (const Comm<int>& comm,
1920 const EReductionType reductType,
1921 const int count,
1922 const unsigned int sendBuffer[],
1923 unsigned int globalReducts[])
1924{
1925 TEUCHOS_COMM_TIME_MONITOR(
1926 "Teuchos::reduceAll<int, unsigned int> (" << count << ", "
1927 << toString (reductType) << ")"
1928 );
1929 reduceAllImpl<unsigned int> (comm, reductType, count, sendBuffer, globalReducts);
1930}
1931
1932template<>
1933RCP<Teuchos::CommRequest<int> >
1934ireceive<int, unsigned int> (const Comm<int>& comm,
1935 const ArrayRCP<unsigned int>& recvBuffer,
1936 const int sourceRank)
1937{
1938 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned int>");
1939 return ireceiveImpl<unsigned int> (comm, recvBuffer, sourceRank);
1940}
1941
1942template<>
1943RCP<Teuchos::CommRequest<int> >
1944ireceive<int, unsigned int> (const ArrayRCP<unsigned int>& recvBuffer,
1945 const int sourceRank,
1946 const int tag,
1947 const Comm<int>& comm)
1948{
1949 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned int>");
1950 return ireceiveImpl<unsigned int> (recvBuffer, sourceRank, tag, comm);
1951}
1952
1953template<>
1954void
1955send<int, unsigned int> (const Comm<int>& comm,
1956 const int count,
1957 const unsigned int sendBuffer[],
1958 const int destRank)
1959{
1960 return sendImpl<unsigned int> (comm, count, sendBuffer, destRank);
1961}
1962
1963template<>
1964void
1965send<int, unsigned int> (const unsigned int sendBuffer[],
1966 const int count,
1967 const int destRank,
1968 const int tag,
1969 const Comm<int>& comm)
1970{
1971 return sendImpl<unsigned int> (sendBuffer, count, destRank, tag, comm);
1972}
1973
1974template<>
1975RCP<Teuchos::CommRequest<int> >
1976isend (const ArrayRCP<const unsigned int>& sendBuffer,
1977 const int destRank,
1978 const int tag,
1979 const Comm<int>& comm)
1980{
1981 return isendImpl<unsigned int> (sendBuffer, destRank, tag, comm);
1982}
1983
1984
1985// Specialization for Ordinal=int and Packet=short.
1986template<>
1987void
1988gather<int, short> (const short sendBuf[],
1989 const int sendCount,
1990 short recvBuf[],
1991 const int recvCount,
1992 const int root,
1993 const Comm<int>& comm)
1994{
1995 gatherImpl<short> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1996}
1997
1998template<>
1999void
2000gatherv<int, short> (const short sendBuf[],
2001 const int sendCount,
2002 short recvBuf[],
2003 const int recvCounts[],
2004 const int displs[],
2005 const int root,
2006 const Comm<int>& comm)
2007{
2008 gathervImpl<short> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
2009}
2010
2011template<>
2012void
2013reduceAll<int, short> (const Comm<int>& comm,
2014 const EReductionType reductType,
2015 const int count,
2016 const short sendBuffer[],
2017 short globalReducts[])
2018{
2019 TEUCHOS_COMM_TIME_MONITOR(
2020 "Teuchos::reduceAll<int, short> (" << count << ", "
2021 << toString (reductType) << ")"
2022 );
2023 reduceAllImpl<short> (comm, reductType, count, sendBuffer, globalReducts);
2024}
2025
2026template<>
2027RCP<Teuchos::CommRequest<int> >
2028ireceive<int, short> (const Comm<int>& comm,
2029 const ArrayRCP<short>& recvBuffer,
2030 const int sourceRank)
2031{
2032 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, short>");
2033 return ireceiveImpl<short> (comm, recvBuffer, sourceRank);
2034}
2035
2036template<>
2037RCP<Teuchos::CommRequest<int> >
2038ireceive<int, short> (const ArrayRCP<short>& recvBuffer,
2039 const int sourceRank,
2040 const int tag,
2041 const Comm<int>& comm)
2042{
2043 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, short>");
2044 return ireceiveImpl<short> (recvBuffer, sourceRank, tag, comm);
2045}
2046
2047template<>
2048void
2049send<int, short> (const Comm<int>& comm,
2050 const int count,
2051 const short sendBuffer[],
2052 const int destRank)
2053{
2054 return sendImpl<short> (comm, count, sendBuffer, destRank);
2055}
2056
2057template<>
2058void
2059send<int, short> (const short sendBuffer[],
2060 const int count,
2061 const int destRank,
2062 const int tag,
2063 const Comm<int>& comm)
2064{
2065 return sendImpl<short> (sendBuffer, count, destRank, tag, comm);
2066}
2067
2068template<>
2069RCP<Teuchos::CommRequest<int> >
2070isend (const ArrayRCP<const short>& sendBuffer,
2071 const int destRank,
2072 const int tag,
2073 const Comm<int>& comm)
2074{
2075 return isendImpl<short> (sendBuffer, destRank, tag, comm);
2076}
2077
2078// mfh 18 Oct 2012: The specialization for Packet=char seems to be
2079// causing problems such as the following:
2080//
2081// http://testing.sandia.gov/cdash/testDetails.php?test=9909246&build=747699
2082//
2083// I am disabling it for now. This should revert back to the old
2084// behavior for Packet=char. That should fix the Tpetra errors, since
2085// many Tpetra objects inherit from DistObject<char, ...>.
2086#if 0
2087// Specialization for Ordinal=int and Packet=char.
2088template<>
2089void
2090reduceAll<int, char> (const Comm<int>& comm,
2091 const EReductionType reductType,
2092 const int count,
2093 const char sendBuffer[],
2094 char globalReducts[])
2095{
2096 TEUCHOS_COMM_TIME_MONITOR(
2097 "Teuchos::reduceAll<int, char> (" << count << ", "
2098 << toString (reductType) << ")"
2099 );
2100 reduceAllImpl<char> (comm, reductType, count, sendBuffer, globalReducts);
2101}
2102#endif // 0
2103
2104} // namespace Teuchos
Declaration of Teuchos::Details::MpiTypeTraits (only if building with MPI)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
Namespace of implementation details.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...