ParticleDebug.hpp 9.85 KB
Newer Older
gsell's avatar
gsell committed
1 2 3 4
// -*- C++ -*-
/***************************************************************************
 *
 * The IPPL Framework
5 6
 *
 * This program was prepared by PSI.
gsell's avatar
gsell committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
 * All rights in the program are reserved by PSI.
 * Neither PSI nor the author(s)
 * makes any warranty, express or implied, or assumes any liability or
 * responsibility for the use of this software
 *
 * Visit www.amas.web.psi for more details
 *
 ***************************************************************************/

// -*- C++ -*-
//-----------------------------------------------------------------------------
// The IPPL Framework - Visit http://people.web.psi.ch/adelmann/ for more details
//
// This program was prepared by the Regents of the University of California at
// ParticleDebug.cpp , Tim Williams 8/6/1998
// Helper functions to print out (formatted ASCII) ParticleAttrib elements.
// Intended mainly for use from within a debugger, called interactively, but
// also callable as template functions from source code. To call from many
// debuggers, the user has to provide nontemplate wrapper functions, as
// described in ParticleDebugFunctions.cpp.

// include files
#include "Utility/ParticleDebug.h"
#include "Utility/Inform.h"
uldis_l's avatar
uldis_l committed
31

gsell's avatar
gsell committed
32 33 34 35 36 37 38 39 40 41 42
#include "Particle/ParticleAttrib.h"

#include <iostream>
#include <iomanip> // need format fcns setf() and setprecision() from here


//----------------------------------------------------------------------
// Print a ParticleAttrib
//----------------------------------------------------------------------
template<class T>
void pap(ParticleAttrib<T>& pattr, bool docomm) {
43

gsell's avatar
gsell committed
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
  // Set Inform ptr if not set:
  if (!PtclDbgInformIsSet) {
    if (!FldDbgInformIsSet) {
      PtclDbgInform = new Inform(NULL, INFORM_ALL_NODES);
    }
    else {
      setPtclDbgInform(*FldDbgInform);
    }
  }

  if (docomm) {
    int mype = IpplInfo::myNode();
    int npes = IpplInfo::getNodes();
    int myNumPtcles = pattr.size();
    int numPtcles = pattr.size();
    int tag = Ippl::Comm->next_tag(IPPL_APP_TAG0, IPPL_APP_CYCLE);
    int tag2 = Ippl::Comm->next_tag(IPPL_APP_TAG0, IPPL_APP_CYCLE);
    Message *msg, *msg2;
    if (mype == 0) {
63
      int otherNumPtcles = 0;
gsell's avatar
gsell committed
64
      for (int pe = 1; pe < npes; pe++) {
65 66
        msg = IpplInfo::Comm->receive_block(pe, tag);
        msg->get(otherNumPtcles);
gsell's avatar
gsell committed
67
        delete msg;
68
        numPtcles += otherNumPtcles;
gsell's avatar
gsell committed
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
      }
      msg2 = new Message;
      msg2->put(numPtcles);
      IpplInfo::Comm->broadcast_others(msg2, tag2);
    }
    else {
      msg = new Message;
      msg->put(myNumPtcles);
      IpplInfo::Comm->send(msg, 0, tag);
      int pe0 = 0;
      msg2 = IpplInfo::Comm->receive_block(pe0, tag2);
      msg2->get(numPtcles);
      delete msg2;
    }
    IpplInfo::Comm->barrier();
    spap(pattr, 0, numPtcles - 1, 1, docomm);
85

gsell's avatar
gsell committed
86 87
  }
  else {
88

gsell's avatar
gsell committed
89 90 91 92 93 94 95 96 97 98
    spap(pattr, 0, pattr.size() - 1, 1, docomm);

  }
}

//----------------------------------------------------------------------
// Print a single element of a ParticleAttrib
//----------------------------------------------------------------------
template<class T>
void epap(ParticleAttrib<T>& pattr, int i, bool docomm) {
99 100


gsell's avatar
gsell committed
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
  // Set Inform ptr if not set:
  if (!PtclDbgInformIsSet) {
    if (!FldDbgInformIsSet) {
      PtclDbgInform = new Inform(NULL, INFORM_ALL_NODES);
    }
    else {
      setPtclDbgInform(*FldDbgInform);
    }
  }
  spap(pattr, i, i, 1, docomm);
}

//----------------------------------------------------------------------
// Print a strided subrange of a ParticleAttrib
//----------------------------------------------------------------------
template<class T>
117 118 119 120
void spap(ParticleAttrib<T>& pattr,
          int ibase, int ibound, int istride, bool docomm) {


gsell's avatar
gsell committed
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135

  // Set Inform ptr if not set:
  if (!PtclDbgInformIsSet) {
    if (!FldDbgInformIsSet) {
      PtclDbgInform = new Inform(NULL, INFORM_ALL_NODES);
    }
    else {
      setPtclDbgInform(*FldDbgInform);
    }
  }

  // Check input parameters for errors and unimplemented values:
  bool okParameters = true;
  if (ibase < -1) {
    (*PtclDbgInform) << "spap() error: ibase (= " << ibase
136
                    << ") < lowest index value (= " << 0 << ")" << endl;
gsell's avatar
gsell committed
137 138 139 140 141
    okParameters = false;
  }
  //tjw??? Can't check if i greater than total num ptcles, because this number
  //isn't available in ParticleAttrib
  if (istride < 0) {
142 143
    (*PtclDbgInform) << "spap() error: istride < 0 not implemented yet."
                     << endl;
gsell's avatar
gsell committed
144 145 146 147 148
    okParameters = false;
  }
  else {
    if ((ibound < ibase) && !((ibase == 0) && (ibound == -1))) {
      (*PtclDbgInform) << "spap() error: ibase (= " << ibase
149 150
                       << ") > ibound (=  " << ibound
                       << ") not implemented yet." << endl;
gsell's avatar
gsell committed
151 152 153 154 155
      okParameters = false;
    }
  }
  if (istride == 0) {
    if (((ibound - ibase) != 0) && !((ibase == 0) && (ibound == -1))) {
156 157
      (*PtclDbgInform) << "spap() error: istride = 0 but (ibound - ibase) = "
                       << (ibound - ibase) << endl;
gsell's avatar
gsell committed
158 159 160
      okParameters = false;
    }
    else {
161
      istride = 1; // Allow specifying stride 0 for 1-element range; set=1
gsell's avatar
gsell committed
162 163
    }
  }
164

gsell's avatar
gsell committed
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
  if (!okParameters) return; // Exit if problem with input parameters

  if (docomm) {

    // With communication; assume a GLOBAL particle index range. Find which PEs
    // own parts of it and have those PEs print out their values:
    int myNumPtcles = pattr.size();
    int npes = IpplInfo::getNodes();
    int* numsPtcles = new int[npes];
    int mype = IpplInfo::myNode();
    for (int pe=0; pe<npes; pe++) {
      numsPtcles[pe] = 0;
      if (pe == mype) numsPtcles[pe] = myNumPtcles;
    }
    int tag = Ippl::Comm->next_tag(IPPL_APP_TAG0, IPPL_APP_CYCLE);
    int tag2 = Ippl::Comm->next_tag(IPPL_APP_TAG0, IPPL_APP_CYCLE);
    Message *msg, *msg2;
    if (mype == 0) {
183
      int otherNumPtcles = 0;
gsell's avatar
gsell committed
184
      for (int pe=1; pe<npes; pe++) {
185 186
        msg = IpplInfo::Comm->receive_block(pe, tag);
        msg->get(otherNumPtcles);
gsell's avatar
gsell committed
187
        delete msg;
188
        numsPtcles[pe] = numsPtcles[pe - 1] + otherNumPtcles;
gsell's avatar
gsell committed
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
      }
      msg2 = new Message;
      msg2->putmsg((void *)numsPtcles, sizeof(int), npes);
      IpplInfo::Comm->broadcast_others(msg2, tag2);
    }
    else {
      msg = new Message;
      msg->put(myNumPtcles);
      IpplInfo::Comm->send(msg, 0, tag);
      int pe0 = 0;
      msg2 = IpplInfo::Comm->receive_block(pe0, tag2);
      msg2->getmsg(numsPtcles);
      delete msg2;
    }
    // Find out if I (pe) own part of the stated global particle index range:
    int myPtcleIndexBegin, myPtcleIndexEnd;
    if (mype == 0) {
      myPtcleIndexBegin = 0;
      myPtcleIndexEnd = myNumPtcles - 1;
    }
    else {
      myPtcleIndexBegin = numsPtcles[mype - 1];
      myPtcleIndexEnd = myPtcleIndexBegin + myNumPtcles - 1;
    }
    // Construct Index objects for convenience of using Index::touches, etc:
    Index myRange(myPtcleIndexBegin, myPtcleIndexEnd, 1);
    Index requestedRange(ibase, ibound, istride);
    for (int pe=0; pe < npes; pe++) {
      if (mype == pe) {
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
        if (myNumPtcles > 0) {
          if (myRange.touches(requestedRange)) {
            Index myRequestedRange = requestedRange.intersect(myRange);
            int mybase = myRequestedRange.first();
            int mybound = myRequestedRange.last();
            *PtclDbgInform << "....PE = " << mype
                          << " GLOBAL ptcle index subrange (" << mybase
                          << " : " << mybound << " : " << istride
                          << ")...." << endl;
            for (int p = mybase; p <= mybound; p += istride*elementsPerLine) {
              for (int item = 0; ((item < elementsPerLine) &&
                                  ((p+item*istride) <= mybound)); item++) {
//                                (item < mylength)); item++) {
                *PtclDbgInform << std::setprecision(digitsPastDecimal)
                               << std::setw(widthOfElements)
                               << pattr[p + item*istride] << " ";
              }
gsell's avatar
gsell committed
235

236 237 238 239
              *PtclDbgInform << endl;
            }
          }
        }
gsell's avatar
gsell committed
240
        else {
241 242 243
          //don't         *PtclDbgInform << "....PE = " << mype
          //don't			<< " has no particles ...." << endl;
        }
gsell's avatar
gsell committed
244 245 246 247 248 249
      }
      IpplInfo::Comm->barrier();
    }
    if (mype == 0) *PtclDbgInform << endl;
    delete [] numsPtcles;
  }
250
  else {
gsell's avatar
gsell committed
251 252 253 254 255 256 257

    // No communication; assume calling pe(s) print data for their particle
    // data values having LOCAL index range (ibase,ibound,istride):
    int mype = IpplInfo::myNode();
    int myNumPtcles = pattr.size();
    if (PtclDbgInform->getPrintNode() != INFORM_ALL_NODES) {
      WARNMSG(endl << "spap(): Currently, if docomm=false you must specify "
258 259 260 261 262 263 264 265 266
              << "an Inform object having INFORM_ALL_NODES as its "
              << "printing-node specifier if you want to see output from "
              << "any processor calling [e,s]pap(); the Inform object "
              << "you're trying to use has "
              << PtclDbgInform->getPrintNode() << " specified. "
              << "N.B.: If you called setInform() and didn't also call "
              << "setPtclDbgInform() you are getting the FldDbgInform object "
              << "you set with setInform, which you may not have constructed "
              << "with INFORM_ALL_NODES." << endl << endl);
gsell's avatar
gsell committed
267 268 269
    }

    if (myNumPtcles > 0) {
270 271 272
      *PtclDbgInform << "....PE = " << mype
                    << " LOCAL ptcle index range (" << ibase
                    << " : " << ibound << " : " << istride << ")...." << endl;
gsell's avatar
gsell committed
273 274
      int length = (ibound - ibase)/istride + 1;
      for (int p = ibase; p <= ibound; p += istride*elementsPerLine) {
275 276 277
        for (int item = 0; ((item < elementsPerLine) &&
                            (item < length)); item++) {
          *PtclDbgInform << std::setprecision(digitsPastDecimal)
gsell's avatar
gsell committed
278
                         << pattr[p + item*istride] << " ";
279 280
        }
        *PtclDbgInform << endl;
gsell's avatar
gsell committed
281 282 283
      }
      *PtclDbgInform << endl;
    } else {
284 285
      *PtclDbgInform << "....PE = " << mype
                    << " has no particles ...." << endl;
gsell's avatar
gsell committed
286 287 288
    }

  }
289
}