|
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 #ifndef TEUCHOS_SERIAL_COMM_HPP 00043 #define TEUCHOS_SERIAL_COMM_HPP 00044 00045 #include "Teuchos_Comm.hpp" 00046 #include "Teuchos_OrdinalTraits.hpp" 00047 00048 00049 namespace Teuchos { 00050 00057 template<class OrdinalType> 00058 class SerialCommStatus : public CommStatus<OrdinalType> { 00059 public: 00061 SerialCommStatus () {} 00062 00064 OrdinalType getSourceRank () { return 0; } 00065 00067 OrdinalType getTag () { return 0; } 00068 }; 00069 00070 00075 template<typename Ordinal> 00076 class SerialComm : public Comm<Ordinal> { 00077 public: 00083 int getTag () const { return 0; } 00084 00086 00087 00089 SerialComm(); 00090 00092 SerialComm(const SerialComm<Ordinal>& other); 00093 00095 00097 00098 00100 virtual int getRank() const; 00102 virtual int getSize() const; 00104 virtual void barrier() const; 00106 virtual void broadcast( 00107 const int rootRank, const Ordinal bytes, char buffer[] 00108 ) const; 00110 virtual void 00111 gather (const Ordinal sendBytes, const char sendBuffer[], 00112 const Ordinal recvBytes, char recvBuffer[], 00113 const int root) const; 00115 virtual void gatherAll( 00116 const Ordinal sendBytes, const char sendBuffer[] 00117 ,const Ordinal recvBytes, char recvBuffer[] 00118 ) const; 00120 virtual void reduceAll( 00121 const ValueTypeReductionOp<Ordinal,char> &reductOp 00122 ,const Ordinal bytes, const char sendBuffer[], char globalReducts[] 00123 ) const; 00125 virtual void reduceAllAndScatter( 00126 const ValueTypeReductionOp<Ordinal,char> &reductOp 00127 ,const Ordinal sendBytes, const char sendBuffer[] 00128 ,const Ordinal recvCounts[], char myGlobalReducts[] 00129 ) const; 00131 virtual void scan( 00132 const ValueTypeReductionOp<Ordinal,char> &reductOp 00133 ,const Ordinal bytes, const char sendBuffer[], char scanReducts[] 00134 ) const; 00136 virtual void send( 00137 const Ordinal bytes, const char sendBuffer[], const int destRank 00138 ) const; 00140 virtual void 00141 send (const Ordinal bytes, 00142 const char sendBuffer[], 00143 const int destRank, 00144 const int tag) const; 00146 virtual void ssend( 00147 const Ordinal bytes, const char sendBuffer[], const int destRank 00148 ) const; 00150 virtual void 00151 ssend (const Ordinal bytes, 00152 const char sendBuffer[], 00153 const int destRank, 00154 const int tag) const; 00156 virtual int receive( 00157 const int sourceRank, const Ordinal bytes, char recvBuffer[] 00158 ) const; 00160 virtual void readySend( 00161 const ArrayView<const char> &sendBuffer, 00162 const int destRank 00163 ) const; 00165 virtual void 00166 readySend (const Ordinal bytes, 00167 const char sendBuffer[], 00168 const int destRank, 00169 const int tag) const; 00171 virtual RCP<CommRequest<Ordinal> > isend( 00172 const ArrayView<const char> &sendBuffer, 00173 const int destRank 00174 ) const; 00176 virtual RCP<CommRequest<Ordinal> > 00177 isend (const ArrayView<const char> &sendBuffer, 00178 const int destRank, 00179 const int tag) const; 00181 virtual RCP<CommRequest<Ordinal> > ireceive( 00182 const ArrayView<char> &Buffer, 00183 const int sourceRank 00184 ) const; 00186 virtual RCP<CommRequest<Ordinal> > 00187 ireceive (const ArrayView<char> &Buffer, 00188 const int sourceRank, 00189 const int tag) const; 00191 virtual void waitAll( 00192 const ArrayView<RCP<CommRequest<Ordinal> > > &requests 00193 ) const; 00195 virtual void 00196 waitAll (const ArrayView<RCP<CommRequest<Ordinal> > >& requests, 00197 const ArrayView<RCP<CommStatus<Ordinal> > >& statuses) const; 00199 virtual RCP<CommStatus<Ordinal> > 00200 wait (const Ptr<RCP<CommRequest<Ordinal> > >& request) const; 00202 virtual RCP< Comm<Ordinal> > duplicate() const; 00204 virtual RCP< Comm<Ordinal> > split(const int color, const int key) const; 00206 virtual RCP< Comm<Ordinal> > createSubcommunicator( 00207 const ArrayView<const int> & ranks) const; 00208 00210 00212 00213 00215 std::string description() const; 00216 00218 00219 }; 00220 00221 00226 template<typename Ordinal> 00227 RCP<SerialComm<Ordinal> > createSerialComm() 00228 { 00229 return Teuchos::rcp(new SerialComm<Ordinal>); 00230 } 00231 00232 00233 // //////////////////////// 00234 // Implementations 00235 00236 00237 // Constructors 00238 00239 00240 template<typename Ordinal> 00241 SerialComm<Ordinal>::SerialComm() 00242 {} 00243 00244 template<typename Ordinal> 00245 SerialComm<Ordinal>::SerialComm(const SerialComm<Ordinal>& other) 00246 {} 00247 00248 00249 // Overridden from Comm 00250 00251 00252 template<typename Ordinal> 00253 int SerialComm<Ordinal>::getRank() const 00254 { 00255 return 0; 00256 } 00257 00258 00259 template<typename Ordinal> 00260 int SerialComm<Ordinal>::getSize() const 00261 { 00262 return 1; 00263 } 00264 00265 00266 template<typename Ordinal> 00267 void SerialComm<Ordinal>::barrier() const 00268 { 00269 // Nothing to do 00270 } 00271 00272 00273 template<typename Ordinal> 00274 void SerialComm<Ordinal>::broadcast( 00275 const int /*rootRank*/, const Ordinal /*bytes*/, char []/*buffer*/ 00276 ) const 00277 { 00278 // Nothing to do 00279 } 00280 00281 00282 template<typename Ordinal> 00283 void SerialComm<Ordinal>::gatherAll( 00284 const Ordinal sendBytes, const char sendBuffer[] 00285 ,const Ordinal recvBytes, char recvBuffer[] 00286 ) const 00287 { 00288 (void)sendBytes; // to remove "unused parameter" warning 00289 (void)recvBytes; 00290 (void)sendBuffer; 00291 (void)recvBuffer; 00292 #ifdef TEUCHOS_DEBUG 00293 TEUCHOS_TEST_FOR_EXCEPT(!(sendBytes==recvBytes)); 00294 #endif 00295 std::copy(sendBuffer,sendBuffer+sendBytes,recvBuffer); 00296 } 00297 00298 00299 template<typename Ordinal> 00300 void 00301 SerialComm<Ordinal>::gather (const Ordinal sendBytes, 00302 const char sendBuffer[], 00303 const Ordinal recvBytes, 00304 char recvBuffer[], 00305 const int root) const 00306 { 00307 (void) sendBytes; // to remove "unused parameter" warning 00308 (void) recvBytes; 00309 (void) sendBuffer; 00310 (void) recvBuffer; 00311 (void) root; 00312 #ifdef TEUCHOS_DEBUG 00313 TEUCHOS_TEST_FOR_EXCEPT(!(sendBytes==recvBytes)); 00314 #endif 00315 std::copy (sendBuffer, sendBuffer + sendBytes, recvBuffer); 00316 } 00317 00318 00319 template<typename Ordinal> 00320 void SerialComm<Ordinal>::reduceAll( 00321 const ValueTypeReductionOp<Ordinal,char> &reductOp 00322 ,const Ordinal bytes, const char sendBuffer[], char globalReducts[] 00323 ) const 00324 { 00325 (void)reductOp; 00326 std::copy(sendBuffer,sendBuffer+bytes,globalReducts); 00327 } 00328 00329 00330 template<typename Ordinal> 00331 void SerialComm<Ordinal>::reduceAllAndScatter( 00332 const ValueTypeReductionOp<Ordinal,char> &reductOp 00333 ,const Ordinal sendBytes, const char sendBuffer[] 00334 ,const Ordinal recvCounts[], char myGlobalReducts[] 00335 ) const 00336 { 00337 // Ignore unused arguments 00338 (void)reductOp; 00339 (void)sendBytes; 00340 (void)sendBuffer; 00341 (void)recvCounts; 00342 (void)myGlobalReducts; 00343 00344 #ifdef TEUCHOS_DEBUG 00345 TEUCHOS_TEST_FOR_EXCEPT( recvCounts==NULL || recvCounts[0] != sendBytes ); 00346 #endif 00347 std::copy(sendBuffer,sendBuffer+sendBytes,myGlobalReducts); 00348 } 00349 00350 00351 template<typename Ordinal> 00352 void SerialComm<Ordinal>::scan( 00353 const ValueTypeReductionOp<Ordinal,char> &reductOp 00354 ,const Ordinal bytes, const char sendBuffer[], char scanReducts[] 00355 ) const 00356 { 00357 (void)reductOp; 00358 std::copy(sendBuffer,sendBuffer+bytes,scanReducts); 00359 } 00360 00361 00362 template<typename Ordinal> 00363 void SerialComm<Ordinal>::send( 00364 const Ordinal /*bytes*/, const char []/*sendBuffer*/, const int /*destRank*/ 00365 ) const 00366 { 00367 TEUCHOS_TEST_FOR_EXCEPTION( 00368 true, std::logic_error 00369 ,"SerialComm<Ordinal>::send(...): Error, you can not call send(...) when you" 00370 " only have one process!" 00371 ); 00372 } 00373 00374 template<typename Ordinal> 00375 void SerialComm<Ordinal>:: 00376 send (const Ordinal /*bytes*/, 00377 const char []/*sendBuffer*/, 00378 const int /*destRank*/, 00379 const int /*tag*/) const 00380 { 00381 TEUCHOS_TEST_FOR_EXCEPTION( 00382 true, std::logic_error 00383 ,"SerialComm<Ordinal>::send(...): Error, you can not call send(...) when you" 00384 " only have one process!" 00385 ); 00386 } 00387 00388 template<typename Ordinal> 00389 void SerialComm<Ordinal>::ssend( 00390 const Ordinal /*bytes*/, const char []/*sendBuffer*/, const int /*destRank*/ 00391 ) const 00392 { 00393 TEUCHOS_TEST_FOR_EXCEPTION( 00394 true, std::logic_error 00395 ,"SerialComm<Ordinal>::send(...): Error, you can not call ssend(...) when you" 00396 " only have one process!" 00397 ); 00398 } 00399 00400 template<typename Ordinal> 00401 void 00402 SerialComm<Ordinal>::ssend (const Ordinal bytes, 00403 const char sendBuffer[], 00404 const int destRank, 00405 const int tag) const 00406 { 00407 TEUCHOS_TEST_FOR_EXCEPTION( 00408 true, std::logic_error 00409 ,"SerialComm<Ordinal>::send(...): Error, you can not call ssend(...) when you" 00410 " only have one process!" 00411 ); 00412 } 00413 00414 template<typename Ordinal> 00415 int SerialComm<Ordinal>::receive( 00416 const int /*sourceRank*/, const Ordinal /*bytes*/, char []/*recvBuffer*/ 00417 ) const 00418 { 00419 TEUCHOS_TEST_FOR_EXCEPTION( 00420 true, std::logic_error 00421 ,"SerialComm<Ordinal>::receive(...): Error, you can not call receive(...) when you" 00422 " only have one process!" 00423 ); 00424 } 00425 00426 00427 template<typename Ordinal> 00428 void SerialComm<Ordinal>::readySend( 00429 const ArrayView<const char> &/*sendBuffer*/, 00430 const int /*destRank*/ 00431 ) const 00432 { 00433 TEUCHOS_TEST_FOR_EXCEPTION( 00434 true, std::logic_error 00435 ,"SerialComm<Ordinal>::readySend(...): Error, you can not call readySend(...) when you" 00436 " only have one process!" 00437 ); 00438 } 00439 00440 template<typename Ordinal> 00441 void 00442 SerialComm<Ordinal>::readySend (const Ordinal bytes, 00443 const char sendBuffer[], 00444 const int destRank, 00445 const int tag) const 00446 { 00447 (void) bytes; 00448 (void) sendBuffer; 00449 (void) destRank; 00450 (void) tag; 00451 00452 TEUCHOS_TEST_FOR_EXCEPTION( 00453 true, std::logic_error 00454 ,"SerialComm<Ordinal>::readySend(...): Error, you can not call readySend(...) when you" 00455 " only have one process!" 00456 ); 00457 } 00458 00459 template<typename Ordinal> 00460 RCP<CommRequest<Ordinal> > SerialComm<Ordinal>::isend( 00461 const ArrayView<const char> &/*sendBuffer*/, 00462 const int /*destRank*/ 00463 ) const 00464 { 00465 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "SerialComm<Ordinal>::isend: You cannot call isend when you only have one process." ); 00466 } 00467 00468 00469 template<typename Ordinal> 00470 RCP<CommRequest<Ordinal> > 00471 SerialComm<Ordinal>:: 00472 isend (const ArrayView<const char> &/*sendBuffer*/, 00473 const int /*destRank*/, 00474 const int /*tag*/) const 00475 { 00476 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "SerialComm<Ordinal>::isend: You cannot call isend when you only have one process." ); 00477 } 00478 00479 00480 template<typename Ordinal> 00481 RCP<CommRequest<Ordinal> > SerialComm<Ordinal>::ireceive( 00482 const ArrayView<char> &/*Buffer*/, 00483 const int /*sourceRank*/ 00484 ) const 00485 { 00486 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "SerialComm<Ordinal>::ireceive: You cannot call isend when you only have one process." ); 00487 } 00488 00489 00490 template<typename Ordinal> 00491 RCP<CommRequest<Ordinal> > 00492 SerialComm<Ordinal>:: 00493 ireceive (const ArrayView<char> &/*Buffer*/, 00494 const int /*sourceRank*/, 00495 const int /*tag*/) const 00496 { 00497 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "SerialComm<Ordinal>::ireceive: You cannot call isend when you only have one process." ); 00498 } 00499 00500 00501 template<typename Ordinal> 00502 void SerialComm<Ordinal>::waitAll (const ArrayView<RCP<CommRequest<Ordinal> > >& requests) const 00503 { 00504 (void) requests; 00505 // There's nothing to wait on! 00506 } 00507 00508 00509 template<typename Ordinal> 00510 void 00511 SerialComm<Ordinal>:: 00512 waitAll (const ArrayView<RCP<CommRequest<Ordinal> > >& requests, 00513 const ArrayView<RCP<CommStatus<Ordinal> > >& statuses) const 00514 { 00515 TEUCHOS_TEST_FOR_EXCEPTION(statuses.size() < requests.size(), 00516 std::invalid_argument, "Teuchos::SerialComm::waitAll: There are not enough " 00517 "entries in the statuses array to hold all the results of the communication" 00518 " requests. requests.size() = " << requests.size() << " > statuses.size() " 00519 "= " << statuses.size() << "."); 00520 00521 for (typename ArrayView<RCP<CommRequest<Ordinal> > >::iterator it = requests.begin(); 00522 it != requests.end(); ++it) { 00523 *it = null; // A postcondition of the Teuchos::Comm interface. 00524 } 00525 } 00526 00527 template<typename Ordinal> 00528 RCP<CommStatus<Ordinal> > 00529 SerialComm<Ordinal>::wait (const Ptr<RCP<CommRequest<Ordinal> > > & request) const 00530 { 00531 (void) request; 00532 TEUCHOS_TEST_FOR_EXCEPTION(request.getRawPtr() == NULL, std::invalid_argument, 00533 "Teuchos::SerialComm::wait: On input, the request pointer is null."); 00534 00535 if (is_null (*request)) { 00536 return null; // Nothing to wait on... 00537 } 00538 *request = null; 00539 return rcp (new SerialCommStatus<Ordinal>); 00540 } 00541 00542 template< typename Ordinal> 00543 RCP< Comm<Ordinal> > 00544 SerialComm<Ordinal>::duplicate() const 00545 { 00546 return rcp(new SerialComm<Ordinal>(*this)); 00547 } 00548 00549 template<typename Ordinal> 00550 RCP< Comm<Ordinal> > 00551 SerialComm<Ordinal>::split(const int color, const int /*key*/) const 00552 { 00553 if (color < 0) { 00554 return RCP< Comm<Ordinal> >(); 00555 } 00556 // Simply return a copy of this communicator. 00557 return rcp(new SerialComm<Ordinal>(*this)); 00558 } 00559 00560 template<typename Ordinal> 00561 RCP< Comm<Ordinal> > 00562 SerialComm<Ordinal>::createSubcommunicator(const ArrayView<const int> &ranks) const 00563 { 00564 if ((ranks.size()) == 1 && (ranks[0] == 0)) { 00565 return rcp(new SerialComm<Ordinal>(*this)); 00566 } else { 00567 return RCP< Comm<Ordinal> >(); 00568 } 00569 } 00570 00571 // Overridden from Describable 00572 00573 00574 template<typename Ordinal> 00575 std::string SerialComm<Ordinal>::description() const 00576 { 00577 std::ostringstream oss; 00578 oss << "Teuchos::SerialComm<"<<OrdinalTraits<Ordinal>::name()<<">"; 00579 return oss.str(); 00580 } 00581 00582 00583 } // namespace Teuchos 00584 00585 00586 #endif // TEUCHOS_SERIAL_COMM_HPP
1.7.6.1