|
Anasazi Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Anasazi: Block Eigensolvers Package 00005 // Copyright (2010) 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 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 // @HEADER 00028 00029 #ifndef __TSQR_Trilinos_TeuchosMessenger_hpp 00030 #define __TSQR_Trilinos_TeuchosMessenger_hpp 00031 00032 #include "Teuchos_CommHelpers.hpp" 00033 #include "Tsqr_MessengerBase.hpp" 00034 #include <algorithm> 00035 00038 00039 namespace TSQR { 00040 namespace Trilinos { 00050 template< class Datum > 00051 class TeuchosMessenger : public MessengerBase< Datum > { 00052 public: 00053 typedef Teuchos::RCP< const Teuchos::Comm<int> > comm_ptr; 00054 00055 TeuchosMessenger (const comm_ptr& pComm) : pComm_ (pComm) {} 00056 00058 virtual void 00059 send (const Datum sendData[], 00060 const int sendCount, 00061 const int destProc, 00062 const int tag) 00063 { 00067 Teuchos::send (*pComm_, sendCount, sendData, destProc); 00068 } 00069 00071 virtual void 00072 recv (Datum recvData[], 00073 const int recvCount, 00074 const int srcProc, 00075 const int tag) 00076 { 00080 Teuchos::receive (*pComm_, srcProc, recvCount, recvData); 00081 } 00082 00086 virtual void 00087 swapData (const Datum sendData[], 00088 Datum recvData[], 00089 const int sendRecvCount, 00090 const int destProc, 00091 const int tag) 00092 { 00093 if (destProc == rank()) 00094 std::copy (sendData, sendData+sendRecvCount, recvData); 00095 else 00096 { 00097 using Teuchos::RCP; 00098 using Teuchos::ArrayRCP; 00099 using Teuchos::CommRequest; 00100 00101 const int srcProc = Teuchos::rank (*pComm_); 00102 00103 // FIXME (mfh 14 June 2010, 09 Jul 2010) It would be nice 00104 // if Teuchos had a sendRecv() routine... as it is, we 00105 // have to do a send and then a receive. We could do an 00106 // isend and an ireceive in order to exploit potential 00107 // overlap of the two messages. That works if sendData 00108 // and recvData don't alias one another. We only do a 00109 // partial check for aliasing here (sendData == recvData). 00110 if (sendData == recvData) 00111 { 00112 // The smaller-rank process sends first, and the 00113 // larger-rank process receives first. 00114 // 00115 // Teuchos::send() and Teuchos::recv() are blocking, 00116 // so we may safely write to recvBuf even if it 00117 // aliases sendBuf. 00118 if (srcProc < destProc) 00119 { 00120 Teuchos::send (*pComm_, sendRecvCount, sendData, destProc); 00121 Teuchos::receive (*pComm_, destProc, sendRecvCount, recvData); 00122 } 00123 else 00124 { 00125 Teuchos::receive (*pComm_, destProc, sendRecvCount, recvData); 00126 Teuchos::send (*pComm_, sendRecvCount, sendData, destProc); 00127 } 00128 } 00129 else 00130 { 00131 ArrayRCP< const Datum > sendBuf (sendData, 0, sendRecvCount, false); 00132 ArrayRCP< Datum > recvBuf (recvData, 0, sendRecvCount, false); 00133 00134 RCP< CommRequest > sendReq, recvReq; 00135 if (srcProc < destProc) 00136 { 00137 sendReq = Teuchos::isend (*pComm_, sendBuf, destProc); 00138 recvReq = Teuchos::ireceive (*pComm_, recvBuf, destProc); 00139 } 00140 else 00141 { 00142 recvReq = Teuchos::ireceive (*pComm_, recvBuf, destProc); 00143 sendReq = Teuchos::isend (*pComm_, sendBuf, destProc); 00144 } 00145 // Wait on both the send and the receive to complete. The 00146 // two can happen independently, because sendBuf and recvBuf 00147 // are different. (We assert no aliasing of buffers here, 00148 // and we've also checked above that destProc != rank().) 00149 Teuchos::waitAll (*pComm_, Teuchos::tuple (sendReq, recvReq)); 00150 } 00151 } 00152 } 00153 00156 virtual Datum 00157 globalSum (const Datum& inDatum) 00158 { 00159 Datum outDatum; 00160 Teuchos::reduceAll (*pComm_, Teuchos::REDUCE_SUM, inDatum, 00161 Teuchos::outArg(outDatum)); 00162 return outDatum; 00163 } 00164 00169 virtual Datum 00170 globalMin (const Datum& inDatum) 00171 { 00172 Datum outDatum; 00173 Teuchos::reduceAll (*pComm_, Teuchos::REDUCE_MIN, inDatum, 00174 Teuchos::outArg(outDatum)); 00175 return outDatum; 00176 } 00177 00182 virtual Datum 00183 globalMax (const Datum& inDatum) 00184 { 00185 Datum outDatum; 00186 Teuchos::reduceAll (*pComm_, Teuchos::REDUCE_MAX, inDatum, 00187 Teuchos::outArg(outDatum)); 00188 return outDatum; 00189 } 00190 00193 virtual void 00194 globalVectorSum (const Datum inData[], 00195 Datum outData[], 00196 const int count) 00197 { 00198 Teuchos::reduceAll (*pComm_, Teuchos::REDUCE_SUM, count, 00199 inData, outData); 00200 } 00201 00202 virtual void 00203 broadcast (Datum data[], 00204 const int count, 00205 const int root) 00206 { 00207 // Assumes that Datum has value semantics. 00208 Teuchos::broadcast (*pComm_, root, count, data); 00209 } 00210 00214 virtual int rank () const { return Teuchos::rank (*pComm_); } 00215 00219 virtual int size () const { return Teuchos::size (*pComm_); } 00220 00224 virtual void barrier () const { Teuchos::barrier (*pComm_); } 00225 00226 private: 00230 comm_ptr pComm_; 00231 }; 00232 } // namespace Trilinos 00233 } // namespace TSQR 00234 00235 #endif // __TSQR_Trilinos_TeuchosMessenger_hpp 00236
1.7.4