Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Teuchos_CommHelpers.cpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #include "Teuchos_CommHelpers.hpp"
00043 #ifdef HAVE_MPI
00044 #  include "Teuchos_Details_MpiCommRequest.hpp"
00045 #endif // HAVE_MPI
00046 
00047 namespace Teuchos {
00048 namespace { // (anonymous)
00049 
00050 #ifdef HAVE_MPI
00051 
00052 MPI_Op getMpiOpForEReductionType (const enum EReductionType reductionType) {
00053   switch (reductionType) {
00054   case REDUCE_SUM: return MPI_SUM;
00055   case REDUCE_MIN: return MPI_MIN;
00056   case REDUCE_MAX: return MPI_MAX;
00057   case REDUCE_AND: return MPI_LAND; // logical AND, not bitwise AND
00058   default:
00059     TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument,
00060       "The given EReductionType value is invalid.");
00061   }
00062 }
00063 
00067 std::string getMpiErrorString (const int errCode) {
00068   // Space for storing the error string returned by MPI.
00069   // Leave room for null termination, since I don't know if MPI does this.
00070   char errString [MPI_MAX_ERROR_STRING+1];
00071   int errStringLen = MPI_MAX_ERROR_STRING; // output argument
00072   (void) MPI_Error_string (errCode, errString, &errStringLen);
00073   // errStringLen on output is the number of characters written.
00074   // I'm not sure (the MPI 3.0 Standard doesn't say) if this
00075   // includes the '\0', so I'll make sure.  We reserved space for
00076   // the extra '\0' if needed.
00077   if (errString[errStringLen-1] != '\0') {
00078     errString[errStringLen] = '\0';
00079   }
00080   return std::string (errString); // This copies the original string.
00081 }
00082 
00090 template<class T>
00091 class MpiTypeTraits {
00092 public:
00098   static MPI_Datatype getType (const T&);
00099 };
00100 
00101 #ifdef TEUCHOS_HAVE_COMPLEX
00102 template<>
00103 class MpiTypeTraits<std::complex<double> > {
00104 public:
00105   static MPI_Datatype getType (const T&) {
00106     return MPI_C_DOUBLE_COMPLEX;
00107   }
00108 };
00109 
00110 template<>
00111 class MpiTypeTraits<std::complex<float> > {
00112 public:
00113   static MPI_Datatype getType (const T&) {
00114     return MPI_C_FLOAT_COMPLEX;
00115   }
00116 };
00117 #endif // TEUCHOS_HAVE_COMPLEX
00118 
00119 template<>
00120 class MpiTypeTraits<double> {
00121 public:
00122   static MPI_Datatype getType (const double&) {
00123     return MPI_DOUBLE;
00124   }
00125 };
00126 
00127 template<>
00128 class MpiTypeTraits<float> {
00129 public:
00130   static MPI_Datatype getType (const float&) {
00131     return MPI_FLOAT;
00132   }
00133 };
00134 
00135 #ifdef TEUCHOS_HAVE_LONG_LONG_INT
00136 template<>
00137 class MpiTypeTraits<long long> {
00138 public:
00139   static MPI_Datatype getType (const long long&) {
00140     return MPI_LONG_LONG;
00141   }
00142 };
00143 
00144 template<>
00145 class MpiTypeTraits<unsigned long long> {
00146 public:
00147   static MPI_Datatype getType (const unsigned long long&) {
00148     return MPI_UNSIGNED_LONG_LONG;
00149   }
00150 };
00151 #endif // TEUCHOS_HAVE_LONG_LONG_INT
00152 
00153 template<>
00154 class MpiTypeTraits<long> {
00155 public:
00156   static MPI_Datatype getType (const long&) {
00157     return MPI_LONG;
00158   }
00159 };
00160 
00161 template<>
00162 class MpiTypeTraits<unsigned long> {
00163 public:
00164   static MPI_Datatype getType (const unsigned long&) {
00165     return MPI_UNSIGNED_LONG;
00166   }
00167 };
00168 
00169 template<>
00170 class MpiTypeTraits<int> {
00171 public:
00172   static MPI_Datatype getType (const int&) {
00173     return MPI_INT;
00174   }
00175 };
00176 
00177 template<>
00178 class MpiTypeTraits<unsigned int> {
00179 public:
00180   static MPI_Datatype getType (const unsigned int&) {
00181     return MPI_UNSIGNED;
00182   }
00183 };
00184 
00185 template<>
00186 class MpiTypeTraits<short> {
00187 public:
00188   static MPI_Datatype getType (const short&) {
00189     return MPI_SHORT;
00190   }
00191 };
00192 
00193 template<>
00194 class MpiTypeTraits<unsigned short> {
00195 public:
00196   static MPI_Datatype getType (const unsigned short&) {
00197     return MPI_UNSIGNED_SHORT;
00198   }
00199 };
00200 #endif // HAVE_MPI
00201 
00202 
00210 template<class T>
00211 void
00212 reduceAllImpl (const Comm<int>& comm,
00213                const EReductionType reductType,
00214                const int count,
00215                const T sendBuffer[],
00216                T globalReducts[])
00217 {
00218 #ifdef HAVE_MPI
00219   // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
00220   // SerialComm or an MpiComm.  If it's something else, we fall back
00221   // to the most general implementation.
00222   const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
00223   if (mpiComm == NULL) {
00224     // Is it a SerialComm?
00225     const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
00226     if (serialComm == NULL) {
00227       // We don't know what kind of Comm we have, so fall back to the
00228       // most general implementation.
00229       std::auto_ptr<ValueTypeReductionOp<int, T> > reductOp (createOp<int, T> (reductType));
00230       reduceAll (comm, *reductOp, count, sendBuffer, globalReducts);
00231     }
00232     else { // It's a SerialComm; there is only 1 process, so just copy.
00233       std::copy (sendBuffer, sendBuffer + count, globalReducts);
00234     }
00235   } else { // It's an MpiComm.  Invoke MPI directly.
00236     MPI_Op rawMpiOp = getMpiOpForEReductionType (reductType);
00237     MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
00238     T t;
00239     MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
00240     const int err = MPI_Allreduce (const_cast<T*> (sendBuffer),
00241       globalReducts, count, rawMpiType, rawMpiOp, rawMpiComm);
00242     TEUCHOS_TEST_FOR_EXCEPTION(
00243       err != MPI_SUCCESS,
00244       std::runtime_error,
00245       "MPI_Allreduce failed with the following error: "
00246       << getMpiErrorString (err));
00247   }
00248 #else
00249   // We've built without MPI, so just assume it's a SerialComm and copy the data.
00250   std::copy (sendBuffer, sendBuffer + count, globalReducts);
00251 #endif // HAVE_MPI
00252 }
00253 
00254 
00262 template<class T>
00263 void
00264 gatherImpl (const T sendBuf[],
00265             const int sendCount,
00266             T recvBuf[],
00267             const int recvCount,
00268             const int root,
00269             const Comm<int>& comm)
00270 {
00271 #ifdef HAVE_MPI
00272   // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
00273   // SerialComm or an MpiComm.  If it's something else, we fall back
00274   // to the most general implementation.
00275   const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
00276   if (mpiComm == NULL) {
00277     // Is it a SerialComm?
00278     const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
00279     if (serialComm == NULL) {
00280       // We don't know what kind of Comm we have, so fall back to the
00281       // most general implementation.
00282       gather<int, T> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
00283     }
00284     else { // It's a SerialComm; there is only 1 process, so just copy.
00285       std::copy (sendBuf, sendBuf + sendCount, recvBuf);
00286     }
00287   } else { // It's an MpiComm.  Invoke MPI directly.
00288     MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
00289     T t;
00290     MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
00291     const int err = MPI_Gather (const_cast<T*> (sendBuf), sendCount, rawMpiType,
00292                                 recvBuf, recvCount, rawMpiType,
00293                                 root, rawMpiComm);
00294     TEUCHOS_TEST_FOR_EXCEPTION(
00295       err != MPI_SUCCESS,
00296       std::runtime_error,
00297       "MPI_Gather failed with the following error: "
00298       << getMpiErrorString (err));
00299   }
00300 #else
00301   // We've built without MPI, so just assume it's a SerialComm and copy the data.
00302   std::copy (sendBuf, sendBuf + sendCount, recvBuf);
00303 #endif // HAVE_MPI
00304 }
00305 
00306 
00314 template<class T>
00315 void
00316 gathervImpl (const T sendBuf[],
00317              const int sendCount,
00318              T recvBuf[],
00319              const int recvCounts[],
00320              const int displs[],
00321              const int root,
00322              const Comm<int>& comm)
00323 {
00324 #ifdef HAVE_MPI
00325   // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
00326   // SerialComm or an MpiComm.  If it's something else, we fall back
00327   // to the most general implementation.
00328   const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
00329   if (mpiComm == NULL) {
00330     // Is it a SerialComm?
00331     const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
00332     if (serialComm == NULL) {
00333       // We don't know what kind of Comm we have, so fall back to the
00334       // most general implementation.
00335       gatherv<int, T> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
00336     }
00337     else { // It's a SerialComm; there is only 1 process, so just copy.
00338       TEUCHOS_TEST_FOR_EXCEPTION(
00339         recvCounts[0] > sendCount, std::invalid_argument,
00340         "Teuchos::gatherv: If the input communicator contains only one "
00341         "process, then you cannot receive more entries than you send.  "
00342         "You aim to receive " << recvCounts[0] << " entries, but to send "
00343         << sendCount << " entries.");
00344       // Serial communicator case: just copy.  recvCounts[0] is the
00345       // amount to receive, so it's the amount to copy.  Start writing
00346       // to recvbuf at the offset displs[0].
00347       std::copy (sendBuf, sendBuf + recvCounts[0], recvBuf + displs[0]);
00348     }
00349   } else { // It's an MpiComm.  Invoke MPI directly.
00350     MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
00351     T t;
00352     MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
00353     const int err = MPI_Gatherv (const_cast<T*> (sendBuf),
00354                                  sendCount,
00355                                  rawMpiType,
00356                                  recvBuf,
00357                                  const_cast<int*> (recvCounts),
00358                                  const_cast<int*> (displs),
00359                                  rawMpiType,
00360                                  root,
00361                                  rawMpiComm);
00362     TEUCHOS_TEST_FOR_EXCEPTION(
00363       err != MPI_SUCCESS,
00364       std::runtime_error,
00365       "MPI_Gatherv failed with the following error: "
00366       << getMpiErrorString (err));
00367   }
00368 #else
00369   // We've built without MPI, so just assume it's a SerialComm and copy the data.
00370   TEUCHOS_TEST_FOR_EXCEPTION(
00371     recvCounts[0] > sendCount, std::invalid_argument,
00372     "Teuchos::gatherv: If the input communicator contains only one "
00373     "process, then you cannot receive more entries than you send.  "
00374     "You aim to receive " << recvCounts[0] << " entries, but to send "
00375     << sendCount << " entries.");
00376   // Serial communicator case: just copy.  recvCounts[0] is the
00377   // amount to receive, so it's the amount to copy.  Start writing
00378   // to recvbuf at the offset displs[0].
00379   std::copy (sendBuf, sendBuf + recvCounts[0], recvBuf + displs[0]);
00380 #endif // HAVE_MPI
00381 }
00382 
00383 
00391 template<class T>
00392 void
00393 reduceAllAndScatterImpl (const Comm<int>& comm,
00394                          const EReductionType reductType,
00395                          const int sendCount,
00396                          const T sendBuffer[],
00397                          const int recvCounts[],
00398                          T myGlobalReducts[])
00399 {
00400 #ifdef HAVE_MPI
00401   // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
00402   // SerialComm or an MpiComm.  If it's something else, we fall back
00403   // to the most general implementation.
00404   const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
00405   if (mpiComm == NULL) {
00406     // Is it a SerialComm?
00407     const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
00408     if (serialComm == NULL) {
00409       TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "reduceAllAndScatter: "
00410         "Not implemented for Comm not MpiComm or SerialComm.");
00411     }
00412     else { // It's a SerialComm; there is only 1 process, so just copy.
00413       //
00414       // FIXME (mfh 09 Apr 2013) Is this right?  This is what
00415       // SerialComm does.
00416       //
00417       std::copy (sendBuffer, sendBuffer + sendCount, myGlobalReducts);
00418     }
00419   } else { // It's an MpiComm.  Invoke MPI directly.
00420     MPI_Op rawMpiOp = getMpiOpForEReductionType (reductType);
00421     MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
00422     T t;
00423     MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
00424     const int err = MPI_Reduce_scatter (const_cast<T*> (sendBuffer),
00425                                         myGlobalReducts,
00426                                         const_cast<int*> (recvCounts),
00427                                         rawMpiType,
00428                                         rawMpiOp,
00429                                         rawMpiComm);
00430     TEUCHOS_TEST_FOR_EXCEPTION(
00431       err != MPI_SUCCESS,
00432       std::runtime_error,
00433       "MPI_Reduce_scatter failed with the following error: "
00434       << getMpiErrorString (err));
00435   }
00436 #else
00437   // We've built without MPI, so just assume it's a SerialComm and copy the data.
00438   //
00439   // FIXME (mfh 09 Apr 2013) Is this right?  This is what SerialComm does.
00440   //
00441   std::copy (sendBuffer, sendBuffer + sendCount, myGlobalReducts);
00442 #endif // HAVE_MPI
00443 }
00444 
00445 
00451 template<typename Packet>
00452 RCP<Teuchos::CommRequest<int> >
00453 ireceiveGeneral(const Comm<int>& comm,
00454                 const ArrayRCP<Packet> &recvBuffer,
00455                 const int sourceRank)
00456 {
00457   TEUCHOS_COMM_TIME_MONITOR(
00458     "Teuchos::ireceive<int, " << "," << TypeNameTraits<Packet>::name ()
00459     << "> ( value type )"
00460     );
00461   ValueTypeSerializationBuffer<int, Packet>
00462     charRecvBuffer (recvBuffer.size (), recvBuffer.getRawPtr ());
00463   RCP<CommRequest<int> > commRequest =
00464     comm.ireceive (charRecvBuffer.getCharBufferView (), sourceRank);
00465   set_extra_data (recvBuffer, "buffer", inOutArg (commRequest));
00466   return commRequest;
00467 }
00468 
00471 template<typename Packet>
00472 RCP<Teuchos::CommRequest<int> >
00473 ireceiveGeneral (const ArrayRCP<Packet> &recvBuffer,
00474                  const int sourceRank,
00475                  const int tag,
00476                  const Comm<int>& comm)
00477 {
00478   TEUCHOS_COMM_TIME_MONITOR(
00479     "Teuchos::ireceive<int, " << "," << TypeNameTraits<Packet>::name ()
00480     << "> ( value type )"
00481     );
00482   ValueTypeSerializationBuffer<int, Packet>
00483     charRecvBuffer (recvBuffer.size (), recvBuffer.getRawPtr ());
00484   RCP<CommRequest<int> > commRequest =
00485     comm.ireceive (charRecvBuffer.getCharBufferView (), sourceRank, tag);
00486   set_extra_data (recvBuffer, "buffer", inOutArg (commRequest));
00487   return commRequest;
00488 }
00489 
00502 template<class T>
00503 RCP<CommRequest<int> >
00504 ireceiveImpl (const Comm<int>& comm,
00505               const ArrayRCP<T>& recvBuffer,
00506               const int sourceRank)
00507 {
00508 #ifdef HAVE_MPI
00509   // Even in an MPI build, Comm might be either a SerialComm or an
00510   // MpiComm.  If it's something else, we fall back to the most
00511   // general implementation.
00512   const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
00513   if (mpiComm == NULL) {
00514     // Is it a SerialComm?
00515     const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
00516     if (serialComm == NULL) {
00517       // We don't know what kind of Comm we have, so fall back to the
00518       // most general implementation.
00519       return ireceiveGeneral<T> (comm, recvBuffer, sourceRank);
00520     }
00521     else { // SerialComm doesn't implement ireceive anyway.
00522       TEUCHOS_TEST_FOR_EXCEPTION(
00523         true,
00524         std::logic_error,
00525         "ireceiveImpl: Not implemented for a serial communicator.");
00526     }
00527   }
00528   else { // It's an MpiComm.  Invoke MPI directly.
00529     MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
00530     T t;
00531     MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
00532     T* rawRecvBuf = recvBuffer.getRawPtr ();
00533     const int count = as<int> (recvBuffer.size ());
00534     const int tag = mpiComm->getTag ();
00535     MPI_Request rawRequest = MPI_REQUEST_NULL;
00536     const int err = MPI_Irecv (rawRecvBuf, count, rawType, sourceRank, tag,
00537                                rawComm, &rawRequest);
00538     TEUCHOS_TEST_FOR_EXCEPTION(
00539       err != MPI_SUCCESS, std::runtime_error,
00540       "MPI_Irecv failed with the following error: "
00541       << getMpiErrorString (err));
00542 
00543     ArrayRCP<const char> buf =
00544       arcp_const_cast<const char> (arcp_reinterpret_cast<char> (recvBuffer));
00545     RCP<Details::MpiCommRequest> req (new Details::MpiCommRequest (rawRequest, buf));
00546     return rcp_implicit_cast<CommRequest<int> > (req);
00547   }
00548 #else
00549   TEUCHOS_TEST_FOR_EXCEPTION(
00550     true,
00551     std::logic_error,
00552     "ireceiveImpl: Not implemented for a serial communicator.");
00553 
00554   // NOTE (mfh 15 Sep 2014): Most compilers have figured out that the
00555   // return statement below is unreachable.  Some older compilers
00556   // might not realize this.  That's why the return statement was put
00557   // there, so that those compilers don't warn that this function
00558   // doesn't return a value.  If it's a choice between one warning and
00559   // another, I would prefer the choice that produces less code and
00560   // doesn't have unreachable code (which never gets tested).
00561 
00562   //return null; // Guard to avoid compiler warning about not returning a value.
00563 #endif // HAVE_MPI
00564 }
00565 
00568 template<class T>
00569 RCP<CommRequest<int> >
00570 ireceiveImpl (const ArrayRCP<T>& recvBuffer,
00571               const int sourceRank,
00572               const int tag,
00573               const Comm<int>& comm)
00574 {
00575 #ifdef HAVE_MPI
00576   // Even in an MPI build, Comm might be either a SerialComm or an
00577   // MpiComm.  If it's something else, we fall back to the most
00578   // general implementation.
00579   const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
00580   if (mpiComm == NULL) {
00581     // Is it a SerialComm?
00582     const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
00583     if (serialComm == NULL) {
00584       // We don't know what kind of Comm we have, so fall back to the
00585       // most general implementation.
00586       return ireceiveGeneral<T> (recvBuffer, sourceRank, tag, comm);
00587     }
00588     else { // SerialComm doesn't implement ireceive anyway.
00589       TEUCHOS_TEST_FOR_EXCEPTION(
00590         true,
00591         std::logic_error,
00592         "ireceiveImpl: Not implemented for a serial communicator.");
00593     }
00594   }
00595   else { // It's an MpiComm.  Invoke MPI directly.
00596     MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
00597     T t;
00598     MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
00599     T* rawRecvBuf = recvBuffer.getRawPtr ();
00600     const int count = as<int> (recvBuffer.size ());
00601     MPI_Request rawRequest = MPI_REQUEST_NULL;
00602     const int err = MPI_Irecv (rawRecvBuf, count, rawType, sourceRank, tag,
00603                                rawComm, &rawRequest);
00604     TEUCHOS_TEST_FOR_EXCEPTION(
00605       err != MPI_SUCCESS, std::runtime_error,
00606       "MPI_Irecv failed with the following error: "
00607       << getMpiErrorString (err));
00608 
00609     ArrayRCP<const char> buf =
00610       arcp_const_cast<const char> (arcp_reinterpret_cast<char> (recvBuffer));
00611     RCP<Details::MpiCommRequest> req (new Details::MpiCommRequest (rawRequest, buf));
00612     return rcp_implicit_cast<CommRequest<int> > (req);
00613   }
00614 #else
00615   TEUCHOS_TEST_FOR_EXCEPTION(
00616     true,
00617     std::logic_error,
00618     "ireceiveImpl: Not implemented for a serial communicator.");
00619 
00620   return null; // Guard to avoid compiler warning about not returning a value.
00621 #endif // HAVE_MPI
00622 }
00623 
00629 template<class T>
00630 void
00631 sendGeneral (const Comm<int>& comm,
00632              const int count,
00633              const T sendBuffer[],
00634              const int destRank)
00635 {
00636   TEUCHOS_COMM_TIME_MONITOR(
00637     "Teuchos::send<int, " << TypeNameTraits<T>::name () << ">");
00638   ConstValueTypeSerializationBuffer<int,T> charSendBuffer (count, sendBuffer);
00639   comm.send (charSendBuffer.getBytes (),
00640              charSendBuffer.getCharBuffer (),
00641              destRank);
00642 }
00643 
00646 template<class T>
00647 void
00648 sendGeneral (const T sendBuffer[],
00649              const int count,
00650              const int destRank,
00651              const int tag,
00652              const Comm<int>& comm)
00653 {
00654   TEUCHOS_COMM_TIME_MONITOR(
00655     "Teuchos::send<int, " << TypeNameTraits<T>::name () << ">");
00656   ConstValueTypeSerializationBuffer<int,T> charSendBuffer (count, sendBuffer);
00657   comm.send (charSendBuffer.getBytes (),
00658              charSendBuffer.getCharBuffer (),
00659              destRank, tag);
00660 }
00661 
00674 template<class T>
00675 void
00676 sendImpl (const Comm<int>& comm,
00677           const int count,
00678           const T sendBuffer[],
00679           const int destRank)
00680 {
00681 #ifdef HAVE_MPI
00682   // Even in an MPI build, Comm might be either a SerialComm or an
00683   // MpiComm.  If it's something else, we fall back to the most
00684   // general implementation.
00685   const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
00686   if (mpiComm == NULL) {
00687     // Is it a SerialComm?
00688     const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
00689     if (serialComm == NULL) {
00690       // We don't know what kind of Comm we have, so fall back to the
00691       // most general implementation.
00692       sendGeneral<T> (comm, count, sendBuffer, destRank);
00693     }
00694     else { // SerialComm doesn't implement send correctly anyway.
00695       TEUCHOS_TEST_FOR_EXCEPTION(
00696         true,
00697         std::logic_error,
00698         "sendImpl: Not implemented for a serial communicator.");
00699     }
00700   }
00701   else { // It's an MpiComm.  Invoke MPI directly.
00702     MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
00703     T t;
00704     MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
00705     T* rawBuf = const_cast<T*> (sendBuffer);
00706     const int tag = mpiComm->getTag ();
00707     const int err = MPI_Send (rawBuf, count, rawType, destRank, tag, rawComm);
00708     TEUCHOS_TEST_FOR_EXCEPTION(
00709       err != MPI_SUCCESS,
00710       std::runtime_error,
00711       "MPI_Send failed with the following error: "
00712       << getMpiErrorString (err));
00713   }
00714 #else
00715   TEUCHOS_TEST_FOR_EXCEPTION(
00716     true,
00717     std::logic_error,
00718     "sendImpl: Not implemented for a serial communicator.");
00719 #endif // HAVE_MPI
00720 }
00721 
00724 template<class T>
00725 void
00726 sendImpl (const T sendBuffer[],
00727           const int count,
00728           const int destRank,
00729           const int tag,
00730           const Comm<int>& comm)
00731 {
00732 #ifdef HAVE_MPI
00733   // Even in an MPI build, Comm might be either a SerialComm or an
00734   // MpiComm.  If it's something else, we fall back to the most
00735   // general implementation.
00736   const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
00737   if (mpiComm == NULL) {
00738     // Is it a SerialComm?
00739     const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
00740     if (serialComm == NULL) {
00741       // We don't know what kind of Comm we have, so fall back to the
00742       // most general implementation.
00743       sendGeneral<T> (sendBuffer, count, destRank, tag, comm);
00744     }
00745     else { // SerialComm doesn't implement send correctly anyway.
00746       TEUCHOS_TEST_FOR_EXCEPTION(
00747         true,
00748         std::logic_error,
00749         "sendImpl: Not implemented for a serial communicator.");
00750     }
00751   }
00752   else { // It's an MpiComm.  Invoke MPI directly.
00753     MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
00754     T t;
00755     MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
00756     T* rawBuf = const_cast<T*> (sendBuffer);
00757     const int err = MPI_Send (rawBuf, count, rawType, destRank, tag, rawComm);
00758     TEUCHOS_TEST_FOR_EXCEPTION(
00759       err != MPI_SUCCESS,
00760       std::runtime_error,
00761       "MPI_Send failed with the following error: "
00762       << getMpiErrorString (err));
00763   }
00764 #else
00765   TEUCHOS_TEST_FOR_EXCEPTION(
00766     true,
00767     std::logic_error,
00768     "sendImpl: Not implemented for a serial communicator.");
00769 #endif // HAVE_MPI
00770 }
00771 
00777 template<class T>
00778 RCP<CommRequest<int> >
00779 isendGeneral (const Comm<int>& comm,
00780               const ArrayRCP<const T>& sendBuffer,
00781               const int destRank)
00782 {
00783   TEUCHOS_COMM_TIME_MONITOR(
00784     "Teuchos::isend<int," << TypeNameTraits<T>::name () << ">");
00785   ConstValueTypeSerializationBuffer<int, T>
00786     charSendBuffer (sendBuffer.size (), sendBuffer.getRawPtr ());
00787   RCP<CommRequest<int> > commRequest =
00788     comm.isend (charSendBuffer.getCharBufferView (), destRank);
00789   set_extra_data (sendBuffer, "buffer", inOutArg (commRequest));
00790   return commRequest;
00791 }
00792 
00799 template<class T>
00800 RCP<CommRequest<int> >
00801 isendGeneral (const ArrayRCP<const T>& sendBuffer,
00802               const int destRank,
00803               const int tag,
00804               const Comm<int>& comm)
00805 {
00806   TEUCHOS_COMM_TIME_MONITOR(
00807     "Teuchos::isend<int," << TypeNameTraits<T>::name () << ">");
00808   ConstValueTypeSerializationBuffer<int, T>
00809     charSendBuffer (sendBuffer.size (), sendBuffer.getRawPtr ());
00810   RCP<CommRequest<int> > commRequest =
00811     comm.isend (charSendBuffer.getCharBufferView (), destRank, tag);
00812   set_extra_data (sendBuffer, "buffer", inOutArg (commRequest));
00813   return commRequest;
00814 }
00815 
00818 template<class T>
00819 RCP<Teuchos::CommRequest<int> >
00820 isendImpl (const ArrayRCP<const T>& sendBuffer,
00821            const int destRank,
00822            const int tag,
00823            const Comm<int>& comm)
00824 {
00825 #ifdef HAVE_MPI
00826   // Even in an MPI build, Comm might be either a SerialComm or an
00827   // MpiComm.  If it's something else, we fall back to the most
00828   // general implementation.
00829   const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
00830   if (mpiComm == NULL) {
00831     // Is it a SerialComm?
00832     const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
00833     if (serialComm == NULL) {
00834       // We don't know what kind of Comm we have, so fall back to the
00835       // most general implementation.
00836       return isendGeneral<T> (sendBuffer, destRank, tag, comm);
00837     }
00838     else { // SerialComm doesn't implement send correctly anyway.
00839       TEUCHOS_TEST_FOR_EXCEPTION(
00840         true, std::logic_error,
00841         "isendImpl: Not implemented for a serial communicator.");
00842     }
00843   }
00844   else { // It's an MpiComm.  Invoke MPI directly.
00845     MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
00846     T t;
00847     MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
00848     // MPI promises not to modify the send buffer; the const_cast
00849     // merely ensures compatibilty with C89, which does not have a
00850     // "const" keyword.
00851     T* rawSendBuf = const_cast<T*> (sendBuffer.getRawPtr ());
00852     const int count = as<int> (sendBuffer.size ());
00853     MPI_Request rawRequest = MPI_REQUEST_NULL;
00854     const int err = MPI_Isend (rawSendBuf, count, rawType, destRank, tag,
00855                                rawComm, &rawRequest);
00856     TEUCHOS_TEST_FOR_EXCEPTION(
00857       err != MPI_SUCCESS,
00858       std::runtime_error,
00859       "MPI_Isend failed with the following error: "
00860       << getMpiErrorString (err));
00861 
00862     ArrayRCP<const char> buf = arcp_reinterpret_cast<const char> (sendBuffer);
00863     RCP<Details::MpiCommRequest> req (new Details::MpiCommRequest (rawRequest, buf));
00864     return rcp_implicit_cast<CommRequest<int> > (req);
00865   }
00866 #else
00867   TEUCHOS_TEST_FOR_EXCEPTION(
00868     true,
00869     std::logic_error,
00870     "isendImpl: Not implemented for a serial communicator.");
00871 #endif // HAVE_MPI
00872 }
00873 
00874 } // namespace (anonymous)
00875 
00876 
00877 const char*
00878 toString (const EReductionType reductType)
00879 {
00880   switch (reductType) {
00881   case REDUCE_SUM: return "REDUCE_SUM";
00882   case REDUCE_MIN: return "REDUCE_MIN";
00883   case REDUCE_MAX: return "REDUCE_MAX";
00884   case REDUCE_AND: return "REDUCE_AND";
00885   default:
00886     TEUCHOS_TEST_FOR_EXCEPTION(
00887       true, std::invalid_argument, "Teuchos::toString(EReductionType): "
00888       "Invalid EReductionType value " << reductType << ".  Valid values "
00889       "include REDUCE_SUM = " << REDUCE_SUM << ", REDUCE_MIN = " << REDUCE_MIN
00890       << ", REDUCE_MAX = " << REDUCE_MIN << ", and REDUCE_AND = " << REDUCE_AND
00891       << ".");
00892   }
00893 }
00894 
00895 
00896 // mfh 18 Oct 2012: Note on full template specializations
00897 //
00898 // To make Windows builds happy, declarations of full template
00899 // specializations (as found in Teuchos_CommHelpers.hpp) must use the
00900 // TEUCHOSCOMM_LIB_DLL_EXPORT macro.  However, _definitions_ of the
00901 // specializations (as found in this file) must _not_ use the macro.
00902 // That's why we don't use that macro here.
00903 
00904 #ifdef TEUCHOS_HAVE_COMPLEX
00905 // Specialization for Ordinal=int and Packet=std::complex<double>.
00906 template<>
00907 void
00908 reduceAll<int, std::complex<double> > (const Comm<int>& comm,
00909                                        const EReductionType reductType,
00910                                        const int count,
00911                                        const std::complex<double> sendBuffer[],
00912                                        std::complex<double> globalReducts[])
00913 {
00914   TEUCHOS_COMM_TIME_MONITOR(
00915     "Teuchos::reduceAll<int, std::complex<double> > (" << count << ", "
00916     << toString (reductType) << ")"
00917     );
00918   reduceAllImpl<std::complex<double> > (comm, reductType, count, sendBuffer, globalReducts);
00919 }
00920 
00921 template<>
00922 RCP<Teuchos::CommRequest<int> >
00923 ireceive<int, std::complex<double> > (const Comm<int>& comm,
00924                                       const ArrayRCP<std::complex<double> >& recvBuffer,
00925                                       const int sourceRank)
00926 {
00927   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<double> >");
00928   return ireceiveImpl<std::complex<double> > (comm, recvBuffer, sourceRank);
00929 }
00930 
00931 template<>
00932 RCP<Teuchos::CommRequest<int> >
00933 ireceive<int, std::complex<double> > (const ArrayRCP<std::complex<double> >& recvBuffer,
00934                                       const int sourceRank,
00935                                       const int tag,
00936                                       const Comm<int>& comm)
00937 {
00938   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<double> >");
00939   return ireceiveImpl<std::complex<double> > (recvBuffer, sourceRank, tag, comm);
00940 }
00941 
00942 template<>
00943 void
00944 send<int, std::complex<double> > (const Comm<int>& comm,
00945                                   const int count,
00946                                   const std::complex<double> sendBuffer[],
00947                                   const int destRank)
00948 {
00949   sendImpl<std::complex<double> > (comm, count, sendBuffer, destRank);
00950 }
00951 
00952 template<>
00953 void
00954 send<int, std::complex<double> > (const std::complex<double> sendBuffer[],
00955                                   const int count,
00956                                   const int destRank,
00957                                   const int tag,
00958                                   const Comm<int>& comm)
00959 {
00960   sendImpl<std::complex<double> > (sendBuffer, count, destRank, tag, comm);
00961 }
00962 
00963 template<>
00964 RCP<Teuchos::CommRequest<int> >
00965 isend (const ArrayRCP<const std::complex<double> >& sendBuffer,
00966        const int destRank,
00967        const int tag,
00968        const Comm<int>& comm)
00969 {
00970   return isendImpl<std::complex<double> > (sendBuffer, destRank, tag, comm);
00971 }
00972 
00973 // Specialization for Ordinal=int and Packet=std::complex<float>.
00974 template<>
00975 void
00976 reduceAll<int, std::complex<float> > (const Comm<int>& comm,
00977                                       const EReductionType reductType,
00978                                       const int count,
00979                                       const std::complex<float> sendBuffer[],
00980                                       std::complex<float> globalReducts[])
00981 {
00982   TEUCHOS_COMM_TIME_MONITOR(
00983     "Teuchos::reduceAll<int, std::complex<float> > (" << count << ", "
00984     << toString (reductType) << ")"
00985     );
00986   reduceAllImpl<std::complex<float> > (comm, reductType, count, sendBuffer, globalReducts);
00987 }
00988 
00989 template<>
00990 RCP<Teuchos::CommRequest<int> >
00991 ireceive<int, std::complex<float> > (const Comm<int>& comm,
00992                                      const ArrayRCP<std::complex<float> >& recvBuffer,
00993                                      const int sourceRank)
00994 {
00995   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<float> >");
00996   return ireceiveImpl<std::complex<float> > (comm, recvBuffer, sourceRank);
00997 }
00998 
00999 template<>
01000 RCP<Teuchos::CommRequest<int> >
01001 ireceive<int, std::complex<float> > (const ArrayRCP<std::complex<float> >& recvBuffer,
01002                                      const int sourceRank,
01003                                      const int tag,
01004                                      const Comm<int>& comm)
01005 {
01006   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<float> >");
01007   return ireceiveImpl<std::complex<float> > (recvBuffer, sourceRank, tag, comm);
01008 }
01009 
01010 template<>
01011 void
01012 send<int, std::complex<float> > (const Comm<int>& comm,
01013                                  const int count,
01014                                  const std::complex<float> sendBuffer[],
01015                                  const int destRank)
01016 {
01017   return sendImpl<std::complex<float> > (comm, count, sendBuffer, destRank);
01018 }
01019 
01020 template<>
01021 void
01022 send<int, std::complex<float> > (const std::complex<float> sendBuffer[],
01023                                  const int count,
01024                                  const int destRank,
01025                                  const int tag,
01026                                  const Comm<int>& comm)
01027 {
01028   return sendImpl<std::complex<float> > (sendBuffer, count, destRank, tag, comm);
01029 }
01030 
01031 template<>
01032 RCP<Teuchos::CommRequest<int> >
01033 isend (const ArrayRCP<const std::complex<float> >& sendBuffer,
01034        const int destRank,
01035        const int tag,
01036        const Comm<int>& comm)
01037 {
01038   return isendImpl<std::complex<float> > (sendBuffer, destRank, tag, comm);
01039 }
01040 #endif // TEUCHOS_HAVE_COMPLEX
01041 
01042 
01043 // Specialization for Ordinal=int and Packet=double.
01044 template<>
01045 void
01046 reduceAll<int, double> (const Comm<int>& comm,
01047                         const EReductionType reductType,
01048                         const int count,
01049                         const double sendBuffer[],
01050                         double globalReducts[])
01051 {
01052   TEUCHOS_COMM_TIME_MONITOR(
01053     "Teuchos::reduceAll<int, double> (" << count << ", "
01054     << toString (reductType) << ")"
01055     );
01056   reduceAllImpl<double> (comm, reductType, count, sendBuffer, globalReducts);
01057 }
01058 
01059 template<>
01060 RCP<Teuchos::CommRequest<int> >
01061 ireceive<int, double> (const Comm<int>& comm,
01062                        const ArrayRCP<double>& recvBuffer,
01063                        const int sourceRank)
01064 {
01065   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, double>");
01066   return ireceiveImpl<double> (comm, recvBuffer, sourceRank);
01067 }
01068 
01069 template<>
01070 RCP<Teuchos::CommRequest<int> >
01071 ireceive<int, double> (const ArrayRCP<double>& recvBuffer,
01072                        const int sourceRank,
01073                        const int tag,
01074                        const Comm<int>& comm)
01075 {
01076   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, double>");
01077   return ireceiveImpl<double> (recvBuffer, sourceRank, tag, comm);
01078 }
01079 
01080 template<>
01081 void
01082 send<int, double> (const Comm<int>& comm,
01083                    const int count,
01084                    const double sendBuffer[],
01085                    const int destRank)
01086 {
01087   return sendImpl<double> (comm, count, sendBuffer, destRank);
01088 }
01089 
01090 template<>
01091 void
01092 send<int, double> (const double sendBuffer[],
01093                    const int count,
01094                    const int destRank,
01095                    const int tag,
01096                    const Comm<int>& comm)
01097 {
01098   return sendImpl<double> (sendBuffer, count, destRank, tag, comm);
01099 }
01100 
01101 template<>
01102 RCP<Teuchos::CommRequest<int> >
01103 isend (const ArrayRCP<const double>& sendBuffer,
01104         const int destRank,
01105         const int tag,
01106         const Comm<int>& comm)
01107 {
01108   return isendImpl<double> (sendBuffer, destRank, tag, comm);
01109 }
01110 
01111 // Specialization for Ordinal=int and Packet=float.
01112 template<>
01113 void
01114 reduceAll<int, float> (const Comm<int>& comm,
01115                        const EReductionType reductType,
01116                        const int count,
01117                        const float sendBuffer[],
01118                        float globalReducts[])
01119 {
01120   TEUCHOS_COMM_TIME_MONITOR(
01121     "Teuchos::reduceAll<int, float> (" << count << ", "
01122     << toString (reductType) << ")"
01123     );
01124   reduceAllImpl<float> (comm, reductType, count, sendBuffer, globalReducts);
01125 }
01126 
01127 template<>
01128 RCP<Teuchos::CommRequest<int> >
01129 ireceive<int, float> (const Comm<int>& comm,
01130                       const ArrayRCP<float>& recvBuffer,
01131                       const int sourceRank)
01132 {
01133   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, float>");
01134   return ireceiveImpl<float> (comm, recvBuffer, sourceRank);
01135 }
01136 
01137 template<>
01138 RCP<Teuchos::CommRequest<int> >
01139 ireceive<int, float> (const ArrayRCP<float>& recvBuffer,
01140                       const int sourceRank,
01141                       const int tag,
01142                       const Comm<int>& comm)
01143 {
01144   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, float>");
01145   return ireceiveImpl<float> (recvBuffer, sourceRank, tag, comm);
01146 }
01147 
01148 template<>
01149 void
01150 send<int, float> (const Comm<int>& comm,
01151                   const int count,
01152                   const float sendBuffer[],
01153                   const int destRank)
01154 {
01155   return sendImpl<float> (comm, count, sendBuffer, destRank);
01156 }
01157 
01158 template<>
01159 void
01160 send<int, float> (const float sendBuffer[],
01161                   const int count,
01162                   const int destRank,
01163                   const int tag,
01164                   const Comm<int>& comm)
01165 {
01166   return sendImpl<float> (sendBuffer, count, destRank, tag, comm);
01167 }
01168 
01169 template<>
01170 RCP<Teuchos::CommRequest<int> >
01171 isend (const ArrayRCP<const float>& sendBuffer,
01172        const int destRank,
01173        const int tag,
01174        const Comm<int>& comm)
01175 {
01176   return isendImpl<float> (sendBuffer, destRank, tag, comm);
01177 }
01178 
01179 
01180 #ifdef TEUCHOS_HAVE_LONG_LONG_INT
01181 // Specialization for Ordinal=int and Packet=long long.
01182 template<>
01183 void
01184 gather<int, long long> (const long long sendBuf[],
01185                         const int sendCount,
01186                         long long recvBuf[],
01187                         const int recvCount,
01188                         const int root,
01189                         const Comm<int>& comm)
01190 {
01191   gatherImpl<long long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
01192 }
01193 
01194 template<>
01195 void
01196 gatherv<int, long long> (const long long sendBuf[],
01197                          const int sendCount,
01198                          long long recvBuf[],
01199                          const int recvCounts[],
01200                          const int displs[],
01201                          const int root,
01202                          const Comm<int>& comm)
01203 {
01204   gathervImpl<long long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
01205 }
01206 
01207 template<>
01208 void
01209 reduceAll<int, long long> (const Comm<int>& comm,
01210                            const EReductionType reductType,
01211                            const int count,
01212                            const long long sendBuffer[],
01213                            long long globalReducts[])
01214 {
01215   TEUCHOS_COMM_TIME_MONITOR(
01216     "Teuchos::reduceAll<int, long long> (" << count << ", "
01217     << toString (reductType) << ")"
01218     );
01219   reduceAllImpl<long long> (comm, reductType, count, sendBuffer, globalReducts);
01220 }
01221 
01222 template<>
01223 RCP<Teuchos::CommRequest<int> >
01224 ireceive<int, long long> (const Comm<int>& comm,
01225                           const ArrayRCP<long long>& recvBuffer,
01226                           const int sourceRank)
01227 {
01228   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long long>");
01229   return ireceiveImpl<long long> (comm, recvBuffer, sourceRank);
01230 }
01231 
01232 template<>
01233 RCP<Teuchos::CommRequest<int> >
01234 ireceive<int, long long> (const ArrayRCP<long long>& recvBuffer,
01235                           const int sourceRank,
01236                           const int tag,
01237                           const Comm<int>& comm)
01238 {
01239   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long long>");
01240   return ireceiveImpl<long long> (recvBuffer, sourceRank, tag, comm);
01241 }
01242 
01243 template<>
01244 void
01245 send<int, long long> (const Comm<int>& comm,
01246                       const int count,
01247                       const long long sendBuffer[],
01248                       const int destRank)
01249 {
01250   return sendImpl<long long> (comm, count, sendBuffer, destRank);
01251 }
01252 
01253 template<>
01254 void
01255 send<int, long long> (const long long sendBuffer[],
01256                       const int count,
01257                       const int destRank,
01258                       const int tag,
01259                       const Comm<int>& comm)
01260 {
01261   return sendImpl<long long> (sendBuffer, count, destRank, tag, comm);
01262 }
01263 
01264 template<>
01265 RCP<Teuchos::CommRequest<int> >
01266 isend (const ArrayRCP<const long long>& sendBuffer,
01267        const int destRank,
01268        const int tag,
01269        const Comm<int>& comm)
01270 {
01271   return isendImpl<long long> (sendBuffer, destRank, tag, comm);
01272 }
01273 
01274 // Specialization for Ordinal=int and Packet=unsigned long long.
01275 template<>
01276 void
01277 gather<int, unsigned long long> (const unsigned long long sendBuf[],
01278                                  const int sendCount,
01279                                  unsigned long long recvBuf[],
01280                                  const int recvCount,
01281                                  const int root,
01282                                  const Comm<int>& comm)
01283 {
01284   gatherImpl<unsigned long long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
01285 }
01286 
01287 template<>
01288 void
01289 gatherv<int, unsigned long long> (const unsigned long long sendBuf[],
01290                                   const int sendCount,
01291                                   unsigned long long recvBuf[],
01292                                   const int recvCounts[],
01293                                   const int displs[],
01294                                   const int root,
01295                                   const Comm<int>& comm)
01296 {
01297   gathervImpl<unsigned long long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
01298 }
01299 
01300 template<>
01301 void
01302 reduceAll<int, unsigned long long> (const Comm<int>& comm,
01303                                     const EReductionType reductType,
01304                                     const int count,
01305                                     const unsigned long long sendBuffer[],
01306                                     unsigned long long globalReducts[])
01307 {
01308   TEUCHOS_COMM_TIME_MONITOR(
01309     "Teuchos::reduceAll<int, unsigned long long> (" << count << ", "
01310     << toString (reductType) << ")"
01311     );
01312   reduceAllImpl<unsigned long long> (comm, reductType, count, sendBuffer, globalReducts);
01313 }
01314 
01315 template<>
01316 RCP<Teuchos::CommRequest<int> >
01317 ireceive<int, unsigned long long> (const Comm<int>& comm,
01318                                    const ArrayRCP<unsigned long long>& recvBuffer,
01319                                    const int sourceRank)
01320 {
01321   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long long>");
01322   return ireceiveImpl<unsigned long long> (comm, recvBuffer, sourceRank);
01323 }
01324 
01325 template<>
01326 RCP<Teuchos::CommRequest<int> >
01327 ireceive<int, unsigned long long> (const ArrayRCP<unsigned long long>& recvBuffer,
01328                                    const int sourceRank,
01329                                    const int tag,
01330                                    const Comm<int>& comm)
01331 {
01332   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long long>");
01333   return ireceiveImpl<unsigned long long> (recvBuffer, sourceRank, tag, comm);
01334 }
01335 
01336 template<>
01337 void
01338 send<int, unsigned long long> (const Comm<int>& comm,
01339                                const int count,
01340                                const unsigned long long sendBuffer[],
01341                                const int destRank)
01342 {
01343   return sendImpl<unsigned long long> (comm, count, sendBuffer, destRank);
01344 }
01345 
01346 template<>
01347 void
01348 send<int, unsigned long long> (const unsigned long long sendBuffer[],
01349                                const int count,
01350                                const int destRank,
01351                                const int tag,
01352                                const Comm<int>& comm)
01353 {
01354   return sendImpl<unsigned long long> (sendBuffer, count, destRank, tag, comm);
01355 }
01356 
01357 template<>
01358 RCP<Teuchos::CommRequest<int> >
01359 isend (const ArrayRCP<const unsigned long long>& sendBuffer,
01360        const int destRank,
01361        const int tag,
01362        const Comm<int>& comm)
01363 {
01364   return isendImpl<unsigned long long> (sendBuffer, destRank, tag, comm);
01365 }
01366 
01367 #endif // TEUCHOS_HAVE_LONG_LONG_INT
01368 
01369 
01370 // Specialization for Ordinal=int and Packet=long.
01371 template<>
01372 void
01373 gather<int, long> (const long sendBuf[],
01374                    const int sendCount,
01375                    long recvBuf[],
01376                    const int recvCount,
01377                    const int root,
01378                    const Comm<int>& comm)
01379 {
01380   gatherImpl<long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
01381 }
01382 
01383 template<>
01384 void
01385 gatherv<int, long> (const long sendBuf[],
01386                     const int sendCount,
01387                     long recvBuf[],
01388                     const int recvCounts[],
01389                     const int displs[],
01390                     const int root,
01391                     const Comm<int>& comm)
01392 {
01393   gathervImpl<long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
01394 }
01395 
01396 template<>
01397 void
01398 reduceAll<int, long> (const Comm<int>& comm,
01399                       const EReductionType reductType,
01400                       const int count,
01401                       const long sendBuffer[],
01402                       long globalReducts[])
01403 {
01404   TEUCHOS_COMM_TIME_MONITOR(
01405     "Teuchos::reduceAll<int, long> (" << count << ", "
01406     << toString (reductType) << ")"
01407     );
01408   reduceAllImpl<long> (comm, reductType, count, sendBuffer, globalReducts);
01409 }
01410 
01411 template<>
01412 RCP<Teuchos::CommRequest<int> >
01413 ireceive<int, long> (const Comm<int>& comm,
01414                      const ArrayRCP<long>& recvBuffer,
01415                      const int sourceRank)
01416 {
01417   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long>");
01418   return ireceiveImpl<long> (comm, recvBuffer, sourceRank);
01419 }
01420 
01421 template<>
01422 RCP<Teuchos::CommRequest<int> >
01423 ireceive<int, long> (const ArrayRCP<long>& recvBuffer,
01424                      const int sourceRank,
01425                      const int tag,
01426                      const Comm<int>& comm)
01427 {
01428   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long>");
01429   return ireceiveImpl<long> (recvBuffer, sourceRank, tag, comm);
01430 }
01431 
01432 template<>
01433 void
01434 send<int, long> (const Comm<int>& comm,
01435                  const int count,
01436                  const long sendBuffer[],
01437                  const int destRank)
01438 {
01439   return sendImpl<long> (comm, count, sendBuffer, destRank);
01440 }
01441 
01442 template<>
01443 void
01444 send<int, long> (const long sendBuffer[],
01445                  const int count,
01446                  const int destRank,
01447                  const int tag,
01448                  const Comm<int>& comm)
01449 {
01450   return sendImpl<long> (sendBuffer, count, destRank, tag, comm);
01451 }
01452 
01453 template<>
01454 RCP<Teuchos::CommRequest<int> >
01455 isend (const ArrayRCP<const long>& sendBuffer,
01456        const int destRank,
01457        const int tag,
01458        const Comm<int>& comm)
01459 {
01460   return isendImpl<long> (sendBuffer, destRank, tag, comm);
01461 }
01462 
01463 
01464 // Specialization for Ordinal=int and Packet=unsigned long.
01465 template<>
01466 void
01467 gather<int, unsigned long> (const unsigned long sendBuf[],
01468                             const int sendCount,
01469                             unsigned long recvBuf[],
01470                             const int recvCount,
01471                             const int root,
01472                             const Comm<int>& comm)
01473 {
01474   gatherImpl<unsigned long> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
01475 }
01476 
01477 template<>
01478 void
01479 gatherv<int, unsigned long> (const unsigned long sendBuf[],
01480                              const int sendCount,
01481                              unsigned long recvBuf[],
01482                              const int recvCounts[],
01483                              const int displs[],
01484                              const int root,
01485                              const Comm<int>& comm)
01486 {
01487   gathervImpl<unsigned long> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
01488 }
01489 
01490 template<>
01491 void
01492 reduceAll<int, unsigned long> (const Comm<int>& comm,
01493                                const EReductionType reductType,
01494                                const int count,
01495                                const unsigned long sendBuffer[],
01496                                unsigned long globalReducts[])
01497 {
01498   TEUCHOS_COMM_TIME_MONITOR(
01499     "Teuchos::reduceAll<int, unsigned long> (" << count << ", "
01500     << toString (reductType) << ")"
01501     );
01502   reduceAllImpl<unsigned long> (comm, reductType, count, sendBuffer, globalReducts);
01503 }
01504 
01505 template<>
01506 RCP<Teuchos::CommRequest<int> >
01507 ireceive<int, unsigned long> (const Comm<int>& comm,
01508                               const ArrayRCP<unsigned long>& recvBuffer,
01509                               const int sourceRank)
01510 {
01511   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long>");
01512   return ireceiveImpl<unsigned long> (comm, recvBuffer, sourceRank);
01513 }
01514 
01515 template<>
01516 RCP<Teuchos::CommRequest<int> >
01517 ireceive<int, unsigned long> (const ArrayRCP<unsigned long>& recvBuffer,
01518                               const int sourceRank,
01519                               const int tag,
01520                               const Comm<int>& comm)
01521 {
01522   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned long>");
01523   return ireceiveImpl<unsigned long> (recvBuffer, sourceRank, tag, comm);
01524 }
01525 
01526 template<>
01527 void
01528 send<int, unsigned long> (const Comm<int>& comm,
01529                           const int count,
01530                           const unsigned long sendBuffer[],
01531                           const int destRank)
01532 {
01533   return sendImpl<unsigned long> (comm, count, sendBuffer, destRank);
01534 }
01535 
01536 template<>
01537 void
01538 send<int, unsigned long> (const unsigned long sendBuffer[],
01539                  const int count,
01540                  const int destRank,
01541                  const int tag,
01542                  const Comm<int>& comm)
01543 {
01544   return sendImpl<unsigned long> (sendBuffer, count, destRank, tag, comm);
01545 }
01546 
01547 template<>
01548 RCP<Teuchos::CommRequest<int> >
01549 isend (const ArrayRCP<const unsigned long>& sendBuffer,
01550        const int destRank,
01551        const int tag,
01552        const Comm<int>& comm)
01553 {
01554   return isendImpl<unsigned long> (sendBuffer, destRank, tag, comm);
01555 }
01556 
01557 // Specialization for Ordinal=int and Packet=int.
01558 template<>
01559 void
01560 gather<int, int> (const int sendBuf[],
01561                   const int sendCount,
01562                   int recvBuf[],
01563                   const int recvCount,
01564                   const int root,
01565                   const Comm<int>& comm)
01566 {
01567   gatherImpl<int> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
01568 }
01569 
01570 template<>
01571 void
01572 gatherv<int, int> (const int sendBuf[],
01573                    const int sendCount,
01574                    int recvBuf[],
01575                    const int recvCounts[],
01576                    const int displs[],
01577                    const int root,
01578                    const Comm<int>& comm)
01579 {
01580   gathervImpl<int> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
01581 }
01582 
01583 template<>
01584 void
01585 reduceAll<int, int> (const Comm<int>& comm,
01586                      const EReductionType reductType,
01587                      const int count,
01588                      const int sendBuffer[],
01589                      int globalReducts[])
01590 {
01591   TEUCHOS_COMM_TIME_MONITOR(
01592     "Teuchos::reduceAll<int, int> (" << count << ", "
01593     << toString (reductType) << ")"
01594     );
01595   reduceAllImpl<int> (comm, reductType, count, sendBuffer, globalReducts);
01596 }
01597 
01598 template<>
01599 void
01600 reduceAllAndScatter<int, int> (const Comm<int>& comm,
01601                                const EReductionType reductType,
01602                                const int sendCount,
01603                                const int sendBuffer[],
01604                                const int recvCounts[],
01605                                int myGlobalReducts[])
01606 {
01607   reduceAllAndScatterImpl<int> (comm, reductType, sendCount, sendBuffer,
01608                                 recvCounts, myGlobalReducts);
01609 }
01610 
01611 template<>
01612 RCP<Teuchos::CommRequest<int> >
01613 ireceive<int, int> (const Comm<int>& comm,
01614                     const ArrayRCP<int>& recvBuffer,
01615                     const int sourceRank)
01616 {
01617   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, int>");
01618   return ireceiveImpl<int> (comm, recvBuffer, sourceRank);
01619 }
01620 
01621 template<>
01622 RCP<Teuchos::CommRequest<int> >
01623 ireceive<int, int> (const ArrayRCP<int>& recvBuffer,
01624                     const int sourceRank,
01625                     const int tag,
01626                     const Comm<int>& comm)
01627 {
01628   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, int>");
01629   return ireceiveImpl<int> (recvBuffer, sourceRank, tag, comm);
01630 }
01631 
01632 template<>
01633 void
01634 send<int, int> (const Comm<int>& comm,
01635                 const int count,
01636                 const int sendBuffer[],
01637                 const int destRank)
01638 {
01639   return sendImpl<int> (comm, count, sendBuffer, destRank);
01640 }
01641 
01642 template<>
01643 void
01644 send<int, int> (const int sendBuffer[],
01645                 const int count,
01646                 const int destRank,
01647                 const int tag,
01648                 const Comm<int>& comm)
01649 {
01650   return sendImpl<int> (sendBuffer, count, destRank, tag, comm);
01651 }
01652 
01653 template<>
01654 RCP<Teuchos::CommRequest<int> >
01655 isend (const ArrayRCP<const int>& sendBuffer,
01656        const int destRank,
01657        const int tag,
01658        const Comm<int>& comm)
01659 {
01660   return isendImpl<int> (sendBuffer, destRank, tag, comm);
01661 }
01662 
01663 // Specialization for Ordinal=int and Packet=unsigned int.
01664 template<>
01665 void
01666 gather<int, unsigned int> (const unsigned int sendBuf[],
01667                             const int sendCount,
01668                             unsigned int recvBuf[],
01669                             const int recvCount,
01670                             const int root,
01671                             const Comm<int>& comm)
01672 {
01673   gatherImpl<unsigned int> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
01674 }
01675 
01676 template<>
01677 void
01678 gatherv<int, unsigned int> (const unsigned int sendBuf[],
01679                              const int sendCount,
01680                              unsigned int recvBuf[],
01681                              const int recvCounts[],
01682                              const int displs[],
01683                              const int root,
01684                              const Comm<int>& comm)
01685 {
01686   gathervImpl<unsigned int> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
01687 }
01688 
01689 template<>
01690 void
01691 reduceAll<int, unsigned int> (const Comm<int>& comm,
01692                               const EReductionType reductType,
01693                               const int count,
01694                               const unsigned int sendBuffer[],
01695                               unsigned int globalReducts[])
01696 {
01697   TEUCHOS_COMM_TIME_MONITOR(
01698     "Teuchos::reduceAll<int, unsigned int> (" << count << ", "
01699     << toString (reductType) << ")"
01700     );
01701   reduceAllImpl<unsigned int> (comm, reductType, count, sendBuffer, globalReducts);
01702 }
01703 
01704 template<>
01705 RCP<Teuchos::CommRequest<int> >
01706 ireceive<int, unsigned int> (const Comm<int>& comm,
01707                              const ArrayRCP<unsigned int>& recvBuffer,
01708                              const int sourceRank)
01709 {
01710   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned int>");
01711   return ireceiveImpl<unsigned int> (comm, recvBuffer, sourceRank);
01712 }
01713 
01714 template<>
01715 RCP<Teuchos::CommRequest<int> >
01716 ireceive<int, unsigned int> (const ArrayRCP<unsigned int>& recvBuffer,
01717                              const int sourceRank,
01718                              const int tag,
01719                              const Comm<int>& comm)
01720 {
01721   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, unsigned int>");
01722   return ireceiveImpl<unsigned int> (recvBuffer, sourceRank, tag, comm);
01723 }
01724 
01725 template<>
01726 void
01727 send<int, unsigned int> (const Comm<int>& comm,
01728                          const int count,
01729                          const unsigned int sendBuffer[],
01730                          const int destRank)
01731 {
01732   return sendImpl<unsigned int> (comm, count, sendBuffer, destRank);
01733 }
01734 
01735 template<>
01736 void
01737 send<int, unsigned int> (const unsigned int sendBuffer[],
01738                          const int count,
01739                          const int destRank,
01740                          const int tag,
01741                          const Comm<int>& comm)
01742 {
01743   return sendImpl<unsigned int> (sendBuffer, count, destRank, tag, comm);
01744 }
01745 
01746 template<>
01747 RCP<Teuchos::CommRequest<int> >
01748 isend (const ArrayRCP<const unsigned int>& sendBuffer,
01749        const int destRank,
01750        const int tag,
01751        const Comm<int>& comm)
01752 {
01753   return isendImpl<unsigned int> (sendBuffer, destRank, tag, comm);
01754 }
01755 
01756 
01757 // Specialization for Ordinal=int and Packet=short.
01758 template<>
01759 void
01760 gather<int, short> (const short sendBuf[],
01761                     const int sendCount,
01762                     short recvBuf[],
01763                     const int recvCount,
01764                     const int root,
01765                     const Comm<int>& comm)
01766 {
01767   gatherImpl<short> (sendBuf, sendCount, recvBuf, recvCount, root, comm);
01768 }
01769 
01770 template<>
01771 void
01772 gatherv<int, short> (const short sendBuf[],
01773                      const int sendCount,
01774                      short recvBuf[],
01775                      const int recvCounts[],
01776                      const int displs[],
01777                      const int root,
01778                      const Comm<int>& comm)
01779 {
01780   gathervImpl<short> (sendBuf, sendCount, recvBuf, recvCounts, displs, root, comm);
01781 }
01782 
01783 template<>
01784 void
01785 reduceAll<int, short> (const Comm<int>& comm,
01786                        const EReductionType reductType,
01787                        const int count,
01788                        const short sendBuffer[],
01789                        short globalReducts[])
01790 {
01791   TEUCHOS_COMM_TIME_MONITOR(
01792     "Teuchos::reduceAll<int, short> (" << count << ", "
01793     << toString (reductType) << ")"
01794     );
01795   reduceAllImpl<short> (comm, reductType, count, sendBuffer, globalReducts);
01796 }
01797 
01798 template<>
01799 RCP<Teuchos::CommRequest<int> >
01800 ireceive<int, short> (const Comm<int>& comm,
01801                       const ArrayRCP<short>& recvBuffer,
01802                       const int sourceRank)
01803 {
01804   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, short>");
01805   return ireceiveImpl<short> (comm, recvBuffer, sourceRank);
01806 }
01807 
01808 template<>
01809 RCP<Teuchos::CommRequest<int> >
01810 ireceive<int, short> (const ArrayRCP<short>& recvBuffer,
01811                       const int sourceRank,
01812                       const int tag,
01813                       const Comm<int>& comm)
01814 {
01815   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, short>");
01816   return ireceiveImpl<short> (recvBuffer, sourceRank, tag, comm);
01817 }
01818 
01819 template<>
01820 void
01821 send<int, short> (const Comm<int>& comm,
01822                   const int count,
01823                   const short sendBuffer[],
01824                   const int destRank)
01825 {
01826   return sendImpl<short> (comm, count, sendBuffer, destRank);
01827 }
01828 
01829 template<>
01830 void
01831 send<int, short> (const short sendBuffer[],
01832                   const int count,
01833                   const int destRank,
01834                   const int tag,
01835                   const Comm<int>& comm)
01836 {
01837   return sendImpl<short> (sendBuffer, count, destRank, tag, comm);
01838 }
01839 
01840 template<>
01841 RCP<Teuchos::CommRequest<int> >
01842 isend (const ArrayRCP<const short>& sendBuffer,
01843        const int destRank,
01844        const int tag,
01845        const Comm<int>& comm)
01846 {
01847   return isendImpl<short> (sendBuffer, destRank, tag, comm);
01848 }
01849 
01850 // mfh 18 Oct 2012: The specialization for Packet=char seems to be
01851 // causing problems such as the following:
01852 //
01853 // http://testing.sandia.gov/cdash/testDetails.php?test=9909246&build=747699
01854 //
01855 // I am disabling it for now.  This should revert back to the old
01856 // behavior for Packet=char.  That should fix the Tpetra errors, since
01857 // many Tpetra objects inherit from DistObject<char, ...>.
01858 #if 0
01859 // Specialization for Ordinal=int and Packet=char.
01860 template<>
01861 void
01862 reduceAll<int, char> (const Comm<int>& comm,
01863                       const EReductionType reductType,
01864                       const int count,
01865                       const char sendBuffer[],
01866                       char globalReducts[])
01867 {
01868   TEUCHOS_COMM_TIME_MONITOR(
01869     "Teuchos::reduceAll<int, char> (" << count << ", "
01870     << toString (reductType) << ")"
01871     );
01872   reduceAllImpl<char> (comm, reductType, count, sendBuffer, globalReducts);
01873 }
01874 #endif // 0
01875 
01876 } // namespace Teuchos
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines