|
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_TpetraMessenger_hpp 00030 #define __TSQR_Trilinos_TpetraMessenger_hpp 00031 00032 #include "Teuchos_CommHelpers.hpp" 00033 #include "Tsqr_MessengerBase.hpp" 00034 #include <algorithm> 00035 00038 00039 namespace TSQR { 00040 namespace Trilinos { 00051 template< class Datum > 00052 class TpetraMessenger : public MessengerBase< Datum > { 00053 public: 00054 typedef Teuchos::RCP< const Teuchos::Comm<int> > comm_ptr; 00055 00056 TpetraMessenger (const comm_ptr& pComm) : pComm_ (pComm) {} 00057 00059 virtual void 00060 send (const Datum sendData[], 00061 const int sendCount, 00062 const int destProc, 00063 const int tag) 00064 { 00068 Teuchos::send (*pComm_, sendCount, sendData, destProc); 00069 } 00070 00072 virtual void 00073 recv (Datum recvData[], 00074 const int recvCount, 00075 const int srcProc, 00076 const int tag) 00077 { 00081 Teuchos::receive (*pComm_, srcProc, recvCount, recvData); 00082 } 00083 00087 virtual void 00088 swapData (const Datum sendData[], 00089 Datum recvData[], 00090 const int sendRecvCount, 00091 const int destProc, 00092 const int tag) 00093 { 00094 if (destProc == rank()) 00095 std::copy (sendData, sendData+sendRecvCount, recvData); 00096 else 00097 { 00098 using Teuchos::RCP; 00099 using Teuchos::ArrayRCP; 00100 using Teuchos::CommRequest; 00101 00102 const int srcProc = Teuchos::rank (*pComm_); 00103 00104 // FIXME (mfh 14 June 2010, 09 Jul 2010) It would be nice 00105 // if Teuchos had a sendRecv() routine... as it is, we 00106 // have to do a send and then a receive. We could do an 00107 // isend and an ireceive in order to exploit potential 00108 // overlap of the two messages. That works if sendData 00109 // and recvData don't alias one another. We only do a 00110 // partial check for aliasing here (sendData == recvData). 00111 if (sendData == recvData) 00112 { 00113 // The smaller-rank process sends first, and the 00114 // larger-rank process receives first. 00115 // 00116 // Teuchos::send() and Teuchos::recv() are blocking, 00117 // so we may safely write to recvBuf even if it 00118 // aliases sendBuf. 00119 if (srcProc < destProc) 00120 { 00121 Teuchos::send (*pComm_, sendRecvCount, sendData, destProc); 00122 Teuchos::receive (*pComm_, destProc, sendRecvCount, recvData); 00123 } 00124 else 00125 { 00126 Teuchos::receive (*pComm_, destProc, sendRecvCount, recvData); 00127 Teuchos::send (*pComm_, sendRecvCount, sendData, destProc); 00128 } 00129 } 00130 else 00131 { 00132 ArrayRCP< const Datum > sendBuf (sendData, 0, sendRecvCount, false); 00133 ArrayRCP< Datum > recvBuf (recvData, 0, sendRecvCount, false); 00134 00135 RCP< CommRequest > sendReq, recvReq; 00136 if (srcProc < destProc) 00137 { 00138 sendReq = Teuchos::isend (*pComm_, sendBuf, destProc); 00139 recvReq = Teuchos::ireceive (*pComm_, recvBuf, destProc); 00140 } 00141 else 00142 { 00143 recvReq = Teuchos::ireceive (*pComm_, recvBuf, destProc); 00144 sendReq = Teuchos::isend (*pComm_, sendBuf, destProc); 00145 } 00146 // Wait on both the send and the receive to complete. The 00147 // two can happen independently, because sendBuf and recvBuf 00148 // are different. (We assert no aliasing of buffers here, 00149 // and we've also checked above that destProc != rank().) 00150 Teuchos::waitAll (*pComm_, Teuchos::tuple (sendReq, recvReq)); 00151 } 00152 } 00153 } 00154 00157 virtual Datum 00158 globalSum (const Datum& inDatum) 00159 { 00160 Datum outDatum; 00161 Teuchos::reduceAll (*pComm_, Teuchos::REDUCE_SUM, inDatum, 00162 Teuchos::outArg(outDatum)); 00163 return outDatum; 00164 } 00165 00170 virtual Datum 00171 globalMin (const Datum& inDatum) 00172 { 00173 Datum outDatum; 00174 Teuchos::reduceAll (*pComm_, Teuchos::REDUCE_MIN, inDatum, 00175 Teuchos::outArg(outDatum)); 00176 return outDatum; 00177 } 00178 00183 virtual Datum 00184 globalMax (const Datum& inDatum) 00185 { 00186 Datum outDatum; 00187 Teuchos::reduceAll (*pComm_, Teuchos::REDUCE_MAX, inDatum, 00188 Teuchos::outArg(outDatum)); 00189 return outDatum; 00190 } 00191 00194 virtual void 00195 globalVectorSum (const Datum inData[], 00196 Datum outData[], 00197 const int count) 00198 { 00199 Teuchos::reduceAll (*pComm_, Teuchos::REDUCE_SUM, count, 00200 inData, outData); 00201 } 00202 00203 virtual void 00204 broadcast (Datum data[], 00205 const int count, 00206 const int root) 00207 { 00208 // Assumes that Datum has value semantics. 00209 Teuchos::broadcast (*pComm_, root, count, data); 00210 } 00211 00215 virtual int rank () const { return Teuchos::rank (*pComm_); } 00216 00220 virtual int size () const { return Teuchos::size (*pComm_); } 00221 00225 virtual void barrier () const { Teuchos::barrier (*pComm_); } 00226 00227 private: 00231 comm_ptr pComm_; 00232 }; 00233 } // namespace Trilinos 00234 } // namespace TSQR 00235 00236 #endif // __TSQR_Trilinos_TpetraMessenger_hpp 00237
1.7.4