Teuchos - Trilinos Tools Package Version of the Day
Teuchos_DefaultSerialComm.hpp
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 };
00066 
00067 
00072 template<typename Ordinal>
00073 class SerialComm : public Comm<Ordinal> {
00074 public:
00075 
00077 
00078 
00080   SerialComm();
00081 
00083   SerialComm(const SerialComm<Ordinal>& other);
00084 
00086 
00088 
00089 
00091   virtual int getRank() const;
00093   virtual int getSize() const;
00095   virtual void barrier() const;
00097   virtual void broadcast(
00098     const int rootRank, const Ordinal bytes, char buffer[]
00099     ) const;
00101   virtual void gatherAll(
00102     const Ordinal sendBytes, const char sendBuffer[]
00103     ,const Ordinal recvBytes, char recvBuffer[]
00104     ) const;
00106   virtual void reduceAll(
00107     const ValueTypeReductionOp<Ordinal,char> &reductOp
00108     ,const Ordinal bytes, const char sendBuffer[], char globalReducts[]
00109     ) const;
00111   virtual void reduceAllAndScatter(
00112     const ValueTypeReductionOp<Ordinal,char> &reductOp
00113     ,const Ordinal sendBytes, const char sendBuffer[]
00114     ,const Ordinal recvCounts[], char myGlobalReducts[]
00115     ) const;
00117   virtual void scan(
00118     const ValueTypeReductionOp<Ordinal,char> &reductOp
00119     ,const Ordinal bytes, const char sendBuffer[], char scanReducts[]
00120     ) const;
00122   virtual void send(
00123     const Ordinal bytes, const char sendBuffer[], const int destRank
00124     ) const;
00126   virtual void ssend(
00127     const Ordinal bytes, const char sendBuffer[], const int destRank
00128     ) const;
00130   virtual int receive(
00131     const int sourceRank, const Ordinal bytes, char recvBuffer[]
00132     ) const;
00134   virtual void readySend(
00135     const ArrayView<const char> &sendBuffer,
00136     const int destRank
00137     ) const;
00139   virtual RCP<CommRequest> isend(
00140     const ArrayView<const char> &sendBuffer,
00141     const int destRank
00142     ) const;
00144   virtual RCP<CommRequest> ireceive(
00145     const ArrayView<char> &Buffer,
00146     const int sourceRank
00147     ) const;
00149   virtual void waitAll(
00150     const ArrayView<RCP<CommRequest> > &requests
00151     ) const;
00153   virtual void 
00154   waitAll (const ArrayView<RCP<CommRequest> >& requests,
00155      const ArrayView<RCP<CommStatus<Ordinal> > >& statuses) const;
00157   virtual RCP<CommStatus<Ordinal> > 
00158   wait (const Ptr<RCP<CommRequest> >& request) const;
00160   virtual RCP< Comm<Ordinal> > duplicate() const;
00162   virtual RCP< Comm<Ordinal> > split(const int color, const int key) const;
00164   virtual RCP< Comm<Ordinal> > createSubcommunicator(
00165     const ArrayView<const int> & ranks) const;
00166 
00168 
00170 
00171 
00173   std::string description() const;
00174 
00176   
00177 };
00178 
00179 
00184 template<typename Ordinal>
00185 RCP<SerialComm<Ordinal> > createSerialComm()
00186 {
00187   return Teuchos::rcp(new SerialComm<Ordinal>);
00188 }
00189 
00190 
00191 // ////////////////////////
00192 // Implementations
00193 
00194 
00195 // Constructors
00196 
00197 
00198 template<typename Ordinal>
00199 SerialComm<Ordinal>::SerialComm()
00200 {}
00201 
00202 template<typename Ordinal>
00203 SerialComm<Ordinal>::SerialComm(const SerialComm<Ordinal>& other)
00204 {}
00205 
00206 
00207 // Overridden from Comm
00208 
00209   
00210 template<typename Ordinal>
00211 int SerialComm<Ordinal>::getRank() const
00212 {
00213   return 0;
00214 }
00215 
00216   
00217 template<typename Ordinal>
00218 int SerialComm<Ordinal>::getSize() const
00219 {
00220   return 1;
00221 }
00222 
00223   
00224 template<typename Ordinal>
00225 void SerialComm<Ordinal>::barrier() const
00226 {
00227   // Nothing to do
00228 }
00229 
00230   
00231 template<typename Ordinal>
00232 void SerialComm<Ordinal>::broadcast(
00233   const int /*rootRank*/, const Ordinal /*bytes*/, char []/*buffer*/
00234   ) const
00235 {
00236   // Nothing to do
00237 }
00238 
00239   
00240 template<typename Ordinal>
00241 void SerialComm<Ordinal>::gatherAll(
00242   const Ordinal sendBytes, const char sendBuffer[]
00243   ,const Ordinal recvBytes, char recvBuffer[]
00244   ) const
00245 {
00246   (void)sendBytes;  // to remove "unused parameter" warning
00247   (void)recvBytes;
00248   (void)sendBuffer;
00249   (void)recvBuffer;
00250 #ifdef TEUCHOS_DEBUG
00251   TEUCHOS_TEST_FOR_EXCEPT(!(sendBytes==recvBytes));
00252 #endif
00253   std::copy(sendBuffer,sendBuffer+sendBytes,recvBuffer);
00254 }
00255 
00256   
00257 template<typename Ordinal>
00258 void SerialComm<Ordinal>::reduceAll(
00259   const ValueTypeReductionOp<Ordinal,char> &reductOp
00260   ,const Ordinal bytes, const char sendBuffer[], char globalReducts[]
00261   ) const
00262 {
00263   (void)reductOp;
00264   std::copy(sendBuffer,sendBuffer+bytes,globalReducts);
00265 }
00266 
00267   
00268 template<typename Ordinal>
00269 void SerialComm<Ordinal>::reduceAllAndScatter(
00270   const ValueTypeReductionOp<Ordinal,char> &reductOp
00271   ,const Ordinal sendBytes, const char sendBuffer[]
00272   ,const Ordinal recvCounts[], char myGlobalReducts[]
00273   ) const
00274 {
00275   // Ignore unused arguments
00276   (void)reductOp;
00277   (void)sendBytes;
00278   (void)sendBuffer;
00279   (void)recvCounts;
00280   (void)myGlobalReducts;
00281 
00282 #ifdef TEUCHOS_DEBUG
00283   TEUCHOS_TEST_FOR_EXCEPT( recvCounts==NULL || recvCounts[0] != sendBytes ); 
00284 #endif
00285   std::copy(sendBuffer,sendBuffer+sendBytes,myGlobalReducts);
00286 }
00287 
00288   
00289 template<typename Ordinal>
00290 void SerialComm<Ordinal>::scan(
00291   const ValueTypeReductionOp<Ordinal,char> &reductOp
00292   ,const Ordinal bytes, const char sendBuffer[], char scanReducts[]
00293   ) const
00294 {
00295   (void)reductOp;
00296   std::copy(sendBuffer,sendBuffer+bytes,scanReducts);
00297 }
00298 
00299   
00300 template<typename Ordinal>
00301 void SerialComm<Ordinal>::send(
00302   const Ordinal /*bytes*/, const char []/*sendBuffer*/, const int /*destRank*/
00303   ) const
00304 {
00305   TEUCHOS_TEST_FOR_EXCEPTION(
00306     true, std::logic_error
00307     ,"SerialComm<Ordinal>::send(...): Error, you can not call send(...) when you"
00308     " only have one process!"
00309     );
00310 }
00311 
00312 
00313 template<typename Ordinal>
00314 void SerialComm<Ordinal>::ssend(
00315   const Ordinal /*bytes*/, const char []/*sendBuffer*/, const int /*destRank*/
00316   ) const
00317 {
00318   TEUCHOS_TEST_FOR_EXCEPTION(
00319     true, std::logic_error
00320     ,"SerialComm<Ordinal>::send(...): Error, you can not call send(...) when you"
00321     " only have one process!"
00322     );
00323 }
00324 
00325   
00326 template<typename Ordinal>
00327 int SerialComm<Ordinal>::receive(
00328   const int /*sourceRank*/, const Ordinal /*bytes*/, char []/*recvBuffer*/
00329   ) const
00330 {
00331   TEUCHOS_TEST_FOR_EXCEPTION(
00332     true, std::logic_error
00333     ,"SerialComm<Ordinal>::receive(...): Error, you can not call receive(...) when you"
00334     " only have one process!"
00335     );
00336   // The next line will never be reached, but a return is required on some platforms
00337   return 0; 
00338 }
00339 
00340 
00341 template<typename Ordinal>
00342 void SerialComm<Ordinal>::readySend(
00343   const ArrayView<const char> &/*sendBuffer*/,
00344   const int /*destRank*/
00345   ) const
00346 {
00347   TEUCHOS_TEST_FOR_EXCEPTION(
00348     true, std::logic_error
00349     ,"SerialComm<Ordinal>::readySend(...): Error, you can not call readySend(...) when you"
00350     " only have one process!"
00351     );
00352 }
00353 
00354 
00355 template<typename Ordinal>
00356 RCP<CommRequest> SerialComm<Ordinal>::isend(
00357   const ArrayView<const char> &/*sendBuffer*/,
00358   const int /*destRank*/
00359   ) const
00360 {
00361   TEUCHOS_TEST_FOR_EXCEPT(true);
00362   return null;
00363 }
00364 
00365 
00366 template<typename Ordinal>
00367 RCP<CommRequest> SerialComm<Ordinal>::ireceive(
00368   const ArrayView<char> &/*Buffer*/,
00369   const int /*sourceRank*/
00370   ) const
00371 {
00372   TEUCHOS_TEST_FOR_EXCEPT(true);
00373   return null;
00374 }
00375 
00376 
00377 template<typename Ordinal>
00378 void SerialComm<Ordinal>::waitAll (const ArrayView<RCP<CommRequest> >& requests) const
00379 {
00380   (void) requests;
00381   // There's nothing to wait on!
00382 }
00383 
00384 
00385 template<typename Ordinal>
00386 void 
00387 SerialComm<Ordinal>::
00388 waitAll (const ArrayView<RCP<CommRequest> >& requests,
00389    const ArrayView<RCP<CommStatus<Ordinal> > >& statuses) const
00390 {
00391   TEUCHOS_TEST_FOR_EXCEPTION(statuses.size() < requests.size(), 
00392     std::invalid_argument, "Teuchos::SerialComm::waitAll: There are not enough "
00393     "entries in the statuses array to hold all the results of the communication"
00394     " requests.  requests.size() = " << requests.size() << " > statuses.size() "
00395     "= " << statuses.size() << ".");
00396 
00397   for (ArrayView<RCP<CommRequest> >::iterator it = requests.begin(); 
00398        it != requests.end(); ++it) {
00399     *it = null; // A postcondition of the Teuchos::Comm interface.
00400   }
00401 }
00402 
00403 template<typename Ordinal>
00404 RCP<CommStatus<Ordinal> > 
00405 SerialComm<Ordinal>::wait (const Ptr<RCP<CommRequest> > & request) const
00406 {
00407   (void) request;
00408   TEUCHOS_TEST_FOR_EXCEPTION(request.getRawPtr() == NULL, std::invalid_argument,
00409     "Teuchos::SerialComm::wait: On input, the request pointer is null.");
00410 
00411   if (is_null (*request)) {
00412     return null; // Nothing to wait on...
00413   }
00414   *request = null;
00415   return rcp (new SerialCommStatus<Ordinal>);
00416 }
00417 
00418 template< typename Ordinal>
00419 RCP< Comm<Ordinal> >
00420 SerialComm<Ordinal>::duplicate() const
00421 {
00422   return rcp(new SerialComm<Ordinal>(*this));
00423 }
00424 
00425 template<typename Ordinal>
00426 RCP< Comm<Ordinal> >
00427 SerialComm<Ordinal>::split(const int color, const int /*key*/) const
00428 {
00429   if (color < 0) {
00430     return RCP< Comm<Ordinal> >();
00431   }
00432   // Simply return a copy of this communicator.
00433   return rcp(new SerialComm<Ordinal>(*this));
00434 }
00435 
00436 template<typename Ordinal>
00437 RCP< Comm<Ordinal> >
00438 SerialComm<Ordinal>::createSubcommunicator(const ArrayView<const int> &ranks) const
00439 {
00440   if ((ranks.size()) == 1 && (ranks[0] == 0)) {
00441     return rcp(new SerialComm<Ordinal>(*this));
00442   } else {
00443     return RCP< Comm<Ordinal> >();
00444   }
00445 }
00446 
00447 // Overridden from Describable
00448 
00449 
00450 template<typename Ordinal>
00451 std::string SerialComm<Ordinal>::description() const
00452 {
00453   std::ostringstream oss;
00454   oss << "Teuchos::SerialComm<"<<OrdinalTraits<Ordinal>::name()<<">";
00455   return oss.str();
00456 }
00457 
00458 
00459 } // namespace Teuchos
00460 
00461 
00462 #endif // TEUCHOS_SERIAL_COMM_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines