src/Utility/ParticleDebug.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 // The IPPL Framework - Visit http://people.web.psi.ch/adelmann/ for more details
00019 //
00020 // This program was prepared by the Regents of the University of California at
00021 // ParticleDebug.cpp , Tim Williams 8/6/1998
00022 // Helper functions to print out (formatted ASCII) ParticleAttrib elements.
00023 // Intended mainly for use from within a debugger, called interactively, but
00024 // also callable as template functions from source code. To call from many
00025 // debuggers, the user has to provide nontemplate wrapper functions, as
00026 // described in ParticleDebugFunctions.cpp.
00027 
00028 // include files
00029 #include "Utility/ParticleDebug.h"
00030 #include "Utility/Inform.h"
00031 #include "Profile/Profiler.h"
00032 #include "Particle/ParticleAttrib.h"
00033 
00034 #ifdef IPPL_USE_STANDARD_HEADERS
00035 #include <iostream>
00036 #include <iomanip> // need format fcns setf() and setprecision() from here
00037 using namespace std;
00038 #else
00039 #include <iostream.h>
00040 #include <iomanip.h> // need format fcns setf() and setprecision() from here
00041 #endif
00042 
00043 
00044 //----------------------------------------------------------------------
00045 // Print a ParticleAttrib
00046 //----------------------------------------------------------------------
00047 template<class T>
00048 void pap(ParticleAttrib<T>& pattr, bool docomm) {
00049   TAU_TYPE_STRING(taustr, "void (" + CT(pattr) + " )" );
00050   TAU_PROFILE("pap()", taustr, TAU_UTILITY | TAU_FIELD | TAU_IO);
00051   // Set Inform ptr if not set:
00052   if (!PtclDbgInformIsSet) {
00053     if (!FldDbgInformIsSet) {
00054       PtclDbgInform = new Inform(NULL, INFORM_ALL_NODES);
00055     }
00056     else {
00057       setPtclDbgInform(*FldDbgInform);
00058     }
00059   }
00060 
00061   if (docomm) {
00062     int mype = IpplInfo::myNode();
00063     int npes = IpplInfo::getNodes();
00064     int myNumPtcles = pattr.size();
00065     int numPtcles = pattr.size();
00066     int tag = Ippl::Comm->next_tag(IPPL_APP_TAG0, IPPL_APP_CYCLE);
00067     int tag2 = Ippl::Comm->next_tag(IPPL_APP_TAG0, IPPL_APP_CYCLE);
00068     Message *msg, *msg2;
00069     if (mype == 0) {
00070       int otherNumPtcles;
00071       for (int pe = 1; pe < npes; pe++) {
00072         msg = IpplInfo::Comm->receive_block(pe, tag);
00073         msg->get(otherNumPtcles);
00074         delete msg;
00075         numPtcles += otherNumPtcles;
00076       }
00077       msg2 = new Message;
00078       msg2->put(numPtcles);
00079       IpplInfo::Comm->broadcast_others(msg2, tag2);
00080     }
00081     else {
00082       msg = new Message;
00083       msg->put(myNumPtcles);
00084       IpplInfo::Comm->send(msg, 0, tag);
00085       int pe0 = 0;
00086       msg2 = IpplInfo::Comm->receive_block(pe0, tag2);
00087       msg2->get(numPtcles);
00088       delete msg2;
00089     }
00090     IpplInfo::Comm->barrier();
00091     spap(pattr, 0, numPtcles - 1, 1, docomm);
00092     
00093   }
00094   else {
00095       
00096     spap(pattr, 0, pattr.size() - 1, 1, docomm);
00097 
00098   }
00099 }
00100 
00101 //----------------------------------------------------------------------
00102 // Print a single element of a ParticleAttrib
00103 //----------------------------------------------------------------------
00104 template<class T>
00105 void epap(ParticleAttrib<T>& pattr, int i, bool docomm) {
00106   TAU_TYPE_STRING(taustr, "void (" + CT(pattr) + ", int )" );
00107   TAU_PROFILE("epap()", taustr, TAU_UTILITY | TAU_FIELD | TAU_IO);
00108   // Set Inform ptr if not set:
00109   if (!PtclDbgInformIsSet) {
00110     if (!FldDbgInformIsSet) {
00111       PtclDbgInform = new Inform(NULL, INFORM_ALL_NODES);
00112     }
00113     else {
00114       setPtclDbgInform(*FldDbgInform);
00115     }
00116   }
00117   spap(pattr, i, i, 1, docomm);
00118 }
00119 
00120 //----------------------------------------------------------------------
00121 // Print a strided subrange of a ParticleAttrib
00122 //----------------------------------------------------------------------
00123 template<class T>
00124 void spap(ParticleAttrib<T>& pattr, 
00125           int ibase, int ibound, int istride, bool docomm) {
00126   TAU_TYPE_STRING(taustr, "void (" + CT(pattr) + ", int, int, int )" );
00127   TAU_PROFILE("spap()", taustr, TAU_UTILITY | TAU_FIELD | TAU_IO);
00128 
00129   // Set Inform ptr if not set:
00130   if (!PtclDbgInformIsSet) {
00131     if (!FldDbgInformIsSet) {
00132       PtclDbgInform = new Inform(NULL, INFORM_ALL_NODES);
00133     }
00134     else {
00135       setPtclDbgInform(*FldDbgInform);
00136     }
00137   }
00138 
00139   // Check input parameters for errors and unimplemented values:
00140   bool okParameters = true;
00141   if (ibase < -1) {
00142     (*PtclDbgInform) << "spap() error: ibase (= " << ibase
00143                     << ") < lowest index value (= " << 0 << ")" << endl;
00144     okParameters = false;
00145   }
00146   //tjw??? Can't check if i greater than total num ptcles, because this number
00147   //isn't available in ParticleAttrib
00148   if (istride < 0) {
00149     (*PtclDbgInform) << "spap() error: istride < 0 not implemented yet." 
00150                      << endl;
00151     okParameters = false;
00152   }
00153   else {
00154     if ((ibound < ibase) && !((ibase == 0) && (ibound == -1))) {
00155       (*PtclDbgInform) << "spap() error: ibase (= " << ibase
00156                        << ") > ibound (=  " << ibound 
00157                        << ") not implemented yet." << endl;
00158       okParameters = false;
00159     }
00160   }
00161   if (istride == 0) {
00162     if (((ibound - ibase) != 0) && !((ibase == 0) && (ibound == -1))) {
00163       (*PtclDbgInform) << "spap() error: istride = 0 but (ibound - ibase) = " 
00164                        << (ibound - ibase) << endl;
00165       okParameters = false;
00166     }
00167     else {
00168       istride = 1; // Allow specifying stride 0 for 1-element range; set=1 
00169     }
00170   }
00171   
00172   if (!okParameters) return; // Exit if problem with input parameters
00173 
00174   if (docomm) {
00175 
00176     // With communication; assume a GLOBAL particle index range. Find which PEs
00177     // own parts of it and have those PEs print out their values:
00178     int myNumPtcles = pattr.size();
00179     int npes = IpplInfo::getNodes();
00180     int* numsPtcles = new int[npes];
00181     int mype = IpplInfo::myNode();
00182     for (int pe=0; pe<npes; pe++) {
00183       numsPtcles[pe] = 0;
00184       if (pe == mype) numsPtcles[pe] = myNumPtcles;
00185     }
00186     int tag = Ippl::Comm->next_tag(IPPL_APP_TAG0, IPPL_APP_CYCLE);
00187     int tag2 = Ippl::Comm->next_tag(IPPL_APP_TAG0, IPPL_APP_CYCLE);
00188     Message *msg, *msg2;
00189     if (mype == 0) {
00190       int otherNumPtcles;
00191       for (int pe=1; pe<npes; pe++) {
00192         msg = IpplInfo::Comm->receive_block(pe, tag);
00193         msg->get(otherNumPtcles);
00194         delete msg;
00195         numsPtcles[pe] = numsPtcles[pe - 1] + otherNumPtcles;
00196       }
00197       msg2 = new Message;
00198       msg2->putmsg((void *)numsPtcles, sizeof(int), npes);
00199       IpplInfo::Comm->broadcast_others(msg2, tag2);
00200     }
00201     else {
00202       msg = new Message;
00203       msg->put(myNumPtcles);
00204       IpplInfo::Comm->send(msg, 0, tag);
00205       int pe0 = 0;
00206       msg2 = IpplInfo::Comm->receive_block(pe0, tag2);
00207       msg2->getmsg(numsPtcles);
00208       delete msg2;
00209     }
00210     // Find out if I (pe) own part of the stated global particle index range:
00211     int myPtcleIndexBegin, myPtcleIndexEnd;
00212     if (mype == 0) {
00213       myPtcleIndexBegin = 0;
00214       myPtcleIndexEnd = myNumPtcles - 1;
00215     }
00216     else {
00217       myPtcleIndexBegin = numsPtcles[mype - 1];
00218       myPtcleIndexEnd = myPtcleIndexBegin + myNumPtcles - 1;
00219     }
00220     // Construct Index objects for convenience of using Index::touches, etc:
00221     Index myRange(myPtcleIndexBegin, myPtcleIndexEnd, 1);
00222     Index requestedRange(ibase, ibound, istride);
00223     for (int pe=0; pe < npes; pe++) {
00224       if (mype == pe) {
00225         if (myNumPtcles > 0) {
00226           if (myRange.touches(requestedRange)) {
00227             Index myRequestedRange = requestedRange.intersect(myRange);
00228             int mybase = myRequestedRange.first();
00229             int mybound = myRequestedRange.last();
00230             int mylength = myRequestedRange.length();
00231             *PtclDbgInform << "....PE = " << mype 
00232                           << " GLOBAL ptcle index subrange (" << mybase
00233                           << " : " << mybound << " : " << istride 
00234                           << ")...." << endl;
00235             for (int p = mybase; p <= mybound; p += istride*elementsPerLine) {
00236               for (int item = 0; ((item < elementsPerLine) &&
00237                                   ((p+item*istride) <= mybound)); item++) {
00238 //                                (item < mylength)); item++) {
00239                 *PtclDbgInform << setprecision(digitsPastDecimal) 
00240                                << setw(widthOfElements)
00241                                << pattr[p + item*istride] << " ";
00242               }
00243 
00244               *PtclDbgInform << endl;
00245             }
00246           }         
00247         }
00248         else {
00249           //don't         *PtclDbgInform << "....PE = " << mype 
00250           //don't                       << " has no particles ...." << endl;
00251         }
00252       }
00253       IpplInfo::Comm->barrier();
00254     }
00255     if (mype == 0) *PtclDbgInform << endl;
00256     delete [] numsPtcles;
00257   }
00258   else { 
00259 
00260     // No communication; assume calling pe(s) print data for their particle
00261     // data values having LOCAL index range (ibase,ibound,istride):
00262     int mype = IpplInfo::myNode();
00263     int myNumPtcles = pattr.size();
00264     if (PtclDbgInform->getPrintNode() != INFORM_ALL_NODES) {
00265       WARNMSG(endl << "spap(): Currently, if docomm=false you must specify "
00266               << "an Inform object having INFORM_ALL_NODES as its "
00267               << "printing-node specifier if you want to see output from "
00268               << "any processor calling [e,s]pap(); the Inform object "
00269               << "you're trying to use has " 
00270               << PtclDbgInform->getPrintNode() << " specified. " 
00271               << "N.B.: If you called setInform() and didn't also call "
00272               << "setPtclDbgInform() you are getting the FldDbgInform object "
00273               << "you set with setInform, which you may not have constructed "
00274               << "with INFORM_ALL_NODES." << endl << endl);
00275     }
00276 
00277     if (myNumPtcles > 0) {
00278       *PtclDbgInform << "....PE = " << mype 
00279                     << " LOCAL ptcle index range (" << ibase
00280                     << " : " << ibound << " : " << istride << ")...." << endl;
00281       int length = (ibound - ibase)/istride + 1;
00282       for (int p = ibase; p <= ibound; p += istride*elementsPerLine) {
00283         for (int item = 0; ((item < elementsPerLine) &&
00284                             (item < length)); item++) {
00285           *PtclDbgInform << setprecision(digitsPastDecimal) 
00286                         << pattr[p + item*istride] << " ";
00287         }
00288         *PtclDbgInform << endl;
00289       }
00290       *PtclDbgInform << endl;
00291     } else {
00292       *PtclDbgInform << "....PE = " << mype 
00293                     << " has no particles ...." << endl;
00294     }
00295 
00296   }
00297 
00298 }
00299 
00300 // $Id: ParticleDebug.cpp,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $
00301 
00302 /***************************************************************************
00303  * $RCSfile: addheaderfooter,v $   $Author: adelmann $
00304  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:17 $
00305  * IPPL_VERSION_ID: $Id: addheaderfooter,v 1.1.1.1 2003/01/23 07:40:17 adelmann Exp $ 
00306  ***************************************************************************/
00307 

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