|
Teuchos Package Browser (Single Doxygen Collection)
Version of the Day
|
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
1.7.6.1