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>
408RCP<Teuchos::CommRequest<int> >
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 );
417 ValueTypeSerializationBuffer<int, Packet>
418 charRecvBuffer (recvBuffer.size (), recvBuffer.getRawPtr ());
419 RCP<CommRequest<int> > commRequest =
420 comm.ireceive (charRecvBuffer.getCharBufferView (), sourceRank);
421 set_extra_data (recvBuffer, "buffer", inOutArg (commRequest));
422 return commRequest;
423}
424
427template<typename Packet>
428RCP<Teuchos::CommRequest<int> >
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 );
438 ValueTypeSerializationBuffer<int, Packet>
439 charRecvBuffer (recvBuffer.size (), recvBuffer.getRawPtr ());
440 RCP<CommRequest<int> > commRequest =
441 comm.ireceive (charRecvBuffer.getCharBufferView (), sourceRank, tag);
442 set_extra_data (recvBuffer, "buffer", inOutArg (commRequest));
443 return commRequest;
444}
445
458template<class T>
459RCP<CommRequest<int> >
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
501 ArrayRCP<const char> buf =
502 arcp_const_cast<const char> (arcp_reinterpret_cast<char> (recvBuffer));
503 RCP<Details::MpiCommRequest> req (new Details::MpiCommRequest (rawRequest, buf));
504 return rcp_implicit_cast<CommRequest<int> > (req);
505 }
506#else
508 true,
509 std::logic_error,
510 "ireceiveImpl: Not implemented for a serial communicator.");
511
512 // NOTE (mfh 15 Sep 2014): Most compilers have figured out that the
513 // return statement below is unreachable. Some older compilers
514 // might not realize this. That's why the return statement was put
515 // there, so that those compilers don't warn that this function
516 // doesn't return a value. If it's a choice between one warning and
517 // another, I would prefer the choice that produces less code and
518 // doesn't have unreachable code (which never gets tested).
519
520 //return null; // Guard to avoid compiler warning about not returning a value.
521#endif // HAVE_TEUCHOS_MPI
522}
523
526template<class T>
527RCP<CommRequest<int> >
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
569 ArrayRCP<const char> buf =
570 arcp_const_cast<const char> (arcp_reinterpret_cast<char> (recvBuffer));
571 RCP<Details::MpiCommRequest> req (new Details::MpiCommRequest (rawRequest, buf));
572 return rcp_implicit_cast<CommRequest<int> > (req);
573 }
574#else
576 true,
577 std::logic_error,
578 "ireceiveImpl: Not implemented for a serial communicator.");
579
580 return null; // Guard to avoid compiler warning about not returning a value.
581#endif // HAVE_TEUCHOS_MPI
582}
583
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 TEUCHOS_COMM_TIME_MONITOR(
665 "Teuchos::sendImpl<" << TypeNameTraits<T>::name () << ">");
666 MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
667 T t;
668 MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
669 T* rawBuf = const_cast<T*> (sendBuffer);
670 const int tag = mpiComm->getTag ();
671 const int err = MPI_Send (rawBuf, count, rawType, destRank, tag, rawComm);
673 err != MPI_SUCCESS,
674 std::runtime_error,
675 "MPI_Send failed with the following error: "
676 << ::Teuchos::Details::getMpiErrorString (err));
677 }
678#else
680 true,
681 std::logic_error,
682 "sendImpl: Not implemented for a serial communicator.");
683#endif // HAVE_TEUCHOS_MPI
684}
685
688template<class T>
689void
690sendImpl (const T sendBuffer[],
691 const int count,
692 const int destRank,
693 const int tag,
694 const Comm<int>& comm)
695{
696#ifdef HAVE_TEUCHOS_MPI
697 using Teuchos::Details::MpiTypeTraits;
698
699 // Even in an MPI build, Comm might be either a SerialComm or an
700 // MpiComm. If it's something else, we fall back to the most
701 // general implementation.
702 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
703 if (mpiComm == NULL) {
704 // Is it a SerialComm?
705 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
706 if (serialComm == NULL) {
707 // We don't know what kind of Comm we have, so fall back to the
708 // most general implementation.
709 sendGeneral<T> (sendBuffer, count, destRank, tag, comm);
710 }
711 else { // SerialComm doesn't implement send correctly anyway.
713 true,
714 std::logic_error,
715 "sendImpl: Not implemented for a serial communicator.");
716 }
717 }
718 else { // It's an MpiComm. Invoke MPI directly.
719 TEUCHOS_COMM_TIME_MONITOR(
720 "Teuchos::sendImpl<" << TypeNameTraits<T>::name () << ">");
721 MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
722 T t;
723 MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
724 T* rawBuf = const_cast<T*> (sendBuffer);
725 const int err = MPI_Send (rawBuf, count, rawType, destRank, tag, rawComm);
727 err != MPI_SUCCESS,
728 std::runtime_error,
729 "MPI_Send failed with the following error: "
730 << ::Teuchos::Details::getMpiErrorString (err));
731 }
732#else
734 true,
735 std::logic_error,
736 "sendImpl: Not implemented for a serial communicator.");
737#endif // HAVE_TEUCHOS_MPI
738}
739
745template<class T>
746RCP<CommRequest<int> >
747isendGeneral (const Comm<int>& comm,
748 const ArrayRCP<const T>& sendBuffer,
749 const int destRank)
750{
751 TEUCHOS_COMM_TIME_MONITOR(
752 "Teuchos::isend<int," << TypeNameTraits<T>::name () << ">");
753 ConstValueTypeSerializationBuffer<int, T>
754 charSendBuffer (sendBuffer.size (), sendBuffer.getRawPtr ());
755 RCP<CommRequest<int> > commRequest =
756 comm.isend (charSendBuffer.getCharBufferView (), destRank);
757 set_extra_data (sendBuffer, "buffer", inOutArg (commRequest));
758 return commRequest;
759}
760
767template<class T>
768RCP<CommRequest<int> >
769isendGeneral (const ArrayRCP<const T>& sendBuffer,
770 const int destRank,
771 const int tag,
772 const Comm<int>& comm)
773{
774 TEUCHOS_COMM_TIME_MONITOR(
775 "Teuchos::isend<int," << TypeNameTraits<T>::name () << ">");
776 ConstValueTypeSerializationBuffer<int, T>
777 charSendBuffer (sendBuffer.size (), sendBuffer.getRawPtr ());
778 RCP<CommRequest<int> > commRequest =
779 comm.isend (charSendBuffer.getCharBufferView (), destRank, tag);
780 set_extra_data (sendBuffer, "buffer", inOutArg (commRequest));
781 return commRequest;
782}
783
786template<class T>
787RCP<Teuchos::CommRequest<int> >
788isendImpl (const ArrayRCP<const T>& sendBuffer,
789 const int destRank,
790 const int tag,
791 const Comm<int>& comm)
792{
793#ifdef HAVE_TEUCHOS_MPI
794 using Teuchos::Details::MpiTypeTraits;
795
796 // Even in an MPI build, Comm might be either a SerialComm or an
797 // MpiComm. If it's something else, we fall back to the most
798 // general implementation.
799 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
800 if (mpiComm == NULL) {
801 // Is it a SerialComm?
802 const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
803 if (serialComm == NULL) {
804 // We don't know what kind of Comm we have, so fall back to the
805 // most general implementation.
806 return isendGeneral<T> (sendBuffer, destRank, tag, comm);
807 }
808 else { // SerialComm doesn't implement send correctly anyway.
810 true, std::logic_error,
811 "isendImpl: Not implemented for a serial communicator.");
812 }
813 }
814 else { // It's an MpiComm. Invoke MPI directly.
815 TEUCHOS_COMM_TIME_MONITOR(
816 "Teuchos::isendImpl<" << TypeNameTraits<T>::name () << ">");
817
818 MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
819 T t;
820 MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
821 // MPI promises not to modify the send buffer; the const_cast
822 // merely ensures compatibilty with C89, which does not have a
823 // "const" keyword.
824 T* rawSendBuf = const_cast<T*> (sendBuffer.getRawPtr ());
825 const int count = as<int> (sendBuffer.size ());
826 MPI_Request rawRequest = MPI_REQUEST_NULL;
827 const int err = MPI_Isend (rawSendBuf, count, rawType, destRank, tag,
828 rawComm, &rawRequest);
830 err != MPI_SUCCESS,
831 std::runtime_error,
832 "MPI_Isend failed with the following error: "
833 << ::Teuchos::Details::getMpiErrorString (err));
834
835 ArrayRCP<const char> buf = arcp_reinterpret_cast<const char> (sendBuffer);
836 RCP<Details::MpiCommRequest> req (new Details::MpiCommRequest (rawRequest, buf));
837 return rcp_implicit_cast<CommRequest<int> > (req);
838 }
839#else
841 true,
842 std::logic_error,
843 "isendImpl: Not implemented for a serial communicator.");
844#endif // HAVE_TEUCHOS_MPI
845}
846
847} // namespace (anonymous)
848
849
850// mfh 18 Oct 2012: Note on full template specializations
851//
852// To make Windows builds happy, declarations of full template
853// specializations (as found in Teuchos_CommHelpers.hpp) must use the
854// TEUCHOSCOMM_LIB_DLL_EXPORT macro. However, _definitions_ of the
855// specializations (as found in this file) must _not_ use the macro.
856// That's why we don't use that macro here.
857
858// amb See note in .hpp file.
859#if 0
860#ifdef HAVE_TEUCHOS_COMPLEX
861// Specialization for Ordinal=int and Packet=std::complex<double>.
862template<>
863void
864reduceAll<int, std::complex<double> > (const Comm<int>& comm,
865 const EReductionType reductType,
866 const int count,
867 const std::complex<double> sendBuffer[],
868 std::complex<double> globalReducts[])
869{
870 TEUCHOS_COMM_TIME_MONITOR(
871 "Teuchos::reduceAll<int, std::complex<double> > (" << count << ", "
872 << toString (reductType) << ")"
873 );
874 reduceAllImpl<std::complex<double> > (comm, reductType, count, sendBuffer, globalReducts);
875}
876
877template<>
878RCP<Teuchos::CommRequest<int> >
879ireceive<int, std::complex<double> > (const Comm<int>& comm,
880 const ArrayRCP<std::complex<double> >& recvBuffer,
881 const int sourceRank)
882{
883 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<double> >");
884 return ireceiveImpl<std::complex<double> > (comm, recvBuffer, sourceRank);
885}
886
887template<>
888RCP<Teuchos::CommRequest<int> >
889ireceive<int, std::complex<double> > (const ArrayRCP<std::complex<double> >& recvBuffer,
890 const int sourceRank,
891 const int tag,
892 const Comm<int>& comm)
893{
894 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<double> >");
895 return ireceiveImpl<std::complex<double> > (recvBuffer, sourceRank, tag, comm);
896}
897
898template<>
899void
900send<int, std::complex<double> > (const Comm<int>& comm,
901 const int count,
902 const std::complex<double> sendBuffer[],
903 const int destRank)
904{
905 sendImpl<std::complex<double> > (comm, count, sendBuffer, destRank);
906}
907
908template<>
909void
910send<int, std::complex<double> > (const std::complex<double> sendBuffer[],
911 const int count,
912 const int destRank,
913 const int tag,
914 const Comm<int>& comm)
915{
916 sendImpl<std::complex<double> > (sendBuffer, count, destRank, tag, comm);
917}
918
919template<>
920RCP<Teuchos::CommRequest<int> >
921isend (const ArrayRCP<const std::complex<double> >& sendBuffer,
922 const int destRank,
923 const int tag,
924 const Comm<int>& comm)
925{
926 return isendImpl<std::complex<double> > (sendBuffer, destRank, tag, comm);
927}
928
929// Specialization for Ordinal=int and Packet=std::complex<float>.
930template<>
931void
932reduceAll<int, std::complex<float> > (const Comm<int>& comm,
933 const EReductionType reductType,
934 const int count,
935 const std::complex<float> sendBuffer[],
936 std::complex<float> globalReducts[])
937{
938 TEUCHOS_COMM_TIME_MONITOR(
939 "Teuchos::reduceAll<int, std::complex<float> > (" << count << ", "
940 << toString (reductType) << ")"
941 );
942 reduceAllImpl<std::complex<float> > (comm, reductType, count, sendBuffer, globalReducts);
943}
944
945template<>
946RCP<Teuchos::CommRequest<int> >
947ireceive<int, std::complex<float> > (const Comm<int>& comm,
948 const ArrayRCP<std::complex<float> >& recvBuffer,
949 const int sourceRank)
950{
951 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<float> >");
952 return ireceiveImpl<std::complex<float> > (comm, recvBuffer, sourceRank);
953}
954
955template<>
956RCP<Teuchos::CommRequest<int> >
957ireceive<int, std::complex<float> > (const ArrayRCP<std::complex<float> >& recvBuffer,
958 const int sourceRank,
959 const int tag,
960 const Comm<int>& comm)
961{
962 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<float> >");
963 return ireceiveImpl<std::complex<float> > (recvBuffer, sourceRank, tag, comm);
964}
965
966template<>
967void
968send<int, std::complex<float> > (const Comm<int>& comm,
969 const int count,
970 const std::complex<float> sendBuffer[],
971 const int destRank)
972{
973 return sendImpl<std::complex<float> > (comm, count, sendBuffer, destRank);
974}
975
976template<>
977void
978send<int, std::complex<float> > (const std::complex<float> sendBuffer[],
979 const int count,
980 const int destRank,
981 const int tag,
982 const Comm<int>& comm)
983{
984 return sendImpl<std::complex<float> > (sendBuffer, count, destRank, tag, comm);
985}
986
987template<>
988RCP<Teuchos::CommRequest<int> >
989isend (const ArrayRCP<const std::complex<float> >& sendBuffer,
990 const int destRank,
991 const int tag,
992 const Comm<int>& comm)
993{
994 return isendImpl<std::complex<float> > (sendBuffer, destRank, tag, comm);
995}
996#endif // HAVE_TEUCHOS_COMPLEX
997#endif // if 0
998
999// Specialization for Ordinal=int and Packet=double.
1000template<>
1001void
1002reduceAll<int, double> (const Comm<int>& comm,
1003 const EReductionType reductType,
1004 const int count,
1005 const double sendBuffer[],
1006 double globalReducts[])
1007{
1008 TEUCHOS_COMM_TIME_MONITOR(
1009 "Teuchos::reduceAll<int, double> (" << count << ", "
1010 << toString (reductType) << ")"
1011 );
1012 reduceAllImpl<double> (comm, reductType, count, sendBuffer, globalReducts);
1013}
1014
1015template<>
1016RCP<Teuchos::CommRequest<int> >
1017ireceive<int, double> (const Comm<int>& comm,
1018 const ArrayRCP<double>& recvBuffer,
1019 const int sourceRank)
1020{
1021 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, double>");
1022 return ireceiveImpl<double> (comm, recvBuffer, sourceRank);
1023}
1024
1025template<>
1026RCP<Teuchos::CommRequest<int> >
1027ireceive<int, double> (const ArrayRCP<double>& recvBuffer,
1028 const int sourceRank,
1029 const int tag,
1030 const Comm<int>& comm)
1031{
1032 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, double>");
1033 return ireceiveImpl<double> (recvBuffer, sourceRank, tag, comm);
1034}
1035
1036template<>
1037void
1038send<int, double> (const Comm<int>& comm,
1039 const int count,
1040 const double sendBuffer[],
1041 const int destRank)
1042{
1043 return sendImpl<double> (comm, count, sendBuffer, destRank);
1044}
1045
1046template<>
1047void
1048send<int, double> (const double sendBuffer[],
1049 const int count,
1050 const int destRank,
1051 const int tag,
1052 const Comm<int>& comm)
1053{
1054 return sendImpl<double> (sendBuffer, count, destRank, tag, comm);
1055}
1056
1057template<>
1058RCP<Teuchos::CommRequest<int> >
1059isend (const ArrayRCP<const double>& sendBuffer,
1060 const int destRank,
1061 const int tag,
1062 const Comm<int>& comm)
1063{
1064 return isendImpl<double> (sendBuffer, destRank, tag, comm);
1065}
1066
1067template<>
1068void
1069gatherv<int, double> (const double sendBuf[],
1070 const int sendCount,
1071 double recvBuf[],
1072 const int recvCounts[],
1073 const int displs[],
1074 const int root,
1075 const Comm<int>& comm)
1076{
1077 gathervImpl<double> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1078}
1079
1080
1081// Specialization for Ordinal=int and Packet=float.
1082template<>
1083void
1084reduceAll<int, float> (const Comm<int>& comm,
1085 const EReductionType reductType,
1086 const int count,
1087 const float sendBuffer[],
1088 float globalReducts[])
1089{
1090 TEUCHOS_COMM_TIME_MONITOR(
1091 "Teuchos::reduceAll<int, float> (" << count << ", "
1092 << toString (reductType) << ")"
1093 );
1094 reduceAllImpl<float> (comm, reductType, count, sendBuffer, globalReducts);
1095}
1096
1097template<>
1098RCP<Teuchos::CommRequest<int> >
1099ireceive<int, float> (const Comm<int>& comm,
1100 const ArrayRCP<float>& recvBuffer,
1101 const int sourceRank)
1102{
1103 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, float>");
1104 return ireceiveImpl<float> (comm, recvBuffer, sourceRank);
1105}
1106
1107template<>
1108RCP<Teuchos::CommRequest<int> >
1109ireceive<int, float> (const ArrayRCP<float>& recvBuffer,
1110 const int sourceRank,
1111 const int tag,
1112 const Comm<int>& comm)
1113{
1114 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, float>");
1115 return ireceiveImpl<float> (recvBuffer, sourceRank, tag, comm);
1116}
1117
1118template<>
1119void
1120send<int, float> (const Comm<int>& comm,
1121 const int count,
1122 const float sendBuffer[],
1123 const int destRank)
1124{
1125 return sendImpl<float> (comm, count, sendBuffer, destRank);
1126}
1127
1128template<>
1129void
1130send<int, float> (const float sendBuffer[],
1131 const int count,
1132 const int destRank,
1133 const int tag,
1134 const Comm<int>& comm)
1135{
1136 return sendImpl<float> (sendBuffer, count, destRank, tag, comm);
1137}
1138
1139template<>
1140RCP<Teuchos::CommRequest<int> >
1141isend (const ArrayRCP<const float>& sendBuffer,
1142 const int destRank,
1143 const int tag,
1144 const Comm<int>& comm)
1145{
1146 return isendImpl<float> (sendBuffer, destRank, tag, comm);
1147}
1148
1149template<>
1150void
1151gatherv<int,float> (const float sendBuf[],
1152 const int sendCount,
1153 float recvBuf[],
1154 const int recvCounts[],
1155 const int displs[],
1156 const int root,
1157 const Comm<int>& comm)
1158{
1159 gathervImpl<float> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1160}
1161
1162
1163// Specialization for Ordinal=int and Packet=long long.
1164template<>
1165void
1166gather<int, long long> (const long long sendBuf[],
1167 const int sendCount,
1168 long long recvBuf[],
1169 const int recvCount,
1170 const int root,
1171 const Comm<int>& comm)
1172{
1173 gatherImpl<long long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1174}
1175
1176template<>
1177void
1178gatherv<int, long long> (const long long sendBuf[],
1179 const int sendCount,
1180 long long recvBuf[],
1181 const int recvCounts[],
1182 const int displs[],
1183 const int root,
1184 const Comm<int>& comm)
1185{
1186 gathervImpl<long long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1187}
1188
1189template<>
1190void
1191reduceAll<int, long long> (const Comm<int>& comm,
1192 const EReductionType reductType,
1193 const int count,
1194 const long long sendBuffer[],
1195 long long globalReducts[])
1196{
1197 TEUCHOS_COMM_TIME_MONITOR(
1198 "Teuchos::reduceAll<int, long long> (" << count << ", "
1199 << toString (reductType) << ")"
1200 );
1201 reduceAllImpl<long long> (comm, reductType, count, sendBuffer, globalReducts);
1202}
1203
1204template<>
1205RCP<Teuchos::CommRequest<int> >
1206ireceive<int, long long> (const Comm<int>& comm,
1207 const ArrayRCP<long long>& recvBuffer,
1208 const int sourceRank)
1209{
1210 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long long>");
1211 return ireceiveImpl<long long> (comm, recvBuffer, sourceRank);
1212}
1213
1214template<>
1215RCP<Teuchos::CommRequest<int> >
1216ireceive<int, long long> (const ArrayRCP<long long>& recvBuffer,
1217 const int sourceRank,
1218 const int tag,
1219 const Comm<int>& comm)
1220{
1221 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long long>");
1222 return ireceiveImpl<long long> (recvBuffer, sourceRank, tag, comm);
1223}
1224
1225template<>
1226void
1227send<int, long long> (const Comm<int>& comm,
1228 const int count,
1229 const long long sendBuffer[],
1230 const int destRank)
1231{
1232 return sendImpl<long long> (comm, count, sendBuffer, destRank);
1233}
1234
1235template<>
1236void
1237send<int, long long> (const long long sendBuffer[],
1238 const int count,
1239 const int destRank,
1240 const int tag,
1241 const Comm<int>& comm)
1242{
1243 return sendImpl<long long> (sendBuffer, count, destRank, tag, comm);
1244}
1245
1246template<>
1247RCP<Teuchos::CommRequest<int> >
1248isend (const ArrayRCP<const long long>& sendBuffer,
1249 const int destRank,
1250 const int tag,
1251 const Comm<int>& comm)
1252{
1253 return isendImpl<long long> (sendBuffer, destRank, tag, comm);
1254}
1255
1256// Specialization for Ordinal=int and Packet=unsigned long long.
1257template<>
1258void
1259gather<int, unsigned long long> (const unsigned long long sendBuf[],
1260 const int sendCount,
1261 unsigned long long recvBuf[],
1262 const int recvCount,
1263 const int root,
1264 const Comm<int>& comm)
1265{
1266 gatherImpl<unsigned long long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1267}
1268
1269template<>
1270void
1271gatherv<int, unsigned long long> (const unsigned long long sendBuf[],
1272 const int sendCount,
1273 unsigned long long recvBuf[],
1274 const int recvCounts[],
1275 const int displs[],
1276 const int root,
1277 const Comm<int>& comm)
1278{
1279 gathervImpl<unsigned long long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1280}
1281
1282template<>
1283void
1284reduceAll<int, unsigned long long> (const Comm<int>& comm,
1285 const EReductionType reductType,
1286 const int count,
1287 const unsigned long long sendBuffer[],
1288 unsigned long long globalReducts[])
1289{
1290 TEUCHOS_COMM_TIME_MONITOR(
1291 "Teuchos::reduceAll<int, unsigned long long> (" << count << ", "
1292 << toString (reductType) << ")"
1293 );
1294 reduceAllImpl<unsigned long long> (comm, reductType, count, sendBuffer, globalReducts);
1295}
1296
1297template<>
1298RCP<Teuchos::CommRequest<int> >
1299ireceive<int, unsigned long long> (const Comm<int>& comm,
1300 const ArrayRCP<unsigned long long>& recvBuffer,
1301 const int sourceRank)
1302{
1303 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long long>");
1304 return ireceiveImpl<unsigned long long> (comm, recvBuffer, sourceRank);
1305}
1306
1307template<>
1308RCP<Teuchos::CommRequest<int> >
1309ireceive<int, unsigned long long> (const ArrayRCP<unsigned long long>& recvBuffer,
1310 const int sourceRank,
1311 const int tag,
1312 const Comm<int>& comm)
1313{
1314 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long long>");
1315 return ireceiveImpl<unsigned long long> (recvBuffer, sourceRank, tag, comm);
1316}
1317
1318template<>
1319void
1320send<int, unsigned long long> (const Comm<int>& comm,
1321 const int count,
1322 const unsigned long long sendBuffer[],
1323 const int destRank)
1324{
1325 return sendImpl<unsigned long long> (comm, count, sendBuffer, destRank);
1326}
1327
1328template<>
1329void
1330send<int, unsigned long long> (const unsigned long long sendBuffer[],
1331 const int count,
1332 const int destRank,
1333 const int tag,
1334 const Comm<int>& comm)
1335{
1336 return sendImpl<unsigned long long> (sendBuffer, count, destRank, tag, comm);
1337}
1338
1339template<>
1340RCP<Teuchos::CommRequest<int> >
1341isend (const ArrayRCP<const unsigned long long>& sendBuffer,
1342 const int destRank,
1343 const int tag,
1344 const Comm<int>& comm)
1345{
1346 return isendImpl<unsigned long long> (sendBuffer, destRank, tag, comm);
1347}
1348
1349
1350// Specialization for Ordinal=int and Packet=long.
1351template<>
1352void
1353gather<int, long> (const long sendBuf[],
1354 const int sendCount,
1355 long recvBuf[],
1356 const int recvCount,
1357 const int root,
1358 const Comm<int>& comm)
1359{
1360 gatherImpl<long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1361}
1362
1363template<>
1364void
1365gatherv<int, long> (const long sendBuf[],
1366 const int sendCount,
1367 long recvBuf[],
1368 const int recvCounts[],
1369 const int displs[],
1370 const int root,
1371 const Comm<int>& comm)
1372{
1373 gathervImpl<long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1374}
1375
1376template<>
1377void
1378reduceAll<int, long> (const Comm<int>& comm,
1379 const EReductionType reductType,
1380 const int count,
1381 const long sendBuffer[],
1382 long globalReducts[])
1383{
1384 TEUCHOS_COMM_TIME_MONITOR(
1385 "Teuchos::reduceAll<int, long> (" << count << ", "
1386 << toString (reductType) << ")"
1387 );
1388 reduceAllImpl<long> (comm, reductType, count, sendBuffer, globalReducts);
1389}
1390
1391template<>
1392RCP<Teuchos::CommRequest<int> >
1393ireceive<int, long> (const Comm<int>& comm,
1394 const ArrayRCP<long>& recvBuffer,
1395 const int sourceRank)
1396{
1397 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long>");
1398 return ireceiveImpl<long> (comm, recvBuffer, sourceRank);
1399}
1400
1401template<>
1402RCP<Teuchos::CommRequest<int> >
1403ireceive<int, long> (const ArrayRCP<long>& recvBuffer,
1404 const int sourceRank,
1405 const int tag,
1406 const Comm<int>& comm)
1407{
1408 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long>");
1409 return ireceiveImpl<long> (recvBuffer, sourceRank, tag, comm);
1410}
1411
1412template<>
1413void
1414send<int, long> (const Comm<int>& comm,
1415 const int count,
1416 const long sendBuffer[],
1417 const int destRank)
1418{
1419 return sendImpl<long> (comm, count, sendBuffer, destRank);
1420}
1421
1422template<>
1423void
1424send<int, long> (const long sendBuffer[],
1425 const int count,
1426 const int destRank,
1427 const int tag,
1428 const Comm<int>& comm)
1429{
1430 return sendImpl<long> (sendBuffer, count, destRank, tag, comm);
1431}
1432
1433template<>
1434RCP<Teuchos::CommRequest<int> >
1435isend (const ArrayRCP<const long>& sendBuffer,
1436 const int destRank,
1437 const int tag,
1438 const Comm<int>& comm)
1439{
1440 return isendImpl<long> (sendBuffer, destRank, tag, comm);
1441}
1442
1443
1444// Specialization for Ordinal=int and Packet=unsigned long.
1445template<>
1446void
1447gather<int, unsigned long> (const unsigned long sendBuf[],
1448 const int sendCount,
1449 unsigned long recvBuf[],
1450 const int recvCount,
1451 const int root,
1452 const Comm<int>& comm)
1453{
1454 gatherImpl<unsigned long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1455}
1456
1457template<>
1458void
1459gatherv<int, unsigned long> (const unsigned long sendBuf[],
1460 const int sendCount,
1461 unsigned long recvBuf[],
1462 const int recvCounts[],
1463 const int displs[],
1464 const int root,
1465 const Comm<int>& comm)
1466{
1467 gathervImpl<unsigned long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1468}
1469
1470template<>
1471void
1472reduceAll<int, unsigned long> (const Comm<int>& comm,
1473 const EReductionType reductType,
1474 const int count,
1475 const unsigned long sendBuffer[],
1476 unsigned long globalReducts[])
1477{
1478 TEUCHOS_COMM_TIME_MONITOR(
1479 "Teuchos::reduceAll<int, unsigned long> (" << count << ", "
1480 << toString (reductType) << ")"
1481 );
1482 reduceAllImpl<unsigned long> (comm, reductType, count, sendBuffer, globalReducts);
1483}
1484
1485template<>
1486RCP<Teuchos::CommRequest<int> >
1487ireceive<int, unsigned long> (const Comm<int>& comm,
1488 const ArrayRCP<unsigned long>& recvBuffer,
1489 const int sourceRank)
1490{
1491 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long>");
1492 return ireceiveImpl<unsigned long> (comm, recvBuffer, sourceRank);
1493}
1494
1495template<>
1496RCP<Teuchos::CommRequest<int> >
1497ireceive<int, unsigned long> (const ArrayRCP<unsigned long>& recvBuffer,
1498 const int sourceRank,
1499 const int tag,
1500 const Comm<int>& comm)
1501{
1502 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long>");
1503 return ireceiveImpl<unsigned long> (recvBuffer, sourceRank, tag, comm);
1504}
1505
1506template<>
1507void
1508send<int, unsigned long> (const Comm<int>& comm,
1509 const int count,
1510 const unsigned long sendBuffer[],
1511 const int destRank)
1512{
1513 return sendImpl<unsigned long> (comm, count, sendBuffer, destRank);
1514}
1515
1516template<>
1517void
1518send<int, unsigned long> (const unsigned long sendBuffer[],
1519 const int count,
1520 const int destRank,
1521 const int tag,
1522 const Comm<int>& comm)
1523{
1524 return sendImpl<unsigned long> (sendBuffer, count, destRank, tag, comm);
1525}
1526
1527template<>
1528RCP<Teuchos::CommRequest<int> >
1529isend (const ArrayRCP<const unsigned long>& sendBuffer,
1530 const int destRank,
1531 const int tag,
1532 const Comm<int>& comm)
1533{
1534 return isendImpl<unsigned long> (sendBuffer, destRank, tag, comm);
1535}
1536
1537// Specialization for Ordinal=int and Packet=int.
1538template<>
1539void
1540gather<int, int> (const int sendBuf[],
1541 const int sendCount,
1542 int recvBuf[],
1543 const int recvCount,
1544 const int root,
1545 const Comm<int>& comm)
1546{
1547 gatherImpl<int> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1548}
1549
1550template<>
1551void
1552gatherv<int, int> (const int sendBuf[],
1553 const int sendCount,
1554 int recvBuf[],
1555 const int recvCounts[],
1556 const int displs[],
1557 const int root,
1558 const Comm<int>& comm)
1559{
1560 gathervImpl<int> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1561}
1562
1563template<>
1564void
1565scatter<int, int> (const int sendBuf[],
1566 const int sendCount,
1567 int recvBuf[],
1568 const int recvCount,
1569 const int root,
1570 const Comm<int>& comm)
1571{
1572 scatterImpl<int> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1573}
1574
1575template<>
1576void
1577scatterv<int, double> (const double sendBuf[],
1578 const int sendCount[],
1579 const int displs[],
1580 double recvBuf[],
1581 const int recvCount,
1582 const int root,
1583 const Comm<int>& comm)
1584{
1585 scattervImpl<double> (sendBuf, sendCount, displs, recvBuf, recvCount, root, comm);
1586}
1587
1588template<>
1589void
1590scatterv<int, float> (const float sendBuf[],
1591 const int sendCounts[],
1592 const int displs[],
1593 float recvBuf[],
1594 const int recvCount,
1595 const int root,
1596 const Comm<int>& comm)
1597{
1598 scattervImpl<float> (sendBuf, sendCounts, displs, recvBuf, recvCount, root, comm);
1599}
1600
1601template<>
1602void
1603reduce<int, int> (const int sendBuf[],
1604 int recvBuf[],
1605 const int count,
1606 const EReductionType reductType,
1607 const int root,
1608 const Comm<int>& comm)
1609{
1610 TEUCHOS_COMM_TIME_MONITOR
1611 ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1612 << ")");
1613 reduceImpl<int> (sendBuf, recvBuf, count, reductType, root, comm);
1614}
1615template<>
1616void
1617reduce<int, long> (const long sendBuf[],
1618 long recvBuf[],
1619 const int count,
1620 const EReductionType reductType,
1621 const int root,
1622 const Comm<int>& comm)
1623{
1624 TEUCHOS_COMM_TIME_MONITOR
1625 ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1626 << ")");
1627 reduceImpl<long> (sendBuf, recvBuf, count, reductType, root, comm);
1628}
1629
1630template<>
1631void
1632reduce<int, unsigned long> (const unsigned long sendBuf[],
1633 unsigned long recvBuf[],
1634 const int count,
1635 const EReductionType reductType,
1636 const int root,
1637 const Comm<int>& comm)
1638{
1639 TEUCHOS_COMM_TIME_MONITOR
1640 ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1641 << ")");
1642 reduceImpl<unsigned long> (sendBuf, recvBuf, count, reductType, root, comm);
1643}
1644
1645template<>
1646void
1647reduce<int, unsigned long long > (const unsigned long long sendBuf[],
1648 unsigned long long recvBuf[],
1649 const int count,
1650 const EReductionType reductType,
1651 const int root,
1652 const Comm<int>& comm)
1653{
1654 TEUCHOS_COMM_TIME_MONITOR
1655 ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1656 << ")");
1657 reduceImpl<unsigned long long> (sendBuf, recvBuf, count, reductType, root, comm);
1658}
1659
1660template<>
1661void
1662reduce<int, double> (const double sendBuf[],
1663 double recvBuf[],
1664 const int count,
1665 const EReductionType reductType,
1666 const int root,
1667 const Comm<int>& comm)
1668{
1669 TEUCHOS_COMM_TIME_MONITOR
1670 ("Teuchos::reduce<int, int> (" << count << ", " << toString (reductType)
1671 << ")");
1672 reduceImpl<double> (sendBuf, recvBuf, count, reductType, root, comm);
1673}
1674template<>
1675void
1676reduceAll<int, int> (const Comm<int>& comm,
1677 const EReductionType reductType,
1678 const int count,
1679 const int sendBuffer[],
1680 int globalReducts[])
1681{
1682 TEUCHOS_COMM_TIME_MONITOR(
1683 "Teuchos::reduceAll<int, int> (" << count << ", "
1684 << toString (reductType) << ")"
1685 );
1686 reduceAllImpl<int> (comm, reductType, count, sendBuffer, globalReducts);
1687}
1688
1689template<>
1690RCP<Teuchos::CommRequest<int> >
1691ireceive<int, int> (const Comm<int>& comm,
1692 const ArrayRCP<int>& recvBuffer,
1693 const int sourceRank)
1694{
1695 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, int>");
1696 return ireceiveImpl<int> (comm, recvBuffer, sourceRank);
1697}
1698
1699template<>
1700RCP<Teuchos::CommRequest<int> >
1701ireceive<int, int> (const ArrayRCP<int>& recvBuffer,
1702 const int sourceRank,
1703 const int tag,
1704 const Comm<int>& comm)
1705{
1706 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, int>");
1707 return ireceiveImpl<int> (recvBuffer, sourceRank, tag, comm);
1708}
1709
1710template<>
1711void
1712send<int, int> (const Comm<int>& comm,
1713 const int count,
1714 const int sendBuffer[],
1715 const int destRank)
1716{
1717 return sendImpl<int> (comm, count, sendBuffer, destRank);
1718}
1719
1720template<>
1721void
1722send<int, int> (const int sendBuffer[],
1723 const int count,
1724 const int destRank,
1725 const int tag,
1726 const Comm<int>& comm)
1727{
1728 return sendImpl<int> (sendBuffer, count, destRank, tag, comm);
1729}
1730
1731template<>
1732RCP<Teuchos::CommRequest<int> >
1733isend (const ArrayRCP<const int>& sendBuffer,
1734 const int destRank,
1735 const int tag,
1736 const Comm<int>& comm)
1737{
1738 return isendImpl<int> (sendBuffer, destRank, tag, comm);
1739}
1740
1741// Specialization for Ordinal=int and Packet=unsigned int.
1742template<>
1743void
1744gather<int, unsigned int> (const unsigned int sendBuf[],
1745 const int sendCount,
1746 unsigned int recvBuf[],
1747 const int recvCount,
1748 const int root,
1749 const Comm<int>& comm)
1750{
1751 gatherImpl<unsigned int> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1752}
1753
1754template<>
1755void
1756gatherv<int, unsigned int> (const unsigned int sendBuf[],
1757 const int sendCount,
1758 unsigned int recvBuf[],
1759 const int recvCounts[],
1760 const int displs[],
1761 const int root,
1762 const Comm<int>& comm)
1763{
1764 gathervImpl<unsigned int> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1765}
1766
1767template<>
1768void
1769reduceAll<int, unsigned int> (const Comm<int>& comm,
1770 const EReductionType reductType,
1771 const int count,
1772 const unsigned int sendBuffer[],
1773 unsigned int globalReducts[])
1774{
1775 TEUCHOS_COMM_TIME_MONITOR(
1776 "Teuchos::reduceAll<int, unsigned int> (" << count << ", "
1777 << toString (reductType) << ")"
1778 );
1779 reduceAllImpl<unsigned int> (comm, reductType, count, sendBuffer, globalReducts);
1780}
1781
1782template<>
1783RCP<Teuchos::CommRequest<int> >
1784ireceive<int, unsigned int> (const Comm<int>& comm,
1785 const ArrayRCP<unsigned int>& recvBuffer,
1786 const int sourceRank)
1787{
1788 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned int>");
1789 return ireceiveImpl<unsigned int> (comm, recvBuffer, sourceRank);
1790}
1791
1792template<>
1793RCP<Teuchos::CommRequest<int> >
1794ireceive<int, unsigned int> (const ArrayRCP<unsigned int>& recvBuffer,
1795 const int sourceRank,
1796 const int tag,
1797 const Comm<int>& comm)
1798{
1799 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned int>");
1800 return ireceiveImpl<unsigned int> (recvBuffer, sourceRank, tag, comm);
1801}
1802
1803template<>
1804void
1805send<int, unsigned int> (const Comm<int>& comm,
1806 const int count,
1807 const unsigned int sendBuffer[],
1808 const int destRank)
1809{
1810 return sendImpl<unsigned int> (comm, count, sendBuffer, destRank);
1811}
1812
1813template<>
1814void
1815send<int, unsigned int> (const unsigned int sendBuffer[],
1816 const int count,
1817 const int destRank,
1818 const int tag,
1819 const Comm<int>& comm)
1820{
1821 return sendImpl<unsigned int> (sendBuffer, count, destRank, tag, comm);
1822}
1823
1824template<>
1825RCP<Teuchos::CommRequest<int> >
1826isend (const ArrayRCP<const unsigned int>& sendBuffer,
1827 const int destRank,
1828 const int tag,
1829 const Comm<int>& comm)
1830{
1831 return isendImpl<unsigned int> (sendBuffer, destRank, tag, comm);
1832}
1833
1834
1835// Specialization for Ordinal=int and Packet=short.
1836template<>
1837void
1838gather<int, short> (const short sendBuf[],
1839 const int sendCount,
1840 short recvBuf[],
1841 const int recvCount,
1842 const int root,
1843 const Comm<int>& comm)
1844{
1845 gatherImpl<short> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
1846}
1847
1848template<>
1849void
1850gatherv<int, short> (const short sendBuf[],
1851 const int sendCount,
1852 short recvBuf[],
1853 const int recvCounts[],
1854 const int displs[],
1855 const int root,
1856 const Comm<int>& comm)
1857{
1858 gathervImpl<short> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
1859}
1860
1861template<>
1862void
1863reduceAll<int, short> (const Comm<int>& comm,
1864 const EReductionType reductType,
1865 const int count,
1866 const short sendBuffer[],
1867 short globalReducts[])
1868{
1869 TEUCHOS_COMM_TIME_MONITOR(
1870 "Teuchos::reduceAll<int, short> (" << count << ", "
1871 << toString (reductType) << ")"
1872 );
1873 reduceAllImpl<short> (comm, reductType, count, sendBuffer, globalReducts);
1874}
1875
1876template<>
1877RCP<Teuchos::CommRequest<int> >
1878ireceive<int, short> (const Comm<int>& comm,
1879 const ArrayRCP<short>& recvBuffer,
1880 const int sourceRank)
1881{
1882 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, short>");
1883 return ireceiveImpl<short> (comm, recvBuffer, sourceRank);
1884}
1885
1886template<>
1887RCP<Teuchos::CommRequest<int> >
1888ireceive<int, short> (const ArrayRCP<short>& recvBuffer,
1889 const int sourceRank,
1890 const int tag,
1891 const Comm<int>& comm)
1892{
1893 TEUCHOS_COMM_TIME_MONITOR("ireceive<int, short>");
1894 return ireceiveImpl<short> (recvBuffer, sourceRank, tag, comm);
1895}
1896
1897template<>
1898void
1899send<int, short> (const Comm<int>& comm,
1900 const int count,
1901 const short sendBuffer[],
1902 const int destRank)
1903{
1904 return sendImpl<short> (comm, count, sendBuffer, destRank);
1905}
1906
1907template<>
1908void
1909send<int, short> (const short sendBuffer[],
1910 const int count,
1911 const int destRank,
1912 const int tag,
1913 const Comm<int>& comm)
1914{
1915 return sendImpl<short> (sendBuffer, count, destRank, tag, comm);
1916}
1917
1918template<>
1919RCP<Teuchos::CommRequest<int> >
1920isend (const ArrayRCP<const short>& sendBuffer,
1921 const int destRank,
1922 const int tag,
1923 const Comm<int>& comm)
1924{
1925 return isendImpl<short> (sendBuffer, destRank, tag, comm);
1926}
1927
1928// mfh 18 Oct 2012: The specialization for Packet=char seems to be
1929// causing problems such as the following:
1930//
1931// http://testing.sandia.gov/cdash/testDetails.php?test=9909246&build=747699
1932//
1933// I am disabling it for now. This should revert back to the old
1934// behavior for Packet=char. That should fix the Tpetra errors, since
1935// many Tpetra objects inherit from DistObject<char, ...>.
1936#if 0
1937// Specialization for Ordinal=int and Packet=char.
1938template<>
1939void
1940reduceAll<int, char> (const Comm<int>& comm,
1941 const EReductionType reductType,
1942 const int count,
1943 const char sendBuffer[],
1944 char globalReducts[])
1945{
1946 TEUCHOS_COMM_TIME_MONITOR(
1947 "Teuchos::reduceAll<int, char> (" << count << ", "
1948 << toString (reductType) << ")"
1949 );
1950 reduceAllImpl<char> (comm, reductType, count, sendBuffer, globalReducts);
1951}
1952#endif // 0
1953
1954} // namespace Teuchos
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,...