Teuchos - Trilinos Tools Package Version of the Day
Teuchos_CommHelpers.cpp
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 
00044 namespace Teuchos {
00045 namespace { // (anonymous)
00046 
00047 #ifdef HAVE_MPI
00048 
00049 MPI_Op getMpiOpForEReductionType (const enum EReductionType reductionType) {
00050   switch (reductionType) {
00051   case REDUCE_SUM: return MPI_SUM;
00052   case REDUCE_MIN: return MPI_MIN;
00053   case REDUCE_MAX: return MPI_MAX;
00054   case REDUCE_AND: return MPI_LAND; // logical AND, not bitwise AND
00055   default:
00056     TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, 
00057       "The given EReductionType value is invalid."); 
00058   }
00059 }
00060 
00064 std::string getMpiErrorString (const int errCode) {
00065   // Space for storing the error string returned by MPI.
00066   // Leave room for null termination, since I don't know if MPI does this.
00067   char errString [MPI_MAX_ERROR_STRING+1];
00068   int errStringLen = MPI_MAX_ERROR_STRING; // output argument
00069   (void) MPI_Error_string (errCode, errString, &errStringLen);
00070   // errStringLen on output is the number of characters written.
00071   // I'm not sure (the MPI 3.0 Standard doesn't say) if this
00072   // includes the '\0', so I'll make sure.  We reserved space for
00073   // the extra '\0' if needed.
00074   if (errString[errStringLen-1] != '\0') {
00075     errString[errStringLen] = '\0';
00076   }
00077   return std::string (errString); // This copies the original string.
00078 }
00079 
00087 template<class T>
00088 class MpiTypeTraits {
00089 public:
00095   static MPI_Datatype getType (const T&);
00096 };
00097 
00098 #ifdef TEUCHOS_HAVE_COMPLEX
00099 template<>
00100 class MpiTypeTraits<std::complex<double> > {
00101 public:
00102   static MPI_Datatype getType (const T&) {
00103     return MPI_C_DOUBLE_COMPLEX;
00104   }
00105 };
00106 
00107 template<>
00108 class MpiTypeTraits<std::complex<float> > {
00109 public:
00110   static MPI_Datatype getType (const T&) {
00111     return MPI_C_FLOAT_COMPLEX;
00112   }
00113 };
00114 #endif // TEUCHOS_HAVE_COMPLEX
00115 
00116 template<>
00117 class MpiTypeTraits<double> {
00118 public:
00119   static MPI_Datatype getType (const double&) {
00120     return MPI_DOUBLE;
00121   }
00122 };
00123 
00124 template<>
00125 class MpiTypeTraits<float> {
00126 public:
00127   static MPI_Datatype getType (const float&) {
00128     return MPI_FLOAT;
00129   }
00130 };
00131 
00132 #ifdef TEUCHOS_HAVE_LONG_LONG_INT
00133 template<>
00134 class MpiTypeTraits<long long> {
00135 public:
00136   static MPI_Datatype getType (const long long&) {
00137     return MPI_LONG_LONG;
00138   }
00139 };
00140 #endif // TEUCHOS_HAVE_LONG_LONG_INT
00141 
00142 template<>
00143 class MpiTypeTraits<long> {
00144 public:
00145   static MPI_Datatype getType (const long&) {
00146     return MPI_LONG;
00147   }
00148 };
00149 
00150 template<>
00151 class MpiTypeTraits<int> {
00152 public:
00153   static MPI_Datatype getType (const int&) {
00154     return MPI_INT;
00155   }
00156 };
00157 
00158 template<>
00159 class MpiTypeTraits<short> {
00160 public:
00161   static MPI_Datatype getType (const short&) {
00162     return MPI_SHORT;
00163   }
00164 };
00165 #endif // HAVE_MPI
00166 
00167 
00175 template<class T>
00176 void 
00177 reduceAllImpl (const Comm<int>& comm, 
00178          const EReductionType reductType,
00179          const int count, 
00180          const T sendBuffer[], 
00181          T globalReducts[])
00182 {
00183 #ifdef HAVE_MPI
00184   // mfh 17 Oct 2012: Even in an MPI build, Comm might be either a
00185   // SerialComm or an MpiComm.  If it's something else, we fall back
00186   // to the most general implementation.
00187   const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
00188   if (mpiComm == NULL) {
00189     // Is it a SerialComm?
00190     const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
00191     if (serialComm == NULL) { 
00192       // We don't know what kind of Comm we have, so fall back to the
00193       // most general implementation.
00194       std::auto_ptr<ValueTypeReductionOp<int, T> > reductOp (createOp<int, T> (reductType));
00195       reduceAll (comm, *reductOp, count, sendBuffer, globalReducts);
00196     } 
00197     else { // It's a SerialComm; there is only 1 process, so just copy.
00198       std::copy (sendBuffer, sendBuffer + count, globalReducts);
00199     }
00200   } else { // It's an MpiComm.  Invoke MPI directly.
00201     MPI_Op rawMpiOp = getMpiOpForEReductionType (reductType);
00202     MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
00203     T t;
00204     MPI_Datatype rawMpiType = MpiTypeTraits<T>::getType (t);
00205     const int err = MPI_Allreduce (const_cast<T*> (sendBuffer), 
00206       globalReducts, count, rawMpiType, rawMpiOp, rawMpiComm);
00207     TEUCHOS_TEST_FOR_EXCEPTION(
00208       err != MPI_SUCCESS, 
00209       std::runtime_error,
00210       "MPI_Allreduce failed with the following error: " 
00211       << getMpiErrorString (err));
00212   }
00213 #else 
00214   // We've built without MPI, so just assume it's a SerialComm and copy the data.
00215   std::copy (sendBuffer, sendBuffer + count, globalReducts);
00216 #endif // HAVE_MPI
00217 }
00218 
00224 template<typename Packet>
00225 RCP<Teuchos::CommRequest<int> >
00226 ireceiveGeneral(const Comm<int>& comm,
00227     const ArrayRCP<Packet> &recvBuffer,
00228     const int sourceRank)
00229 {
00230   typedef std::pair<RCP<CommRequest<int> >, ArrayRCP<const Packet> > comm_buffer_pair_t;
00231   TEUCHOS_COMM_TIME_MONITOR(
00232     "Teuchos::ireceive<int, " << "," << TypeNameTraits<Packet>::name () 
00233     << "> ( value type )"
00234     );
00235   ValueTypeSerializationBuffer<int, Packet>
00236     charRecvBuffer (recvBuffer.size (), recvBuffer.getRawPtr ());
00237   RCP<CommRequest<int> > commRequest = 
00238     comm.ireceive (charRecvBuffer.getCharBufferView (), sourceRank);
00239   set_extra_data (recvBuffer, "buffer", inOutArg (commRequest));
00240   return commRequest;
00241 }
00242 
00255 template<class T>
00256 RCP<CommRequest<int> >
00257 ireceiveImpl (const Comm<int>& comm, 
00258         const ArrayRCP<T>& recvBuffer,
00259         const int sourceRank)
00260 {
00261 #ifdef HAVE_MPI
00262   // Even in an MPI build, Comm might be either a SerialComm or an
00263   // MpiComm.  If it's something else, we fall back to the most
00264   // general implementation.
00265   const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
00266   if (mpiComm == NULL) {
00267     // Is it a SerialComm?
00268     const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
00269     if (serialComm == NULL) { 
00270       // We don't know what kind of Comm we have, so fall back to the
00271       // most general implementation.
00272       return ireceiveGeneral<T> (comm, recvBuffer, sourceRank);
00273     } 
00274     else { // SerialComm doesn't implement ireceive anyway.
00275       TEUCHOS_TEST_FOR_EXCEPTION(
00276         true,
00277   std::logic_error,
00278   "ireceiveImpl: Not implemented for a serial communicator.");
00279     }
00280   } 
00281   else { // It's an MpiComm.  Invoke MPI directly.
00282     MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
00283     T t;
00284     MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
00285     T* rawRecvBuf = recvBuffer.getRawPtr ();
00286     const int count = as<int> (recvBuffer.size ());
00287     const int tag = mpiComm->getTag ();
00288     MPI_Request rawRequest = MPI_REQUEST_NULL;
00289     const int err = MPI_Irecv (rawRecvBuf, count, rawType, sourceRank, tag, 
00290              rawComm, &rawRequest);
00291     TEUCHOS_TEST_FOR_EXCEPTION(
00292       err != MPI_SUCCESS, 
00293       std::runtime_error,
00294       "MPI_Irecv failed with the following error: " 
00295       << getMpiErrorString (err));
00296     // The number of bytes is only valid if sizeof(T) says how much
00297     // data lives in an T instance.
00298     RCP<MpiCommRequest<int> > req (new MpiCommRequest<int> (rawRequest, count * sizeof(T)));
00299     // mfh 13 Jan 2013: This ensures survival of the buffer until the
00300     // request is waited on, by tying the request to the buffer (so
00301     // that the buffer will survive at least as long as the request).
00302     set_extra_data (recvBuffer, "buffer", inOutArg (req));
00303     return rcp_implicit_cast<CommRequest<int> > (req);
00304   }
00305 #else 
00306   TEUCHOS_TEST_FOR_EXCEPTION(
00307     true,
00308     std::logic_error,
00309     "ireceiveImpl: Not implemented for a serial communicator.");
00310 
00311   return null; // Guard to avoid compiler warning about not returning a value.
00312 #endif // HAVE_MPI
00313 }
00314 
00320 template<class T>
00321 void
00322 sendGeneral (const Comm<int>& comm, 
00323        const int count,
00324        const T sendBuffer[],
00325        const int destRank)
00326 {
00327   TEUCHOS_COMM_TIME_MONITOR(
00328     "Teuchos::send<int, " << TypeNameTraits<T>::name () << ">");
00329   ConstValueTypeSerializationBuffer<int,T> charSendBuffer (count, sendBuffer);
00330   comm.send (charSendBuffer.getBytes (),
00331        charSendBuffer.getCharBuffer (),
00332        destRank);
00333 }
00334 
00347 template<class T>
00348 void
00349 sendImpl (const Comm<int>& comm, 
00350     const int count,
00351     const T sendBuffer[],
00352     const int destRank)
00353 {
00354 #ifdef HAVE_MPI
00355   // Even in an MPI build, Comm might be either a SerialComm or an
00356   // MpiComm.  If it's something else, we fall back to the most
00357   // general implementation.
00358   const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
00359   if (mpiComm == NULL) {
00360     // Is it a SerialComm?
00361     const SerialComm<int>* serialComm = dynamic_cast<const SerialComm<int>* > (&comm);
00362     if (serialComm == NULL) { 
00363       // We don't know what kind of Comm we have, so fall back to the
00364       // most general implementation.
00365       sendGeneral<T> (comm, count, sendBuffer, destRank);
00366     } 
00367     else { // SerialComm doesn't implement send correctly anyway.
00368       TEUCHOS_TEST_FOR_EXCEPTION(
00369         true,
00370   std::logic_error,
00371   "sendImpl: Not implemented for a serial communicator.");
00372     }
00373   } 
00374   else { // It's an MpiComm.  Invoke MPI directly.
00375     MPI_Comm rawComm = * (mpiComm->getRawMpiComm ());
00376     T t;
00377     MPI_Datatype rawType = MpiTypeTraits<T>::getType (t);
00378     T* rawBuf = const_cast<T*> (sendBuffer);
00379     const int tag = mpiComm->getTag ();
00380     const int err = MPI_Send (rawBuf, count, rawType, destRank, tag, rawComm);
00381     TEUCHOS_TEST_FOR_EXCEPTION(
00382       err != MPI_SUCCESS, 
00383       std::runtime_error,
00384       "MPI_Send failed with the following error: " 
00385       << getMpiErrorString (err));
00386   }
00387 #else 
00388   TEUCHOS_TEST_FOR_EXCEPTION(
00389     true,
00390     std::logic_error,
00391     "sendImpl: Not implemented for a serial communicator.");
00392 #endif // HAVE_MPI
00393 }
00394 
00400 template<class T>
00401 RCP<CommRequest<int> >
00402 isendGeneral (const Comm<int>& comm, 
00403         const int count,
00404         const ArrayRCP<const T>& sendBuffer,
00405         const int destRank)
00406 {
00407   TEUCHOS_COMM_TIME_MONITOR(
00408     "Teuchos::isend<int, " << TypeNameTraits<T>::name () << ">");
00409   ConstValueTypeSerializationBuffer<int, T>
00410     charSendBuffer (sendBuffer.size (), sendBuffer.getRawPtr ());
00411   RCP<CommRequest<int> > commRequest = 
00412     comm.isend (charSendBuffer.getCharBufferView (), destRank);
00413   set_extra_data (sendBuffer, "buffer", inOutArg (commRequest));
00414   return commRequest;
00415 }
00416 
00417 } // namespace (anonymous)
00418 
00419 // mfh 18 Oct 2012: Note on full template specializations
00420 //
00421 // To make Windows builds happy, declarations of full template
00422 // specializations (as found in Teuchos_CommHelpers.hpp) must use the
00423 // TEUCHOSCOMM_LIB_DLL_EXPORT macro.  However, _definitions_ of the
00424 // specializations (as found in this file) must _not_ use the macro.
00425 // That's why we don't use that macro here.
00426 
00427 #ifdef TEUCHOS_HAVE_COMPLEX
00428 // Specialization for Ordinal=int and Packet=std::complex<double>.
00429 template<>
00430 void 
00431 reduceAll<int, std::complex<double> > (const Comm<int>& comm, 
00432                const EReductionType reductType,
00433                const int count, 
00434                const std::complex<double> sendBuffer[], 
00435                std::complex<double> globalReducts[])
00436 {
00437   TEUCHOS_COMM_TIME_MONITOR(
00438     "Teuchos::reduceAll<int, std::complex<double> > (" << count << ", " 
00439     << toString (reductType) << ")"
00440     );
00441   reduceAllImpl<std::complex<double> > (comm, reductType, count, sendBuffer, globalReducts);
00442 }
00443 
00444 template<>
00445 RCP<Teuchos::CommRequest<int> >
00446 ireceive<int, std::complex<double> > (const Comm<int>& comm, 
00447               const ArrayRCP<std::complex<double> >& recvBuffer,
00448               const int sourceRank)
00449 {
00450   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<double> >");
00451   return ireceiveImpl<std::complex<double> > (comm, recvBuffer, sourceRank);
00452 }
00453 
00454 template<>
00455 TEUCHOSCOMM_LIB_DLL_EXPORT void
00456 send<int, std::complex<double> > (const Comm<int>& comm, 
00457           const int count,
00458           const std::complex<double> sendBuffer[],
00459           const int destRank)
00460 {
00461   return sendImpl<std::complex<double> > (comm, count, sendBuffer, destRank);
00462 }
00463 
00464 // Specialization for Ordinal=int and Packet=std::complex<float>.
00465 template<>
00466 void 
00467 reduceAll<int, std::complex<float> > (const Comm<int>& comm, 
00468                const EReductionType reductType,
00469                const int count, 
00470                const std::complex<float> sendBuffer[], 
00471                std::complex<float> globalReducts[])
00472 {
00473   TEUCHOS_COMM_TIME_MONITOR(
00474     "Teuchos::reduceAll<int, std::complex<float> > (" << count << ", " 
00475     << toString (reductType) << ")"
00476     );
00477   reduceAllImpl<std::complex<float> > (comm, reductType, count, sendBuffer, globalReducts);
00478 }
00479 
00480 template<>
00481 RCP<Teuchos::CommRequest<int> >
00482 ireceive<int, std::complex<float> > (const Comm<int>& comm, 
00483              const ArrayRCP<std::complex<float> >& recvBuffer,
00484              const int sourceRank)
00485 {
00486   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, std::complex<float> >");
00487   return ireceiveImpl<std::complex<float> > (comm, recvBuffer, sourceRank);
00488 }
00489 
00490 template<>
00491 TEUCHOSCOMM_LIB_DLL_EXPORT void
00492 send<int, std::complex<float> > (const Comm<int>& comm, 
00493          const int count,
00494          const std::complex<float> sendBuffer[],
00495          const int destRank)
00496 {
00497   return sendImpl<std::complex<float> > (comm, count, sendBuffer, destRank);
00498 }
00499 #endif // TEUCHOS_HAVE_COMPLEX
00500 
00501 
00502 // Specialization for Ordinal=int and Packet=double.
00503 template<>
00504 void 
00505 reduceAll<int, double> (const Comm<int>& comm, 
00506       const EReductionType reductType,
00507       const int count, 
00508       const double sendBuffer[], 
00509       double globalReducts[])
00510 {
00511   TEUCHOS_COMM_TIME_MONITOR(
00512     "Teuchos::reduceAll<int, double> (" << count << ", " 
00513     << toString (reductType) << ")"
00514     );
00515   reduceAllImpl<double> (comm, reductType, count, sendBuffer, globalReducts);
00516 }
00517 
00518 template<>
00519 RCP<Teuchos::CommRequest<int> >
00520 ireceive<int, double> (const Comm<int>& comm, 
00521            const ArrayRCP<double>& recvBuffer,
00522            const int sourceRank)
00523 {
00524   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, double>");
00525   return ireceiveImpl<double> (comm, recvBuffer, sourceRank);
00526 }
00527 
00528 template<>
00529 TEUCHOSCOMM_LIB_DLL_EXPORT void
00530 send<int, double> (const Comm<int>& comm, 
00531        const int count,
00532        const double sendBuffer[],
00533        const int destRank)
00534 {
00535   return sendImpl<double> (comm, count, sendBuffer, destRank);
00536 }
00537 
00538 // Specialization for Ordinal=int and Packet=float.
00539 template<>
00540 void 
00541 reduceAll<int, float> (const Comm<int>& comm, 
00542            const EReductionType reductType,
00543            const int count, 
00544            const float sendBuffer[], 
00545            float globalReducts[])
00546 {
00547   TEUCHOS_COMM_TIME_MONITOR(
00548     "Teuchos::reduceAll<int, float> (" << count << ", " 
00549     << toString (reductType) << ")"
00550     );
00551   reduceAllImpl<float> (comm, reductType, count, sendBuffer, globalReducts);
00552 }
00553 
00554 template<>
00555 RCP<Teuchos::CommRequest<int> >
00556 ireceive<int, float> (const Comm<int>& comm, 
00557           const ArrayRCP<float>& recvBuffer,
00558           const int sourceRank)
00559 {
00560   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, float>");
00561   return ireceiveImpl<float> (comm, recvBuffer, sourceRank);
00562 }
00563 
00564 template<>
00565 TEUCHOSCOMM_LIB_DLL_EXPORT void
00566 send<int, float> (const Comm<int>& comm, 
00567       const int count,
00568       const float sendBuffer[],
00569       const int destRank)
00570 {
00571   return sendImpl<float> (comm, count, sendBuffer, destRank);
00572 }
00573 
00574 #ifdef TEUCHOS_HAVE_LONG_LONG_INT
00575 // Specialization for Ordinal=int and Packet=long long.
00576 template<>
00577 void 
00578 reduceAll<int, long long> (const Comm<int>& comm, 
00579          const EReductionType reductType,
00580          const int count, 
00581          const long long sendBuffer[], 
00582          long long globalReducts[])
00583 {
00584   TEUCHOS_COMM_TIME_MONITOR(
00585     "Teuchos::reduceAll<int, long long> (" << count << ", " 
00586     << toString (reductType) << ")"
00587     );
00588   reduceAllImpl<long long> (comm, reductType, count, sendBuffer, globalReducts);
00589 }
00590 
00591 template<>
00592 RCP<Teuchos::CommRequest<int> >
00593 ireceive<int, long long> (const Comm<int>& comm, 
00594         const ArrayRCP<long long>& recvBuffer,
00595         const int sourceRank)
00596 {
00597   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long long>");
00598   return ireceiveImpl<long long> (comm, recvBuffer, sourceRank);
00599 }
00600 
00601 template<>
00602 TEUCHOSCOMM_LIB_DLL_EXPORT void
00603 send<int, long long> (const Comm<int>& comm, 
00604           const int count,
00605           const long long sendBuffer[],
00606           const int destRank)
00607 {
00608   return sendImpl<long long> (comm, count, sendBuffer, destRank);
00609 }
00610 #endif // TEUCHOS_HAVE_LONG_LONG_INT
00611 
00612 
00613 // Specialization for Ordinal=int and Packet=long.
00614 template<>
00615 void 
00616 reduceAll<int, long> (const Comm<int>& comm, 
00617           const EReductionType reductType,
00618           const int count, 
00619           const long sendBuffer[], 
00620           long globalReducts[])
00621 {
00622   TEUCHOS_COMM_TIME_MONITOR(
00623     "Teuchos::reduceAll<int, long> (" << count << ", " 
00624     << toString (reductType) << ")"
00625     );
00626   reduceAllImpl<long> (comm, reductType, count, sendBuffer, globalReducts);
00627 }
00628 
00629 template<>
00630 RCP<Teuchos::CommRequest<int> >
00631 ireceive<int, long> (const Comm<int>& comm, 
00632          const ArrayRCP<long>& recvBuffer,
00633          const int sourceRank)
00634 {
00635   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, long>");
00636   return ireceiveImpl<long> (comm, recvBuffer, sourceRank);
00637 }
00638 
00639 template<>
00640 TEUCHOSCOMM_LIB_DLL_EXPORT void
00641 send<int, long> (const Comm<int>& comm, 
00642      const int count,
00643      const long sendBuffer[],
00644      const int destRank)
00645 {
00646   return sendImpl<long> (comm, count, sendBuffer, destRank);
00647 }
00648 
00649 // Specialization for Ordinal=int and Packet=int.
00650 template<>
00651 void 
00652 reduceAll<int, int> (const Comm<int>& comm, 
00653          const EReductionType reductType,
00654          const int count, 
00655          const int sendBuffer[], 
00656          int globalReducts[])
00657 {
00658   TEUCHOS_COMM_TIME_MONITOR(
00659     "Teuchos::reduceAll<int, int> (" << count << ", " 
00660     << toString (reductType) << ")"
00661     );
00662   reduceAllImpl<int> (comm, reductType, count, sendBuffer, globalReducts);
00663 }
00664 
00665 template<>
00666 RCP<Teuchos::CommRequest<int> >
00667 ireceive<int, int> (const Comm<int>& comm, 
00668         const ArrayRCP<int>& recvBuffer,
00669         const int sourceRank)
00670 {
00671   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, int>");
00672   return ireceiveImpl<int> (comm, recvBuffer, sourceRank);
00673 }
00674 
00675 template<>
00676 TEUCHOSCOMM_LIB_DLL_EXPORT void
00677 send<int, int> (const Comm<int>& comm, 
00678     const int count,
00679     const int sendBuffer[],
00680     const int destRank)
00681 {
00682   return sendImpl<int> (comm, count, sendBuffer, destRank);
00683 }
00684 
00685 // Specialization for Ordinal=int and Packet=short.
00686 template<>
00687 void 
00688 reduceAll<int, short> (const Comm<int>& comm, 
00689            const EReductionType reductType,
00690            const int count, 
00691            const short sendBuffer[], 
00692            short globalReducts[])
00693 {
00694   TEUCHOS_COMM_TIME_MONITOR(
00695     "Teuchos::reduceAll<int, short> (" << count << ", " 
00696     << toString (reductType) << ")"
00697     );
00698   reduceAllImpl<short> (comm, reductType, count, sendBuffer, globalReducts);
00699 }
00700 
00701 template<>
00702 RCP<Teuchos::CommRequest<int> >
00703 ireceive<int, short> (const Comm<int>& comm, 
00704           const ArrayRCP<short>& recvBuffer,
00705           const int sourceRank)
00706 {
00707   TEUCHOS_COMM_TIME_MONITOR("ireceive<int, short>");
00708   return ireceiveImpl<short> (comm, recvBuffer, sourceRank);
00709 }
00710 
00711 template<>
00712 TEUCHOSCOMM_LIB_DLL_EXPORT void
00713 send<int, short> (const Comm<int>& comm, 
00714       const int count,
00715       const short sendBuffer[],
00716       const int destRank)
00717 {
00718   return sendImpl<short> (comm, count, sendBuffer, destRank);
00719 }
00720 
00721 // mfh 18 Oct 2012: The specialization for Packet=char seems to be
00722 // causing problems such as the following:
00723 //
00724 // http://testing.sandia.gov/cdash/testDetails.php?test=9909246&build=747699
00725 // 
00726 // I am disabling it for now.  This should revert back to the old
00727 // behavior for Packet=char.  That should fix the Tpetra errors, since
00728 // many Tpetra objects inherit from DistObject<char, ...>.
00729 #if 0
00730 // Specialization for Ordinal=int and Packet=char.
00731 template<>
00732 void 
00733 reduceAll<int, char> (const Comm<int>& comm, 
00734           const EReductionType reductType,
00735           const int count, 
00736           const char sendBuffer[], 
00737           char globalReducts[])
00738 {
00739   TEUCHOS_COMM_TIME_MONITOR(
00740     "Teuchos::reduceAll<int, char> (" << count << ", " 
00741     << toString (reductType) << ")"
00742     );
00743   reduceAllImpl<char> (comm, reductType, count, sendBuffer, globalReducts);
00744 }
00745 #endif // 0
00746 
00747 } // namespace Teuchos
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines