Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Teuchos_DefaultSerialComm.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines