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
52template<class T>
53void
54reduceAllImpl (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
122template<class T>
123void
124gatherImpl (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
176template<class T>
177void
178scatterImpl (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
223template<class T>
224void
225scattervImpl (const T sendBuf[],
226 const int sendCounts[],
227 const int displs[],
228 T recvBuf[],
229 const int recvCount,
230 const int root,
231 const Comm<int>& comm)
232{
233#ifdef HAVE_TEUCHOS_MPI
234 using Teuchos::Details::MpiTypeTraits;
235
236 // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
237 // SerialComm or an MpiComm. If it's something else, we fall back
238 // to the most general implementation.
239 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
240 if (mpiComm == NULL) {
241 // Is it a SerialComm?
242 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
243 if (serialComm == NULL) {
244 // We don't know what kind of Comm we have, so fall back to the
245 // most general implementation.
246 scatterv<int, T> (sendBuf, sendCounts, displs, recvBuf, recvCount, root, comm);
247 }
248 else { // It's a SerialComm; there is only 1 process, so just copy.
249 std::copy (sendBuf, sendBuf + sendCounts[0], recvBuf);
250 }
251 } else { // It's an MpiComm. Invoke MPI directly.
252 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
253 T t;
254 MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
255 const int err =
256 MPI_Scatterv (const_cast<T*> (sendBuf), sendCounts, displs, rawMpiType,
257 recvBuf, recvCount, rawMpiType,
258 root, rawMpiComm);
260 (err != MPI_SUCCESS, std::runtime_error,
261 "MPI_Scatter failed with the following error: "
262 << ::Teuchos::Details::getMpiErrorString (err));
263 }
264#else
265 // We've built without MPI, so just assume it's a SerialComm and
266 // copy the data.
267 std::copy (sendBuf, sendBuf + sendCounts[0], recvBuf);
268#endif // HAVE_TEUCHOS_MPI
269}
270
271
279template<class T>
280void
281reduceImpl (const T sendBuf[],
282 T recvBuf[],
283 const int count,
284 const EReductionType reductType,
285 const int root,
286 const Comm<int>& comm)
287{
288#ifdef HAVE_TEUCHOS_MPI
289 using Teuchos::Details::MpiTypeTraits;
290
291 // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
292 // SerialComm or an MpiComm. If it's something else, we fall back
293 // to the most general implementation.
294 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
295 if (mpiComm == NULL) {
296 // Is it a SerialComm?
297 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
298 if (serialComm == NULL) {
299 // We don't know what kind of Comm we have, so fall back to the
300 // most general implementation.
301 reduce<int, T> (sendBuf, recvBuf, count, reductType, root, comm);
302 }
303 else { // It's a SerialComm; there is only 1 process, so just copy.
304 std::copy (sendBuf, sendBuf + count, recvBuf);
305 }
306 } else { // It's an MpiComm. Invoke MPI directly.
307 MPI_Op rawMpiOp = ::Teuchos::Details::getMpiOpForEReductionType (reductType);
308 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
309 T t;
310 MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
311 const int err = MPI_Reduce (const_cast<T*> (sendBuf), recvBuf, count,
312 rawMpiType, rawMpiOp, root, rawMpiComm);
314 (err != MPI_SUCCESS, std::runtime_error, "MPI_Reduce failed with the "
315 "following error: " << ::Teuchos::Details::getMpiErrorString (err));
316 }
317#else
318 // We've built without MPI, so just assume it's a SerialComm and copy the data.
319 std::copy (sendBuf, sendBuf + count, recvBuf);
320#endif // HAVE_TEUCHOS_MPI
321}
322
323
331template<class T>
332void
333gathervImpl (const T sendBuf[],
334 const int sendCount,
335 T recvBuf[],
336 const int recvCounts[],
337 const int displs[],
338 const int root,
339 const Comm<int>& comm)
340{
341#ifdef HAVE_TEUCHOS_MPI
342 using Teuchos::Details::MpiTypeTraits;
343
344 // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
345 // SerialComm or an MpiComm. If it's something else, we fall back
346 // to the most general implementation.
347 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
348 if (mpiComm == NULL) {
349 // Is it a SerialComm?
350 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
351 if (serialComm == NULL) {
352 // We don't know what kind of Comm we have, so fall back to the
353 // most general implementation.
354 gatherv<int, T> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
355 }
356 else { // It's a SerialComm; there is only 1 process, so just copy.
358 recvCounts[0] > sendCount, std::invalid_argument,
359 "Teuchos::gatherv: If the input communicator contains only one "
360 "process, then you cannot receive more entries than you send. "
361 "You aim to receive " << recvCounts[0] << " entries, but to send "
362 << sendCount << " entries.");
363 // Serial communicator case: just copy. recvCounts[0] is the
364 // amount to receive, so it's the amount to copy. Start writing
365 // to recvbuf at the offset displs[0].
366 std::copy (sendBuf, sendBuf + recvCounts[0], recvBuf + displs[0]);
367 }
368 } else { // It's an MpiComm. Invoke MPI directly.
369 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
370 T t;
371 MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
372 const int err = MPI_Gatherv (const_cast<T*> (sendBuf),
373 sendCount,
374 rawMpiType,
375 recvBuf,
376 const_cast<int*> (recvCounts),
377 const_cast<int*> (displs),
378 rawMpiType,
379 root,
380 rawMpiComm);
382 err != MPI_SUCCESS,
383 std::runtime_error,
384 "MPI_Gatherv failed with the following error: "
385 << ::Teuchos::Details::getMpiErrorString (err));
386 }
387#else
388 // We've built without MPI, so just assume it's a SerialComm and copy the data.
390 recvCounts[0] > sendCount, std::invalid_argument,
391 "Teuchos::gatherv: If the input communicator contains only one "
392 "process, then you cannot receive more entries than you send. "
393 "You aim to receive " << recvCounts[0] << " entries, but to send "
394 << sendCount << " entries.");
395 // Serial communicator case: just copy. recvCounts[0] is the
396 // amount to receive, so it's the amount to copy. Start writing
397 // to recvbuf at the offset displs[0].
398 std::copy (sendBuf, sendBuf + recvCounts[0], recvBuf + displs[0]);
399#endif // HAVE_TEUCHOS_MPI
400}
401
407template<typename Packet>
409ireceiveGeneral(const Comm<int>& comm,
410 const ArrayRCP<Packet> &recvBuffer,
411 const int sourceRank)
412{
413 TEUCHOS_COMM_TIME_MONITOR(
414 "Teuchos::ireceive<int, " << "," << TypeNameTraits<Packet>::name ()
415 << "> ( value type )"
416 );
418 charRecvBuffer (recvBuffer.size (), recvBuffer.getRawPtr ());
419 RCP<CommRequest<int> > commRequest =
420 comm.ireceive (charRecvBuffer.getCharBufferView (), sourceRank);
421 set_extra_data (recvBuffer, "buffer", inOutArg (commRequest));
422 return commRequest;
423}
424
427template<typename Packet>
429ireceiveGeneral (const ArrayRCP<Packet> &recvBuffer,
430 const int sourceRank,
431 const int tag,
432 const Comm<int>& comm)
433{
434 TEUCHOS_COMM_TIME_MONITOR(
435 "Teuchos::ireceive<int, " << "," << TypeNameTraits<Packet>::name ()
436 << "> ( value type )"
437 );
439 charRecvBuffer (recvBuffer.size (), recvBuffer.getRawPtr ());
440 RCP<CommRequest<int> > commRequest =
441 comm.ireceive (charRecvBuffer.getCharBufferView (), sourceRank, tag);
442 set_extra_data (recvBuffer, "buffer", inOutArg (commRequest));
443 return commRequest;
444}
445
458template<class T>
460ireceiveImpl (const Comm<int>& comm,
461 const ArrayRCP<T>& recvBuffer,
462 const int sourceRank)
463{
464#ifdef HAVE_TEUCHOS_MPI
465 using Teuchos::Details::MpiTypeTraits;
466
467 // Even in an MPI build, Comm might be either a SerialComm or an
468 // MpiComm. If it's something else, we fall back to the most
469 // general implementation.
470 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
471 if (mpiComm == NULL) {
472 // Is it a SerialComm?
473 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
474 if (serialComm == NULL) {
475 // We don't know what kind of Comm we have, so fall back to the
476 // most general implementation.
477 return ireceiveGeneral<T> (comm, recvBuffer, sourceRank);
478 }
479 else { // SerialComm doesn't implement ireceive anyway.
481 true,
482 std::logic_error,
483 "ireceiveImpl: Not implemented for a serial communicator.");
484 }
485 }
486 else { // It's an MpiComm. Invoke MPI directly.
487 MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
488 T t;
489 MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
490 T* rawRecvBuf = recvBuffer.getRawPtr ();
491 const int count = as<int> (recvBuffer.size ());
492 const int tag = mpiComm->getTag ();
493 MPI_Request rawRequest = MPI_REQUEST_NULL;
494 const int err = MPI_Irecv (rawRecvBuf, count, rawType, sourceRank, tag,
495 rawComm, &rawRequest);
497 err != MPI_SUCCESS, std::runtime_error,
498 "MPI_Irecv failed with the following error: "
499 << ::Teuchos::Details::getMpiErrorString (err));
500
503 RCP<Details::MpiCommRequest> req (new Details::MpiCommRequest (rawRequest, buf));
505 }
506#else
508 true,
509 std::logic_error,
510 "ireceiveImpl: Not implemented for a serial communicator.");
511
512 // NOTE (mfh 15 Sep 2014): Most compilers have figured out that the
513 // return statement below is unreachable. Some older compilers
514 // might not realize this. That's why the return statement was put
515 // there, so that those compilers don't warn that this function
516 // doesn't return a value. If it's a choice between one warning and
517 // another, I would prefer the choice that produces less code and
518 // doesn't have unreachable code (which never gets tested).
519
520 //return null; // Guard to avoid compiler warning about not returning a value.
521#endif // HAVE_TEUCHOS_MPI
522}
523
526template<class T>
528ireceiveImpl (const ArrayRCP<T>& recvBuffer,
529 const int sourceRank,
530 const int tag,
531 const Comm<int>& comm)
532{
533#ifdef HAVE_TEUCHOS_MPI
534 using Teuchos::Details::MpiTypeTraits;
535
536 // Even in an MPI build, Comm might be either a SerialComm or an
537 // MpiComm. If it's something else, we fall back to the most
538 // general implementation.
539 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
540 if (mpiComm == NULL) {
541 // Is it a SerialComm?
542 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
543 if (serialComm == NULL) {
544 // We don't know what kind of Comm we have, so fall back to the
545 // most general implementation.
546 return ireceiveGeneral<T> (recvBuffer, sourceRank, tag, comm);
547 }
548 else { // SerialComm doesn't implement ireceive anyway.
550 true,
551 std::logic_error,
552 "ireceiveImpl: Not implemented for a serial communicator.");
553 }
554 }
555 else { // It's an MpiComm. Invoke MPI directly.
556 MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
557 T t;
558 MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
559 T* rawRecvBuf = recvBuffer.getRawPtr ();
560 const int count = as<int> (recvBuffer.size ());
561 MPI_Request rawRequest = MPI_REQUEST_NULL;
562 const int err = MPI_Irecv (rawRecvBuf, count, rawType, sourceRank, tag,
563 rawComm, &rawRequest);
565 err != MPI_SUCCESS, std::runtime_error,
566 "MPI_Irecv failed with the following error: "
567 << ::Teuchos::Details::getMpiErrorString (err));
568
571 RCP<Details::MpiCommRequest> req (new Details::MpiCommRequest (rawRequest, buf));
573 }
574#else
576 true,
577 std::logic_error,
578 "ireceiveImpl: Not implemented for a serial communicator.");
579
580 return null; // Guard to avoid compiler warning about not returning a value.
581#endif // HAVE_TEUCHOS_MPI
582}
583
589template<class T>
590void
591sendGeneral (const Comm<int>& comm,
592 const int count,
593 const T sendBuffer[],
594 const int destRank)
595{
596 TEUCHOS_COMM_TIME_MONITOR(
597 "Teuchos::send<int, " << TypeNameTraits<T>::name () << ">");
598 ConstValueTypeSerializationBuffer<int,T> charSendBuffer (count, sendBuffer);
599 comm.send (charSendBuffer.getBytes (),
600 charSendBuffer.getCharBuffer (),
601 destRank);
602}
603
606template<class T>
607void
608sendGeneral (const T sendBuffer[],
609 const int count,
610 const int destRank,
611 const int tag,
612 const Comm<int>& comm)
613{
614 TEUCHOS_COMM_TIME_MONITOR(
615 "Teuchos::send<int, " << TypeNameTraits<T>::name () << ">");
616 ConstValueTypeSerializationBuffer<int,T> charSendBuffer (count, sendBuffer);
617 comm.send (charSendBuffer.getBytes (),
618 charSendBuffer.getCharBuffer (),
619 destRank, tag);
620}
621
634template<class T>
635void
636sendImpl (const Comm<int>& comm,
637 const int count,
638 const T sendBuffer[],
639 const int destRank)
640{
641#ifdef HAVE_TEUCHOS_MPI
642 using Teuchos::Details::MpiTypeTraits;
643
644 // Even in an MPI build, Comm might be either a SerialComm or an
645 // MpiComm. If it's something else, we fall back to the most
646 // general implementation.
647 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
648 if (mpiComm == NULL) {
649 // Is it a SerialComm?
650 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
651 if (serialComm == NULL) {
652 // We don't know what kind of Comm we have, so fall back to the
653 // most general implementation.
654 sendGeneral<T> (comm, count, sendBuffer, destRank);
655 }
656 else { // SerialComm doesn't implement send correctly anyway.
658 true,
659 std::logic_error,
660 "sendImpl: Not implemented for a serial communicator.");
661 }
662 }
663 else { // It's an MpiComm. Invoke MPI directly.
664 MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
665 T t;
666 MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
667 T* rawBuf = const_cast<T*> (sendBuffer);
668 const int tag = mpiComm->getTag ();
669 const int err = MPI_Send (rawBuf, count, rawType, destRank, tag, rawComm);
671 err != MPI_SUCCESS,
672 std::runtime_error,
673 "MPI_Send failed with the following error: "
674 << ::Teuchos::Details::getMpiErrorString (err));
675 }
676#else
678 true,
679 std::logic_error,
680 "sendImpl: Not implemented for a serial communicator.");
681#endif // HAVE_TEUCHOS_MPI
682}
683
686template<class T>
687void
688sendImpl (const T sendBuffer[],
689 const int count,
690 const int destRank,
691 const int tag,
692 const Comm<int>& comm)
693{
694#ifdef HAVE_TEUCHOS_MPI
695 using Teuchos::Details::MpiTypeTraits;
696
697 // Even in an MPI build, Comm might be either a SerialComm or an
698 // MpiComm. If it's something else, we fall back to the most
699 // general implementation.
700 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
701 if (mpiComm == NULL) {
702 // Is it a SerialComm?
703 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
704 if (serialComm == NULL) {
705 // We don't know what kind of Comm we have, so fall back to the
706 // most general implementation.
707 sendGeneral<T> (sendBuffer, count, destRank, tag, comm);
708 }
709 else { // SerialComm doesn't implement send correctly anyway.
711 true,
712 std::logic_error,
713 "sendImpl: Not implemented for a serial communicator.");
714 }
715 }
716 else { // It's an MpiComm. Invoke MPI directly.
717 MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
718 T t;
719 MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
720 T* rawBuf = const_cast<T*> (sendBuffer);
721 const int err = MPI_Send (rawBuf, count, rawType, destRank, tag, rawComm);
723 err != MPI_SUCCESS,
724 std::runtime_error,
725 "MPI_Send failed with the following error: "
726 << ::Teuchos::Details::getMpiErrorString (err));
727 }
728#else
730 true,
731 std::logic_error,
732 "sendImpl: Not implemented for a serial communicator.");
733#endif // HAVE_TEUCHOS_MPI
734}
735
741template<class T>
743isendGeneral (const Comm<int>& comm,
744 const ArrayRCP<const T>& sendBuffer,
745 const int destRank)
746{
747 TEUCHOS_COMM_TIME_MONITOR(
748 "Teuchos::isend<int," << TypeNameTraits<T>::name () << ">");
750 charSendBuffer (sendBuffer.size (), sendBuffer.getRawPtr ());
751 RCP<CommRequest<int> > commRequest =
752 comm.isend (charSendBuffer.getCharBufferView (), destRank);
753 set_extra_data (sendBuffer, "buffer", inOutArg (commRequest));
754 return commRequest;
755}
756
763template<class T>
765isendGeneral (const ArrayRCP<const T>& sendBuffer,
766 const int destRank,
767 const int tag,
768 const Comm<int>& comm)
769{
770 TEUCHOS_COMM_TIME_MONITOR(
771 "Teuchos::isend<int," << TypeNameTraits<T>::name () << ">");
773 charSendBuffer (sendBuffer.size (), sendBuffer.getRawPtr ());
774 RCP<CommRequest<int> > commRequest =
775 comm.isend (charSendBuffer.getCharBufferView (), destRank, tag);
776 set_extra_data (sendBuffer, "buffer", inOutArg (commRequest));
777 return commRequest;
778}
779
782template<class T>
784isendImpl (const ArrayRCP<const T>& sendBuffer,
785 const int destRank,
786 const int tag,
787 const Comm<int>& comm)
788{
789#ifdef HAVE_TEUCHOS_MPI
790 using Teuchos::Details::MpiTypeTraits;
791
792 // Even in an MPI build, Comm might be either a SerialComm or an
793 // MpiComm. If it's something else, we fall back to the most
794 // general implementation.
795 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
796 if (mpiComm == NULL) {
797 // Is it a SerialComm?
798 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
799 if (serialComm == NULL) {
800 // We don't know what kind of Comm we have, so fall back to the
801 // most general implementation.
802 return isendGeneral<T> (sendBuffer, destRank, tag, comm);
803 }
804 else { // SerialComm doesn't implement send correctly anyway.
806 true, std::logic_error,
807 "isendImpl: Not implemented for a serial communicator.");
808 }
809 }
810 else { // It's an MpiComm. Invoke MPI directly.
811 MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
812 T t;
813 MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
814 // MPI promises not to modify the send buffer; the const_cast
815 // merely ensures compatibilty with C89, which does not have a
816 // "const" keyword.
817 T* rawSendBuf = const_cast<T*> (sendBuffer.getRawPtr ());
818 const int count = as<int> (sendBuffer.size ());
819 MPI_Request rawRequest = MPI_REQUEST_NULL;
820 const int err = MPI_Isend (rawSendBuf, count, rawType, destRank, tag,
821 rawComm, &rawRequest);
823 err != MPI_SUCCESS,
824 std::runtime_error,
825 "MPI_Isend failed with the following error: "
826 << ::Teuchos::Details::getMpiErrorString (err));
827
829 RCP<Details::MpiCommRequest> req (new Details::MpiCommRequest (rawRequest, buf));
831 }
832#else
834 true,
835 std::logic_error,
836 "isendImpl: Not implemented for a serial communicator.");
837#endif // HAVE_TEUCHOS_MPI
838}
839
840} // namespace (anonymous)
841
842
843// mfh 18 Oct 2012: Note on full template specializations
844//
845// To make Windows builds happy, declarations of full template
846// specializations (as found in Teuchos_CommHelpers.hpp) must use the
847// TEUCHOSCOMM_LIB_DLL_EXPORT macro. However, _definitions_ of the
848// specializations (as found in this file) must _not_ use the macro.
849// That's why we don't use that macro here.
850
851// amb See note in .hpp file.
852#if 0
853#ifdef HAVE_TEUCHOS_COMPLEX
854// Specialization for Ordinal=int and Packet=std::complex<double>.
855template<>
856void
858 const EReductionType reductType,
859 const int count,
860 const std::complex<double> sendBuffer[],
861 std::complex<double> globalReducts[])
862{
863 TEUCHOS_COMM_TIME_MONITOR(
864 "Teuchos::reduceAll<int, std::complex<double> > (" << count << ", "
865 << toString (reductType) << ")"
866 );
867 reduceAllImpl<std::complex<double> > (comm, reductType, count, sendBuffer, globalReducts);
868}
869
870template<>
873 const ArrayRCP<std::complex<double> >& recvBuffer,
874 const int sourceRank)
875{
876 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<double> >");
877 return ireceiveImpl<std::complex<double> > (comm, recvBuffer, sourceRank);
878}
879
880template<>
883 const int sourceRank,
884 const int tag,
885 const Comm<int>& comm)
886{
887 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<double> >");
888 return ireceiveImpl<std::complex<double> > (recvBuffer, sourceRank, tag, comm);
889}
890
891template<>
892void
894 const int count,
895 const std::complex<double> sendBuffer[],
896 const int destRank)
897{
898 sendImpl<std::complex<double> > (comm, count, sendBuffer, destRank);
899}
900
901template<>
902void
903send<int, std::complex<double> > (const std::complex<double> sendBuffer[],
904 const int count,
905 const int destRank,
906 const int tag,
907 const Comm<int>& comm)
908{
909 sendImpl<std::complex<double> > (sendBuffer, count, destRank, tag, comm);
910}
911
912template<>
914isend (const ArrayRCP<const std::complex<double> >& sendBuffer,
915 const int destRank,
916 const int tag,
917 const Comm<int>& comm)
918{
919 return isendImpl<std::complex<double> > (sendBuffer, destRank, tag, comm);
920}
921
922// Specialization for Ordinal=int and Packet=std::complex<float>.
923template<>
924void
926 const EReductionType reductType,
927 const int count,
928 const std::complex<float> sendBuffer[],
929 std::complex<float> globalReducts[])
930{
931 TEUCHOS_COMM_TIME_MONITOR(
932 "Teuchos::reduceAll<int, std::complex<float> > (" << count << ", "
933 << toString (reductType) << ")"
934 );
935 reduceAllImpl<std::complex<float> > (comm, reductType, count, sendBuffer, globalReducts);
936}
937
938template<>
941 const ArrayRCP<std::complex<float> >& recvBuffer,
942 const int sourceRank)
943{
944 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<float> >");
945 return ireceiveImpl<std::complex<float> > (comm, recvBuffer, sourceRank);
946}
947
948template<>
951 const int sourceRank,
952 const int tag,
953 const Comm<int>& comm)
954{
955 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<float> >");
956 return ireceiveImpl<std::complex<float> > (recvBuffer, sourceRank, tag, comm);
957}
958
959template<>
960void
962 const int count,
963 const std::complex<float> sendBuffer[],
964 const int destRank)
965{
966 return sendImpl<std::complex<float> > (comm, count, sendBuffer, destRank);
967}
968
969template<>
970void
971send<int, std::complex<float> > (const std::complex<float> sendBuffer[],
972 const int count,
973 const int destRank,
974 const int tag,
975 const Comm<int>& comm)
976{
977 return sendImpl<std::complex<float> > (sendBuffer, count, destRank, tag, comm);
978}
979
980template<>
982isend (const ArrayRCP<const std::complex<float> >& sendBuffer,
983 const int destRank,
984 const int tag,
985 const Comm<int>& comm)
986{
987 return isendImpl<std::complex<float> > (sendBuffer, destRank, tag, comm);
988}
989#endif // HAVE_TEUCHOS_COMPLEX
990#endif // if 0
991
992// Specialization for Ordinal=int and Packet=double.
993template<>
994void
996 const EReductionType reductType,
997 const int count,
998 const double sendBuffer[],
999 double globalReducts[])
1000{
1001 TEUCHOS_COMM_TIME_MONITOR(
1002 "Teuchos::reduceAll<int, double> (" << count << ", "
1003 << toString (reductType) << ")"
1004 );
1005 reduceAllImpl<double> (comm, reductType, count, sendBuffer, globalReducts);
1006}
1007
1008template<>
1010ireceive<int, double> (const Comm<int>& comm,
1011 const ArrayRCP<double>& recvBuffer,
1012 const int sourceRank)
1013{
1014 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, double>");
1015 return ireceiveImpl<double> (comm, recvBuffer, sourceRank);
1016}
1017
1018template<>
1020ireceive<int, double> (const ArrayRCP<double>& recvBuffer,
1021 const int sourceRank,
1022 const int tag,
1023 const Comm<int>& comm)
1024{
1025 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, double>");
1026 return ireceiveImpl<double> (recvBuffer, sourceRank, tag, comm);
1027}
1028
1029template<>
1030void
1031send<int, double> (const Comm<int>& comm,
1032 const int count,
1033 const double sendBuffer[],
1034 const int destRank)
1035{
1036 return sendImpl<double> (comm, count, sendBuffer, destRank);
1037}
1038
1039template<>
1040void
1041send<int, double> (const double sendBuffer[],
1042 const int count,
1043 const int destRank,
1044 const int tag,
1045 const Comm<int>& comm)
1046{
1047 return sendImpl<double> (sendBuffer, count, destRank, tag, comm);
1048}
1049
1050template<>
1052isend (const ArrayRCP<const double>& sendBuffer,
1053 const int destRank,
1054 const int tag,
1055 const Comm<int>& comm)
1056{
1057 return isendImpl<double> (sendBuffer, destRank, tag, comm);
1058}
1059
1060template<>
1061void
1062gatherv<int, double> (const double sendBuf[],
1063 const int sendCount,
1064 double recvBuf[],
1065 const int recvCounts[],
1066 const int displs[],
1067 const int root,
1068 const Comm<int>& comm)
1069{
1070 gathervImpl<double> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1071}
1072
1073
1074// Specialization for Ordinal=int and Packet=float.
1075template<>
1076void
1077reduceAll<int, float> (const Comm<int>& comm,
1078 const EReductionType reductType,
1079 const int count,
1080 const float sendBuffer[],
1081 float globalReducts[])
1082{
1083 TEUCHOS_COMM_TIME_MONITOR(
1084 "Teuchos::reduceAll<int, float> (" << count << ", "
1085 << toString (reductType) << ")"
1086 );
1087 reduceAllImpl<float> (comm, reductType, count, sendBuffer, globalReducts);
1088}
1089
1090template<>
1092ireceive<int, float> (const Comm<int>& comm,
1093 const ArrayRCP<float>& recvBuffer,
1094 const int sourceRank)
1095{
1096 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, float>");
1097 return ireceiveImpl<float> (comm, recvBuffer, sourceRank);
1098}
1099
1100template<>
1102ireceive<int, float> (const ArrayRCP<float>& recvBuffer,
1103 const int sourceRank,
1104 const int tag,
1105 const Comm<int>& comm)
1106{
1107 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, float>");
1108 return ireceiveImpl<float> (recvBuffer, sourceRank, tag, comm);
1109}
1110
1111template<>
1112void
1113send<int, float> (const Comm<int>& comm,
1114 const int count,
1115 const float sendBuffer[],
1116 const int destRank)
1117{
1118 return sendImpl<float> (comm, count, sendBuffer, destRank);
1119}
1120
1121template<>
1122void
1123send<int, float> (const float sendBuffer[],
1124 const int count,
1125 const int destRank,
1126 const int tag,
1127 const Comm<int>& comm)
1128{
1129 return sendImpl<float> (sendBuffer, count, destRank, tag, comm);
1130}
1131
1132template<>
1134isend (const ArrayRCP<const float>& sendBuffer,
1135 const int destRank,
1136 const int tag,
1137 const Comm<int>& comm)
1138{
1139 return isendImpl<float> (sendBuffer, destRank, tag, comm);
1140}
1141
1142template<>
1143void
1144gatherv<int,float> (const float sendBuf[],
1145 const int sendCount,
1146 float recvBuf[],
1147 const int recvCounts[],
1148 const int displs[],
1149 const int root,
1150 const Comm<int>& comm)
1151{
1152 gathervImpl<float> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1153}
1154
1155
1156// Specialization for Ordinal=int and Packet=long long.
1157template<>
1158void
1159gather<int, long long> (const long long sendBuf[],
1160 const int sendCount,
1161 long long recvBuf[],
1162 const int recvCount,
1163 const int root,
1164 const Comm<int>& comm)
1165{
1166 gatherImpl<long long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1167}
1168
1169template<>
1170void
1171gatherv<int, long long> (const long long sendBuf[],
1172 const int sendCount,
1173 long long recvBuf[],
1174 const int recvCounts[],
1175 const int displs[],
1176 const int root,
1177 const Comm<int>& comm)
1178{
1179 gathervImpl<long long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1180}
1181
1182template<>
1183void
1185 const EReductionType reductType,
1186 const int count,
1187 const long long sendBuffer[],
1188 long long globalReducts[])
1189{
1190 TEUCHOS_COMM_TIME_MONITOR(
1191 "Teuchos::reduceAll<int, long long> (" << count << ", "
1192 << toString (reductType) << ")"
1193 );
1194 reduceAllImpl<long long> (comm, reductType, count, sendBuffer, globalReducts);
1195}
1196
1197template<>
1200 const ArrayRCP<long long>& recvBuffer,
1201 const int sourceRank)
1202{
1203 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long long>");
1204 return ireceiveImpl<long long> (comm, recvBuffer, sourceRank);
1205}
1206
1207template<>
1210 const int sourceRank,
1211 const int tag,
1212 const Comm<int>& comm)
1213{
1214 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long long>");
1215 return ireceiveImpl<long long> (recvBuffer, sourceRank, tag, comm);
1216}
1217
1218template<>
1219void
1220send<int, long long> (const Comm<int>& comm,
1221 const int count,
1222 const long long sendBuffer[],
1223 const int destRank)
1224{
1225 return sendImpl<long long> (comm, count, sendBuffer, destRank);
1226}
1227
1228template<>
1229void
1230send<int, long long> (const long long sendBuffer[],
1231 const int count,
1232 const int destRank,
1233 const int tag,
1234 const Comm<int>& comm)
1235{
1236 return sendImpl<long long> (sendBuffer, count, destRank, tag, comm);
1237}
1238
1239template<>
1241isend (const ArrayRCP<const long long>& sendBuffer,
1242 const int destRank,
1243 const int tag,
1244 const Comm<int>& comm)
1245{
1246 return isendImpl<long long> (sendBuffer, destRank, tag, comm);
1247}
1248
1249// Specialization for Ordinal=int and Packet=unsigned long long.
1250template<>
1251void
1252gather<int, unsigned long long> (const unsigned long long sendBuf[],
1253 const int sendCount,
1254 unsigned long long recvBuf[],
1255 const int recvCount,
1256 const int root,
1257 const Comm<int>& comm)
1258{
1259 gatherImpl<unsigned long long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1260}
1261
1262template<>
1263void
1264gatherv<int, unsigned long long> (const unsigned long long sendBuf[],
1265 const int sendCount,
1266 unsigned long long recvBuf[],
1267 const int recvCounts[],
1268 const int displs[],
1269 const int root,
1270 const Comm<int>& comm)
1271{
1272 gathervImpl<unsigned long long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1273}
1274
1275template<>
1276void
1278 const EReductionType reductType,
1279 const int count,
1280 const unsigned long long sendBuffer[],
1281 unsigned long long globalReducts[])
1282{
1283 TEUCHOS_COMM_TIME_MONITOR(
1284 "Teuchos::reduceAll<int, unsigned long long> (" << count << ", "
1285 << toString (reductType) << ")"
1286 );
1287 reduceAllImpl<unsigned long long> (comm, reductType, count, sendBuffer, globalReducts);
1288}
1289
1290template<>
1293 const ArrayRCP<unsigned long long>& recvBuffer,
1294 const int sourceRank)
1295{
1296 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long long>");
1297 return ireceiveImpl<unsigned long long> (comm, recvBuffer, sourceRank);
1298}
1299
1300template<>
1303 const int sourceRank,
1304 const int tag,
1305 const Comm<int>& comm)
1306{
1307 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long long>");
1308 return ireceiveImpl<unsigned long long> (recvBuffer, sourceRank, tag, comm);
1309}
1310
1311template<>
1312void
1314 const int count,
1315 const unsigned long long sendBuffer[],
1316 const int destRank)
1317{
1318 return sendImpl<unsigned long long> (comm, count, sendBuffer, destRank);
1319}
1320
1321template<>
1322void
1323send<int, unsigned long long> (const unsigned long long sendBuffer[],
1324 const int count,
1325 const int destRank,
1326 const int tag,
1327 const Comm<int>& comm)
1328{
1329 return sendImpl<unsigned long long> (sendBuffer, count, destRank, tag, comm);
1330}
1331
1332template<>
1334isend (const ArrayRCP<const unsigned long long>& sendBuffer,
1335 const int destRank,
1336 const int tag,
1337 const Comm<int>& comm)
1338{
1339 return isendImpl<unsigned long long> (sendBuffer, destRank, tag, comm);
1340}
1341
1342
1343// Specialization for Ordinal=int and Packet=long.
1344template<>
1345void
1346gather<int, long> (const long sendBuf[],
1347 const int sendCount,
1348 long recvBuf[],
1349 const int recvCount,
1350 const int root,
1351 const Comm<int>& comm)
1352{
1353 gatherImpl<long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1354}
1355
1356template<>
1357void
1358gatherv<int, long> (const long sendBuf[],
1359 const int sendCount,
1360 long recvBuf[],
1361 const int recvCounts[],
1362 const int displs[],
1363 const int root,
1364 const Comm<int>& comm)
1365{
1366 gathervImpl<long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1367}
1368
1369template<>
1370void
1371reduceAll<int, long> (const Comm<int>& comm,
1372 const EReductionType reductType,
1373 const int count,
1374 const long sendBuffer[],
1375 long globalReducts[])
1376{
1377 TEUCHOS_COMM_TIME_MONITOR(
1378 "Teuchos::reduceAll<int, long> (" << count << ", "
1379 << toString (reductType) << ")"
1380 );
1381 reduceAllImpl<long> (comm, reductType, count, sendBuffer, globalReducts);
1382}
1383
1384template<>
1386ireceive<int, long> (const Comm<int>& comm,
1387 const ArrayRCP<long>& recvBuffer,
1388 const int sourceRank)
1389{
1390 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long>");
1391 return ireceiveImpl<long> (comm, recvBuffer, sourceRank);
1392}
1393
1394template<>
1396ireceive<int, long> (const ArrayRCP<long>& recvBuffer,
1397 const int sourceRank,
1398 const int tag,
1399 const Comm<int>& comm)
1400{
1401 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long>");
1402 return ireceiveImpl<long> (recvBuffer, sourceRank, tag, comm);
1403}
1404
1405template<>
1406void
1407send<int, long> (const Comm<int>& comm,
1408 const int count,
1409 const long sendBuffer[],
1410 const int destRank)
1411{
1412 return sendImpl<long> (comm, count, sendBuffer, destRank);
1413}
1414
1415template<>
1416void
1417send<int, long> (const long sendBuffer[],
1418 const int count,
1419 const int destRank,
1420 const int tag,
1421 const Comm<int>& comm)
1422{
1423 return sendImpl<long> (sendBuffer, count, destRank, tag, comm);
1424}
1425
1426template<>
1428isend (const ArrayRCP<const long>& sendBuffer,
1429 const int destRank,
1430 const int tag,
1431 const Comm<int>& comm)
1432{
1433 return isendImpl<long> (sendBuffer, destRank, tag, comm);
1434}
1435
1436
1437// Specialization for Ordinal=int and Packet=unsigned long.
1438template<>
1439void
1440gather<int, unsigned long> (const unsigned long sendBuf[],
1441 const int sendCount,
1442 unsigned long recvBuf[],
1443 const int recvCount,
1444 const int root,
1445 const Comm<int>& comm)
1446{
1447 gatherImpl<unsigned long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1448}
1449
1450template<>
1451void
1452gatherv<int, unsigned long> (const unsigned long sendBuf[],
1453 const int sendCount,
1454 unsigned long recvBuf[],
1455 const int recvCounts[],
1456 const int displs[],
1457 const int root,
1458 const Comm<int>& comm)
1459{
1460 gathervImpl<unsigned long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1461}
1462
1463template<>
1464void
1466 const EReductionType reductType,
1467 const int count,
1468 const unsigned long sendBuffer[],
1469 unsigned long globalReducts[])
1470{
1471 TEUCHOS_COMM_TIME_MONITOR(
1472 "Teuchos::reduceAll<int, unsigned long> (" << count << ", "
1473 << toString (reductType) << ")"
1474 );
1475 reduceAllImpl<unsigned long> (comm, reductType, count, sendBuffer, globalReducts);
1476}
1477
1478template<>
1481 const ArrayRCP<unsigned long>& recvBuffer,
1482 const int sourceRank)
1483{
1484 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long>");
1485 return ireceiveImpl<unsigned long> (comm, recvBuffer, sourceRank);
1486}
1487
1488template<>
1491 const int sourceRank,
1492 const int tag,
1493 const Comm<int>& comm)
1494{
1495 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long>");
1496 return ireceiveImpl<unsigned long> (recvBuffer, sourceRank, tag, comm);
1497}
1498
1499template<>
1500void
1502 const int count,
1503 const unsigned long sendBuffer[],
1504 const int destRank)
1505{
1506 return sendImpl<unsigned long> (comm, count, sendBuffer, destRank);
1507}
1508
1509template<>
1510void
1511send<int, unsigned long> (const unsigned long sendBuffer[],
1512 const int count,
1513 const int destRank,
1514 const int tag,
1515 const Comm<int>& comm)
1516{
1517 return sendImpl<unsigned long> (sendBuffer, count, destRank, tag, comm);
1518}
1519
1520template<>
1522isend (const ArrayRCP<const unsigned long>& sendBuffer,
1523 const int destRank,
1524 const int tag,
1525 const Comm<int>& comm)
1526{
1527 return isendImpl<unsigned long> (sendBuffer, destRank, tag, comm);
1528}
1529
1530// Specialization for Ordinal=int and Packet=int.
1531template<>
1532void
1533gather<int, int> (const int sendBuf[],
1534 const int sendCount,
1535 int recvBuf[],
1536 const int recvCount,
1537 const int root,
1538 const Comm<int>& comm)
1539{
1540 gatherImpl<int> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1541}
1542
1543template<>
1544void
1545gatherv<int, int> (const int sendBuf[],
1546 const int sendCount,
1547 int recvBuf[],
1548 const int recvCounts[],
1549 const int displs[],
1550 const int root,
1551 const Comm<int>& comm)
1552{
1553 gathervImpl<int> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1554}
1555
1556template<>
1557void
1558scatter<int, int> (const int sendBuf[],
1559 const int sendCount,
1560 int recvBuf[],
1561 const int recvCount,
1562 const int root,
1563 const Comm<int>& comm)
1564{
1565 scatterImpl<int> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1566}
1567
1568template<>
1569void
1570scatterv<int, double> (const double sendBuf[],
1571 const int sendCount[],
1572 const int displs[],
1573 double recvBuf[],
1574 const int recvCount,
1575 const int root,
1576 const Comm<int>& comm)
1577{
1578 scattervImpl<double> (sendBuf, sendCount, displs, recvBuf, recvCount, root, comm);
1579}
1580
1581template<>
1582void
1583scatterv<int, float> (const float sendBuf[],
1584 const int sendCounts[],
1585 const int displs[],
1586 float recvBuf[],
1587 const int recvCount,
1588 const int root,
1589 const Comm<int>& comm)
1590{
1591 scattervImpl<float> (sendBuf, sendCounts, displs, recvBuf, recvCount, root, comm);
1592}
1593
1594template<>
1595void
1596reduce<int, int> (const int sendBuf[],
1597 int recvBuf[],
1598 const int count,
1599 const EReductionType reductType,
1600 const int root,
1601 const Comm<int>& comm)
1602{
1603 TEUCHOS_COMM_TIME_MONITOR
1604 ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1605 << ")");
1606 reduceImpl<int> (sendBuf, recvBuf, count, reductType, root, comm);
1607}
1608template<>
1609void
1610reduce<int, long> (const long sendBuf[],
1611 long recvBuf[],
1612 const int count,
1613 const EReductionType reductType,
1614 const int root,
1615 const Comm<int>& comm)
1616{
1617 TEUCHOS_COMM_TIME_MONITOR
1618 ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1619 << ")");
1620 reduceImpl<long> (sendBuf, recvBuf, count, reductType, root, comm);
1621}
1622
1623template<>
1624void
1625reduce<int, unsigned long> (const unsigned long sendBuf[],
1626 unsigned long recvBuf[],
1627 const int count,
1628 const EReductionType reductType,
1629 const int root,
1630 const Comm<int>& comm)
1631{
1632 TEUCHOS_COMM_TIME_MONITOR
1633 ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1634 << ")");
1635 reduceImpl<unsigned long> (sendBuf, recvBuf, count, reductType, root, comm);
1636}
1637
1638template<>
1639void
1640reduce<int, unsigned long long > (const unsigned long long sendBuf[],
1641 unsigned long long recvBuf[],
1642 const int count,
1643 const EReductionType reductType,
1644 const int root,
1645 const Comm<int>& comm)
1646{
1647 TEUCHOS_COMM_TIME_MONITOR
1648 ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1649 << ")");
1650 reduceImpl<unsigned long long> (sendBuf, recvBuf, count, reductType, root, comm);
1651}
1652
1653template<>
1654void
1655reduce<int, double> (const double sendBuf[],
1656 double recvBuf[],
1657 const int count,
1658 const EReductionType reductType,
1659 const int root,
1660 const Comm<int>& comm)
1661{
1662 TEUCHOS_COMM_TIME_MONITOR
1663 ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1664 << ")");
1665 reduceImpl<double> (sendBuf, recvBuf, count, reductType, root, comm);
1666}
1667template<>
1668void
1669reduceAll<int, int> (const Comm<int>& comm,
1670 const EReductionType reductType,
1671 const int count,
1672 const int sendBuffer[],
1673 int globalReducts[])
1674{
1675 TEUCHOS_COMM_TIME_MONITOR(
1676 "Teuchos::reduceAll<int, int> (" << count << ", "
1677 << toString (reductType) << ")"
1678 );
1679 reduceAllImpl<int> (comm, reductType, count, sendBuffer, globalReducts);
1680}
1681
1682template<>
1684ireceive<int, int> (const Comm<int>& comm,
1685 const ArrayRCP<int>& recvBuffer,
1686 const int sourceRank)
1687{
1688 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, int>");
1689 return ireceiveImpl<int> (comm, recvBuffer, sourceRank);
1690}
1691
1692template<>
1694ireceive<int, int> (const ArrayRCP<int>& recvBuffer,
1695 const int sourceRank,
1696 const int tag,
1697 const Comm<int>& comm)
1698{
1699 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, int>");
1700 return ireceiveImpl<int> (recvBuffer, sourceRank, tag, comm);
1701}
1702
1703template<>
1704void
1705send<int, int> (const Comm<int>& comm,
1706 const int count,
1707 const int sendBuffer[],
1708 const int destRank)
1709{
1710 return sendImpl<int> (comm, count, sendBuffer, destRank);
1711}
1712
1713template<>
1714void
1715send<int, int> (const int sendBuffer[],
1716 const int count,
1717 const int destRank,
1718 const int tag,
1719 const Comm<int>& comm)
1720{
1721 return sendImpl<int> (sendBuffer, count, destRank, tag, comm);
1722}
1723
1724template<>
1726isend (const ArrayRCP<const int>& sendBuffer,
1727 const int destRank,
1728 const int tag,
1729 const Comm<int>& comm)
1730{
1731 return isendImpl<int> (sendBuffer, destRank, tag, comm);
1732}
1733
1734// Specialization for Ordinal=int and Packet=unsigned int.
1735template<>
1736void
1737gather<int, unsigned int> (const unsigned int sendBuf[],
1738 const int sendCount,
1739 unsigned int recvBuf[],
1740 const int recvCount,
1741 const int root,
1742 const Comm<int>& comm)
1743{
1744 gatherImpl<unsigned int> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1745}
1746
1747template<>
1748void
1749gatherv<int, unsigned int> (const unsigned int sendBuf[],
1750 const int sendCount,
1751 unsigned int recvBuf[],
1752 const int recvCounts[],
1753 const int displs[],
1754 const int root,
1755 const Comm<int>& comm)
1756{
1757 gathervImpl<unsigned int> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1758}
1759
1760template<>
1761void
1763 const EReductionType reductType,
1764 const int count,
1765 const unsigned int sendBuffer[],
1766 unsigned int globalReducts[])
1767{
1768 TEUCHOS_COMM_TIME_MONITOR(
1769 "Teuchos::reduceAll<int, unsigned int> (" << count << ", "
1770 << toString (reductType) << ")"
1771 );
1772 reduceAllImpl<unsigned int> (comm, reductType, count, sendBuffer, globalReducts);
1773}
1774
1775template<>
1778 const ArrayRCP<unsigned int>& recvBuffer,
1779 const int sourceRank)
1780{
1781 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned int>");
1782 return ireceiveImpl<unsigned int> (comm, recvBuffer, sourceRank);
1783}
1784
1785template<>
1788 const int sourceRank,
1789 const int tag,
1790 const Comm<int>& comm)
1791{
1792 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned int>");
1793 return ireceiveImpl<unsigned int> (recvBuffer, sourceRank, tag, comm);
1794}
1795
1796template<>
1797void
1799 const int count,
1800 const unsigned int sendBuffer[],
1801 const int destRank)
1802{
1803 return sendImpl<unsigned int> (comm, count, sendBuffer, destRank);
1804}
1805
1806template<>
1807void
1808send<int, unsigned int> (const unsigned int sendBuffer[],
1809 const int count,
1810 const int destRank,
1811 const int tag,
1812 const Comm<int>& comm)
1813{
1814 return sendImpl<unsigned int> (sendBuffer, count, destRank, tag, comm);
1815}
1816
1817template<>
1819isend (const ArrayRCP<const unsigned int>& sendBuffer,
1820 const int destRank,
1821 const int tag,
1822 const Comm<int>& comm)
1823{
1824 return isendImpl<unsigned int> (sendBuffer, destRank, tag, comm);
1825}
1826
1827
1828// Specialization for Ordinal=int and Packet=short.
1829template<>
1830void
1831gather<int, short> (const short sendBuf[],
1832 const int sendCount,
1833 short recvBuf[],
1834 const int recvCount,
1835 const int root,
1836 const Comm<int>& comm)
1837{
1838 gatherImpl<short> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1839}
1840
1841template<>
1842void
1843gatherv<int, short> (const short sendBuf[],
1844 const int sendCount,
1845 short recvBuf[],
1846 const int recvCounts[],
1847 const int displs[],
1848 const int root,
1849 const Comm<int>& comm)
1850{
1851 gathervImpl<short> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1852}
1853
1854template<>
1855void
1856reduceAll<int, short> (const Comm<int>& comm,
1857 const EReductionType reductType,
1858 const int count,
1859 const short sendBuffer[],
1860 short globalReducts[])
1861{
1862 TEUCHOS_COMM_TIME_MONITOR(
1863 "Teuchos::reduceAll<int, short> (" << count << ", "
1864 << toString (reductType) << ")"
1865 );
1866 reduceAllImpl<short> (comm, reductType, count, sendBuffer, globalReducts);
1867}
1868
1869template<>
1871ireceive<int, short> (const Comm<int>& comm,
1872 const ArrayRCP<short>& recvBuffer,
1873 const int sourceRank)
1874{
1875 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, short>");
1876 return ireceiveImpl<short> (comm, recvBuffer, sourceRank);
1877}
1878
1879template<>
1881ireceive<int, short> (const ArrayRCP<short>& recvBuffer,
1882 const int sourceRank,
1883 const int tag,
1884 const Comm<int>& comm)
1885{
1886 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, short>");
1887 return ireceiveImpl<short> (recvBuffer, sourceRank, tag, comm);
1888}
1889
1890template<>
1891void
1892send<int, short> (const Comm<int>& comm,
1893 const int count,
1894 const short sendBuffer[],
1895 const int destRank)
1896{
1897 return sendImpl<short> (comm, count, sendBuffer, destRank);
1898}
1899
1900template<>
1901void
1902send<int, short> (const short sendBuffer[],
1903 const int count,
1904 const int destRank,
1905 const int tag,
1906 const Comm<int>& comm)
1907{
1908 return sendImpl<short> (sendBuffer, count, destRank, tag, comm);
1909}
1910
1911template<>
1913isend (const ArrayRCP<const short>& sendBuffer,
1914 const int destRank,
1915 const int tag,
1916 const Comm<int>& comm)
1917{
1918 return isendImpl<short> (sendBuffer, destRank, tag, comm);
1919}
1920
1921// mfh 18 Oct 2012: The specialization for Packet=char seems to be
1922// causing problems such as the following:
1923//
1924// http://testing.sandia.gov/cdash/testDetails.php?test=9909246&build=747699
1925//
1926// I am disabling it for now. This should revert back to the old
1927// behavior for Packet=char. That should fix the Tpetra errors, since
1928// many Tpetra objects inherit from DistObject<char, ...>.
1929#if 0
1930// Specialization for Ordinal=int and Packet=char.
1931template<>
1932void
1933reduceAll<int, char> (const Comm<int>& comm,
1934 const EReductionType reductType,
1935 const int count,
1936 const char sendBuffer[],
1937 char globalReducts[])
1938{
1939 TEUCHOS_COMM_TIME_MONITOR(
1940 "Teuchos::reduceAll<int, char> (" << count << ", "
1941 << toString (reductType) << ")"
1942 );
1943 reduceAllImpl<char> (comm, reductType, count, sendBuffer, globalReducts);
1944}
1945#endif // 0
1946
1947} // namespace Teuchos
Declaration of Teuchos::Details::MpiTypeTraits (only if building with MPI).
Reference-counted smart pointer for managing arrays.
ArrayRCP< T2 > arcp_reinterpret_cast(const ArrayRCP< T1 > &p1)
Reinterpret cast of underlying ArrayRCP type from T1* to T2*.
void set_extra_data(const T1 &extra_data, const std::string &name, const Ptr< ArrayRCP< T2 > > &p, EPrePostDestruction destroy_when=POST_DESTROY, bool force_unique=true)
Set extra data associated with a ArrayRCP object.
ArrayRCP< T2 > arcp_const_cast(const ArrayRCP< T1 > &p1)
Const cast of underlying ArrayRCP type from const T* to T*.
Abstract interface for distributed-memory communication.
void reduce(const Packet sendBuf[], Packet recvBuf[], const Ordinal count, const EReductionType reductType, const Ordinal root, const Comm< Ordinal > &comm)
Wrapper for MPI_Reduce; reduction to one process, using a built-in reduction operator selected by enu...
void gather(const Packet sendBuf[], const Ordinal sendCount, Packet recvBuf[], const Ordinal recvCount, const int root, const Comm< Ordinal > &comm)
Gather values from each process to the root process.
void gatherv(const Packet sendBuf[], const Ordinal sendCount, Packet recvBuf[], const Ordinal recvCounts[], const Ordinal displs[], const int root, const Comm< Ordinal > &comm)
Gather arrays of possibly different lengths from each process to the root process.
void reduceAll(const Comm< Ordinal > &comm, const ValueTypeReductionOp< Ordinal, Packet > &reductOp, const Ordinal count, const Packet sendBuffer[], Packet globalReducts[])
Wrapper for MPI_Allreduce that takes a custom reduction operator.
Encapsulate how an array of const objects with value sematics is serialized into a const char[] array...
MPI implementation of CommRequest<int>.
Ptr< T > inOutArg(T &arg)
create a non-persisting (required or optional) input/output argument for a function call.
Smart reference counting pointer class for automatic garbage collection.
RCP< T2 > rcp_implicit_cast(const RCP< T1 > &p1)
Implicit cast of underlying RCP type from T1* to T2*.
Concrete serial communicator subclass.
Encapsulate how an array of non-const objects with value sematics is serialized into a char[] array.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
TypeTo as(const TypeFrom &t)
Convert from one value type to another.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...
RCP< CommRequest< Ordinal > > ireceive(const ArrayRCP< Packet > &recvBuffer, const int sourceRank, const int tag, const Comm< Ordinal > &comm)
Variant of ireceive that takes a tag argument (and restores the correct order of arguments).
void send(const Packet sendBuffer[], const Ordinal count, const int destRank, const int tag, const Comm< Ordinal > &comm)
Variant of send() that takes a tag (and restores the correct order of arguments).