src/IplPaws/PawsPtclAttribDataSource.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  * This program was prepared by PSI. 
00007  * All rights in the program are reserved by PSI.
00008  * Neither PSI nor the author(s)
00009  * makes any warranty, express or implied, or assumes any liability or
00010  * responsibility for the use of this software
00011  *
00012  * Visit http://www.acl.lanl.gov/POOMS for more details
00013  *
00014  ***************************************************************************/
00015 
00016 // -*- C++ -*-
00017 /***************************************************************************
00018  *
00019  * The IPPL Framework
00020  * 
00021  *
00022  * Visit http://people.web.psi.ch/adelmann/ for more details
00023  *
00024  ***************************************************************************/
00025 
00026 // IPPL include files
00027 #include "IpplPaws/PawsPtclAttribDataSource.h"
00028 #include "IpplPaws/PawsDataConnect.h"
00029 #include "Particle/ParticleAttrib.h"
00030 #include "Message/Message.h"
00031 #include "Utility/IpplInfo.h"
00032 #include "Utility/Pstring.h"
00033 #include "Profile/Profiler.h"
00034 
00035 // PAWS include files
00036 #include "Paws/Paws.h"
00037 
00038 
00040 // constructor: the name, the connection, the transfer method, the attrib
00041 template<class T>
00042 PawsParticleAttribDataSource<T>::PawsParticleAttribDataSource(const
00043                                                               char *nm,
00044       DataConnect *dc, int tm, ParticleAttrib<T>& pa)
00045   : DataSourceObject(nm, &pa, dc, tm), attrib(pa),
00046     pawsArray(0), pawsConnect(0), sizeinfo(0)
00047 {
00048   TAU_TYPE_STRING(taustr, "void (char *, DataConnect *, int, " +
00049                   CT(pa));
00050   TAU_PROFILE(
00051     "PawsParticleAttribDataSource::PawsParticleAttribDataSource()",
00052     taustr, TAU_VIZ);
00053 
00054   // do general initialization
00055   string filestring = "paws";
00056   if (string(dc->ID()) != filestring) {
00057     ERRORMSG("Illegal DataConnect object for Paws Data Object." << endl);
00058     Connection = 0;
00059   } else {
00060     // get the data connection pointer for a PAWS connection
00061     pawsConnect = (PawsDataConnect *)dc;
00062 
00063     // figure out the transfer method
00064     if (TransferMethod == DataSource::DEFAULT)
00065       TransferMethod = dc->getDefaultTransferMethod();
00066 
00067     int mode = PAWS_OUT;
00068 
00069     if (TransferMethod == DataSource::INPUT)
00070       mode = PAWS_IN;
00071     else if (TransferMethod == DataSource::OUTPUT)
00072       mode = PAWS_OUT;
00073     else if (TransferMethod == DataSource::BOTH)
00074       mode = PAWS_INOUT;
00075 
00076     // Create a new PawsArrayData object to refer to this attribute
00077     // so that it can connect to other apps.
00078     pawsArray = new PawsArrayData<PawsType_t>(nm, mode,
00079                                               PAWS_SYNC,
00080                                               PAWS_COLUMN,
00081                                               *(pawsConnect->getPawsApp()));
00082 
00083     // we need an array to hold size integers, one for each node
00084     sizeinfo = new int[Ippl::getNodes()];
00085   }
00086 }
00087 
00088 
00090 // destructor
00091 template<class T>
00092 PawsParticleAttribDataSource<T>::~PawsParticleAttribDataSource() {
00093   TAU_TYPE_STRING(taustr, CT(*this) + " void ()");
00094   TAU_PROFILE("PawsParticleAttribDataSource::~PawsParticleAttribDataSource()", 
00095     taustr, TAU_VIZ);
00096 
00097   //Inform dbgmsg("~PawsParticleAttribDataSource", INFORM_ALL_NODES);
00098 
00099   // delete size info array
00100   if (sizeinfo != 0)
00101     delete [] sizeinfo;
00102 
00103   // delete (does disconnect) the array object, if we still have it
00104   //dbgmsg << "Deleting the PawsArrayData object ..." << endl;
00105   if (pawsArray != 0 && pawsConnect != 0) {
00106     //dbgmsg << "Waiting at barrier before deleting PawsArrayData ..." << endl;
00107     //Ippl::Comm->barrier();
00108     pawsConnect->barrier();
00109     delete pawsArray;
00110   }
00111 }
00112 
00113 
00115 // Update the object, that is, make sure the receiver of the data has a
00116 // current and consistent snapshot of the current state.  Return success.
00117 template<class T>
00118 bool PawsParticleAttribDataSource<T>::update() {
00119   TAU_TYPE_STRING(taustr, CT(*this) + " bool ()");
00120   TAU_PROFILE("PawsParticleAttribDataSource::update()", taustr, TAU_VIZ);
00121 
00122   int localblocks = 0, i, first, last, stride, localinfo[3];
00123   int offset = 0, totalsize = 0;
00124   PawsType_t *ptrs[1];
00125   ptrs[0] = 0;
00126 
00127   //Inform dbgmsg("PawsPtclAttrib");
00128   //dbgmsg << "Updating dynamic array '" << name() << "' ..." << endl;
00129   pawsConnect->barrier();
00130 
00131   // if we are sending the data, first do an update, then a send
00132   if (TransferMethod == DataSource::OUTPUT ||
00133       TransferMethod == DataSource::BOTH) {
00134 
00135     // first do the update ... for particles, there is at most one block
00136     // on each processor, but of varying size.  Get info about each block.
00137 
00138     // first do a reduction to get size info for each block
00139     //dbgmsg << "Sending my local size = " << attrib.size() << " ..." <<endl;
00140     for (i=0; i < Ippl::getNodes(); ++i)
00141       sizeinfo[i] = (i == Ippl::myNode() ? attrib.size() : 0);
00142 
00143     reduce(sizeinfo, sizeinfo + Ippl::getNodes(), sizeinfo, OpAddAssign());
00144 
00145     // find our relative offset for our block of data
00146     //dbgmsg << "Received global block size info:";
00147     offset = totalsize = 0;
00148     for (i=0; i < Ippl::getNodes(); ++i) {
00149       //dbgmsg << "  " << sizeinfo[i];
00150       if (i < Ippl::myNode())
00151         offset += sizeinfo[i];
00152       totalsize += sizeinfo[i];
00153     }
00154     //dbgmsg << " ... my offset=" << offset << ", total=" << totalsize << endl;
00155 
00156     // set up all the layout information
00157     first = 0;
00158     last = Size * totalsize - 1;
00159     stride = 1;
00160     localinfo[0] = Size * offset;
00161     localinfo[1] = Size * (offset + attrib.size()) - 1;
00162     localinfo[2] = 1;
00163 
00164     if (attrib.size() > 0) {
00165       localblocks = 1;
00166       ptrs[0] = reinterpret_cast<PawsType_t *>(&(attrib[0]));
00167     } else {
00168       localblocks = 0;
00169     }
00170 
00171     // now update the paws array info
00172     //dbgmsg << "Doing resize with " << localblocks << " local blocks, ";
00173     //dbgmsg << attrib.size() << " local particles, and total domain = [";
00174     //dbgmsg << first << "," << last << "," << stride << "]" << endl;
00175     //pawsConnect->barrier();
00176     pawsArray->resize(ptrs, 1, &first, &last, &stride, localblocks, localinfo);
00177 
00178     // after the update, do a send
00179     pawsArray->send();
00180 
00181   } else {
00182 
00183     // wait for resize info, if necessary ... if this returns
00184     // PAWS_ERROR, we're not connected to anything so we don't
00185     // need to do a receive, etc.
00186 
00187     //dbgmsg << "Waiting for resize information ..." << endl;
00188     //pawsConnect->barrier();
00189     if (pawsArray->resizeWait() == PAWS_ERROR)
00190       return true;
00191 
00192     // first get the total domain
00193     pawsArray->size(&totalsize);
00194     totalsize /= Size;
00195     //dbgmsg << "After waiting for resize info, new size = " << totalsize;
00196     //dbgmsg << endl;
00197 
00198     // put N/P elements on each node, extending or deleting as necessary
00199     int onnode = totalsize / Ippl::getNodes();
00200     int extra = totalsize % Ippl::getNodes();
00201     offset = onnode * Ippl::myNode();
00202     if (Ippl::myNode() < extra) {
00203       onnode++;
00204       offset += Ippl::myNode();
00205     } else {
00206       offset += extra;
00207     }
00208 
00209     //dbgmsg << "Putting " << onnode << " particles with offset = " << offset;
00210     //dbgmsg << " on my node ..." << endl;
00211     if (attrib.size() < onnode)
00212       attrib.create(onnode - attrib.size());
00213     else if (attrib.size() > onnode)
00214       attrib.destroy(attrib.size() - onnode, onnode - 1);
00215 
00216     // set up description of the blocks on our local node
00217     first = 0;
00218     last = Size * totalsize - 1;
00219     stride = 1;
00220     localinfo[0] = Size * offset;
00221     localinfo[1] = Size * (offset + attrib.size()) - 1;
00222     localinfo[2] = 1;
00223     if (attrib.size() > 0) {
00224       localblocks = 1;
00225       ptrs[0] = reinterpret_cast<PawsType_t *>(&(attrib[0]));
00226     } else {
00227       localblocks = 0;
00228     }
00229 
00230     // now update the paws array info
00231     //dbgmsg << "Doing update with " << localblocks << " local blocks, ";
00232     //dbgmsg << attrib.size() << " local particles, and total domain = [";
00233     //dbgmsg << first << "," << last << "," << stride << "]" << endl;
00234     pawsArray->update(ptrs, 1, &first, &last, &stride, localblocks, localinfo);
00235 
00236     // after the update, do a send
00237     //dbgmsg << "Calling receive() ..." << endl;
00238     pawsArray->receive();
00239   }
00240 
00241   // just return, the user should do an update for the ParticleBase
00242   return true;
00243 }
00244 
00245 
00247 // Indicate to the receiver that we're allowing them time to manipulate the
00248 // data (e.g., for a viz program, to rotate it, change representation, etc.)
00249 // This should only return when the manipulation is done.
00250 template<class T>
00251 void PawsParticleAttribDataSource<T>::interact(const char *str) {
00252   TAU_TYPE_STRING(taustr, CT(*this) + " void ()");
00253   TAU_PROFILE("PawsParticleAttribDataSource::interact()", taustr, TAU_VIZ);
00254 
00255   // hand off control to Paws API
00256   pawsConnect->poll();
00257 }
00258 
00260 // List the object to a stream.  This is required by Paws.
00261 // Currently, it is just a stub.
00262 template<class T>
00263 ostream& operator<<(ostream& out, const PawsParticleAttribDataSource<T>& attrib)
00264 {
00265   out << "PawsParticleAttribDataSource" << endl;
00266   return out;
00267 }
00268 
00269 /***************************************************************************
00270  * $RCSfile: PawsPtclAttribDataSource.cpp,v $   $Author: adelmann $
00271  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:32 $
00272  * IPPL_VERSION_ID: $Id: PawsPtclAttribDataSource.cpp,v 1.1.1.1 2003/01/23 07:40:32 adelmann Exp $ 
00273  ***************************************************************************/

Generated on Mon Jan 16 13:23:49 2006 for IPPL by  doxygen 1.4.6