OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
FieldDebugPrint.hpp
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  *
4  * The IPPL Framework
5  *
6  * This program was prepared by PSI.
7  * All rights in the program are reserved by PSI.
8  * Neither PSI nor the author(s)
9  * makes any warranty, express or implied, or assumes any liability or
10  * responsibility for the use of this software
11  *
12  * Visit www.amas.web.psi for more details
13  *
14  ***************************************************************************/
15 
16 // -*- C++ -*-
17 /***************************************************************************
18  *
19  * The IPPL Framework
20  *
21  *
22  * Visit http://people.web.psi.ch/adelmann/ for more details
23  *
24  ***************************************************************************/
25 
26 // include files
28 
29 #include "Field/BrickExpression.h"
30 #include "Field/GuardCellSizes.h"
31 #include "Utility/IpplInfo.h"
32 #include "Utility/PAssert.h"
33 #include "Message/Communicate.h"
34 #include "Message/Message.h"
35 #include <iomanip>
36 
37 // debugging macro
38 #ifdef IPPL_PRINTDEBUG
39 #define FDPDBG(x) x
40 #else
41 #define FDPDBG(x)
42 #endif
43 
44 
45 // Print out the data for a given field, using it's whole domain
46 template<class T, unsigned Dim>
48  Inform& out, bool allnodes) {
49  NDIndex<Dim> domain;
50  if (PrintBC)
51  domain = AddGuardCells(F.getDomain(), F.getGuardCellSizes());
52  else
53  domain = F.getDomain();
54  print(F, domain, out, allnodes);
55 }
56 
57 
58 // print out the data for a given field, using it's whole domain
59 template<class T, unsigned Dim>
61  NDIndex<Dim> domain;
62  if (PrintBC)
63  domain = AddGuardCells(F.getDomain(), F.getGuardCellSizes());
64  else
65  domain = F.getDomain();
66  Inform out("");
67  print(F, domain, out, allnodes);
68 }
69 
70 
71 // print out the data for a given field and domain
72 template<class T, unsigned Dim>
74  const NDIndex<Dim>& view, bool allnodes) {
75  Inform out("");
76  print(F, view, out, allnodes);
77 }
78 
79 
80 // print out the data for a given field and domain
81 template<class T, unsigned Dim>
83  const NDIndex<Dim>& view,
84  Inform& out,
85  bool allnodes) {
86 
87  // a debug Inform object
88  FDPDBG(Inform dbgmsg("FieldDebugPrint", INFORM_ALL_NODES));
89  FDPDBG(dbgmsg << "Printing domain " << view);
90  FDPDBG(dbgmsg << " for a Field with total domain " << F.getDomain() << endl);
91  FDPDBG(dbgmsg << "Involving all nodes? " << allnodes << endl);
92 
93  // generate a new communication tag, if necessary
94  int tag;
95  if (allnodes) {
97  FDPDBG(dbgmsg << "Using tag = " << tag << endl);
98  }
99 
100  // determine the maximum domain of the field
101  NDIndex<Dim> domain;
102  if (PrintBC)
103  domain = AddGuardCells(F.getDomain(), F.getGuardCellSizes());
104  else
105  domain = F.getDomain();
106  FDPDBG(dbgmsg << "Maximum domain of the field (possibly with GC's) = ");
107  FDPDBG(dbgmsg << domain << endl);
108 
109  // check that the view is contained inside of the Field's domain
110  if(!domain.contains(view)) {
111  ERRORMSG("FieldPrint::print - the domain of the field: " << domain<<endl);
112  ERRORMSG(" must contain the selected view: " << view << endl);
113  return;
114  }
115 
116  // In order to print this stuff right, we need to make sure the
117  // guard cells are filled. But we can only do this if this is
118  // being called by all the nodes, since it requires communication.
119  if (allnodes && F.isDirty()) {
120  FDPDBG(dbgmsg << "Filling guard cells first." << endl);
121  F.fillGuardCells();
122  }
123 
124  // create an LField to store the information for the view, and
125  // an LField to indicate which elements we actually have (they might
126  // not be available if we're printing out from the debugger without
127  // any communication). Start off initially saying we do not have
128  // any data.
129  typedef typename LField<T,Dim>::iterator LFI;
130  typedef typename LField<bool,Dim>::iterator BLFI;
131  typedef PETE_Scalar<bool> BPS;
132  LField<T,Dim> myLField(view,view);
133  LField<bool,Dim> availLField(view,view);
134  BPS trueitem(true);
135  BPS falseitem(false);
136  BLFI blhs = availLField.begin();
137  BrickExpression<Dim,BLFI,BPS,OpAssign>(blhs,falseitem).apply();
138 
139  // create an iterator for looping over local vnodes
140  typename BareField<T,Dim>::iterator_if local;
141 
142  // If we're printing involving all the nodes, send data from local vnodes to
143  // node zero and have that node print. If we're doing this on individual
144  // nodes, just have that node fill in the data it has, and print that
145  // (which does not require any communication).
146  if (allnodes) {
147  // Loop over all the local nodes and send the intersecting data to the
148  // parent node
149  if (Ippl::myNode() != 0) {
150  // prepare a message to send to parent node
151  Message *mess = new Message();
152  int datahere;
153  // put data for each local LField in the message
154  for (local = F.begin_if(); local != F.end_if(); ++local) {
155  // find the intersection of this lfield with the view, and put data in
156  // message.
157  LField<T,Dim> &l = *(*local).second;
159  if (view.touches(lo)) {
160  datahere = 1;
161  NDIndex<Dim> intersection = lo.intersect(view);
162  FDPDBG(dbgmsg << "Node " << Ippl::myNode() << " sending domain ");
163  FDPDBG(dbgmsg << intersection << " to node 0." << endl);
164  T compressed_data;
165  LFI rhs = l.begin(intersection, compressed_data);
166  rhs.TryCompress();
167  ::putMessage(*mess, datahere);
168  intersection.putMessage(*mess);
169  rhs.putMessage(*mess);
170  }
171  }
172 
173  // Send the message.
174  datahere = 0;
175  ::putMessage(*mess, datahere);
176  Ippl::Comm->send(mess, 0, tag);
177  } else {
178  // Receive all the messages, one from each node.
179  for (int remaining = Ippl::getNodes() - 1; remaining > 0; --remaining) {
180  // Receive the generic message.
181  int any_node = COMM_ANY_NODE;
182  Message *mess = Ippl::Comm->receive_block(any_node, tag);
183  PAssert(mess);
184 
185  // keep getting blocks until we're done with the message
186  int datahere;
187  ::getMessage(*mess, datahere);
188  while (datahere != 0) {
189  // Extract the intersection domain from the message.
190  NDIndex<Dim> localBlock;
191  localBlock.getMessage(*mess);
192  FDPDBG(dbgmsg << "Parent receiving domain " << localBlock);
193  FDPDBG(dbgmsg << " from node " << any_node << endl);
194 
195  // Extract the rhs iterator from it.
196  T compressed_value;
197  LFI rhs(compressed_value);
198  rhs.getMessage(*mess);
199 
200  // copy the data into our local LField
201  myLField.Uncompress();
202  availLField.Uncompress();
203  LFI lhs = myLField.begin(localBlock);
204  BrickExpression<Dim,LFI,LFI,OpAssign>(lhs,rhs).apply();
205  BLFI blhs = availLField.begin(localBlock);
206  BrickExpression<Dim,BLFI,BPS,OpAssign>(blhs,trueitem).apply();
207 
208  // see if there is another block
209  ::getMessage(*mess, datahere);
210  }
211 
212  // done with the message now
213  delete mess;
214  }
215  }
216  }
217 
218  // Now that we have populated the localfield with the view, we print.
219  // Only print on node 0, or on all the nodes if allnodes = false.
220  if (!allnodes || Ippl::myNode() == 0) {
221 
222  // TJW 1/22/1999
223 
224  // To make this correct with defergcfill=true and allnodes=false (to avoid
225  // inconsistent/unset guard element values being output as physical
226  // elements, do this in two stages. The first fills the single LField
227  // based on intersections with Allocated domains, which can put some
228  // inconsistent/unset guard-element values into physical element
229  // locations. The second fills the single LField based on intersections
230  // with Owned domains, which will overwrite those bogus values with
231  // correct values from owned physical elements in the original BareField's
232  // LFields. There is undoubtably a more efficient way to achieve this end,
233  // but do it this way for now, to fix the bug:
234 
235  // TJW: First stage: intersect with Allocated:
236 
237  // first need to copy all local blocks into the single LField
238  for (local = F.begin_if(); local != F.end_if(); ++local) {
239  // find the intersection of this lfield with the view
240  LField<T,Dim> &l = *(*local).second;
242  if (view.touches(lo)) {
243  myLField.Uncompress();
244  availLField.Uncompress();
245  NDIndex<Dim> intersection = lo.intersect(view);
246  FDPDBG(dbgmsg << "Node "<<Ippl::myNode()<<" copying local domain ");
247  FDPDBG(dbgmsg << intersection << " into local LField storage."<<endl);
248  LFI lhs = myLField.begin(intersection);
249  LFI rhs = l.begin(intersection);
250  BrickExpression<Dim,LFI,LFI,OpAssign>(lhs,rhs).apply();
251  BLFI blhs = availLField.begin(intersection);
252  BrickExpression<Dim,BLFI,BPS,OpAssign>(blhs,trueitem).apply();
253  }
254  }
255 
256  // TJW: Second stage: intersect with Owned:
257 
258  // first need to copy all local blocks into the single LField
259  for (local = F.begin_if(); local != F.end_if(); ++local) {
260  // find the intersection of this lfield with the view
261  LField<T,Dim> &l = *(*local).second;
262  NDIndex<Dim>& lo = (NDIndex<Dim>&) l.getOwned();
263  if (view.touches(lo)) {
264  myLField.Uncompress();
265  availLField.Uncompress();
266  NDIndex<Dim> intersection = lo.intersect(view);
267  FDPDBG(dbgmsg << "Node "<<Ippl::myNode()<<" copying local domain ");
268  FDPDBG(dbgmsg << intersection << " into local LField storage."<<endl);
269  LFI lhs = myLField.begin(intersection);
270  LFI rhs = l.begin(intersection);
271  BrickExpression<Dim,LFI,LFI,OpAssign>(lhs,rhs).apply();
272  BLFI blhs = availLField.begin(intersection);
273  BrickExpression<Dim,BLFI,BPS,OpAssign>(blhs,trueitem).apply();
274  }
275  }
276 
277  FDPDBG(dbgmsg << "Finished assembling data; now printing." << endl);
278 
279  // finally, we can print
280  out << "~~~~~~~~ field slice ";
281  for (unsigned int pd=0; pd < Dim; ++pd) {
282  out << (pd == 0 ? "(" : ", ");
283  out << view[pd].first() << ":" << view[pd].last();
284  out << ":" << view[pd].stride();
285  }
286  out << ") ~~~~~~~~" << endl;
287  if(Scientific)
288  out.setf(std::ios::scientific);
289 
290  int i0, i1, i2;
291  LFI liter = myLField.begin();
292  BLFI bliter = availLField.begin();
293  switch(Dim) {
294  case 1:
295  for (i0=0; i0 < view[0].length(); ++i0, ++liter, ++bliter)
296  printelem(*bliter, *liter, i0, out);
297  out << endl;
298  break;
299 
300  case 2:
301  for (i1=0; i1 < view[1].length(); ++i1) {
302  out << "--------------------------------------------------J = ";
303  out << view[1].first() + i1 << endl;
304  for (i0=0; i0 < view[0].length(); ++i0, ++liter, ++bliter)
305  printelem(*bliter, *liter, i0, out);
306  out << endl;
307  out << endl;
308  }
309  break;
310 
311  case 3:
312  for (i2=0; i2 < view[2].length(); ++i2) {
313  out << "==================================================K = ";
314  out << view[2].first() + i2 << endl;
315  for (i1=0; i1 < view[1].length(); ++i1) {
316  out << "--------------------------------------------------J = ";
317  out << view[1].first() + i1 << endl;
318  for (i0=0; i0 < view[0].length(); ++i0, ++liter, ++bliter)
319  printelem(*bliter, *liter, i0, out);
320  out << endl;
321  out << endl;
322  }
323  }
324  break;
325 
326  default:
327  ERRORMSG("bad Dimension \"" << Dim << "\" in FieldDebugPrint::print()");
328  ERRORMSG(endl);
329  Ippl::abort();
330  }
331  }
332 }
333 
334 
335 // print a single value to the screen
336 template<class T, unsigned Dim>
337 void FieldDebugPrint<T,Dim>::printelem(bool isavail, T &val,
338  unsigned int i0, Inform& out) {
339  if (DataPrecision > 0)
340  out << std::setprecision(DataPrecision);
341  if (DataWidth > 0)
342  out << std::setw(DataWidth);
343  if(Scientific)
344  out.setf(std::ios::scientific);
345  if (isavail)
346  out << val;
347  else
348  out << '-';
349  if (CarReturn > 0 && ((i0+1) % CarReturn) == 0)
350  out << endl;
351  else
352  out << " ";
353 }
354 
355 
356 /***************************************************************************
357  * $RCSfile: FieldDebugPrint.cpp,v $ $Author: adelmann $
358  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:33 $
359  * IPPL_VERSION_ID: $Id: FieldDebugPrint.cpp,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $
360  ***************************************************************************/
static int getNodes()
Definition: IpplInfo.cpp:773
static void abort(const char *=0, int exitcode=(-1))
Definition: IpplInfo.cpp:696
ac_id_larray::iterator iterator_if
Definition: BareField.h:91
bool isDirty() const
Definition: BareField.h:115
const NDIndex< Dim > & getDomain() const
Definition: BareField.h:151
Definition: rbendmap.h:8
#define INFORM_ALL_NODES
Definition: Inform.h:38
const NDIndex< Dim > & getOwned() const
Definition: LField.h:93
#define ERRORMSG(msg)
Definition: IpplInfo.h:399
Message & getMessage(Message &m)
Definition: NDIndex.h:147
#define FP_TAG_CYCLE
Definition: Tags.h:65
const int COMM_ANY_NODE
Definition: Communicate.h:40
static int myNode()
Definition: IpplInfo.cpp:794
Definition: FFT.h:31
void print(BareField< T, Dim > &, const NDIndex< Dim > &, Inform &, bool=true)
void Uncompress(bool fill_domain=true)
Definition: LField.h:166
FmtFlags_t setf(FmtFlags_t setbits, FmtFlags_t field)
Definition: Inform.h:104
NDIndex< Dim > AddGuardCells(const NDIndex< Dim > &idx, const GuardCellSizes< Dim > &g)
void printelem(bool, T &, unsigned int, Inform &)
int next_tag(int t, int s=1000)
Definition: TagMaker.h:43
const iterator & begin() const
Definition: LField.h:104
virtual void fillGuardCells(bool reallyFill=true) const
Definition: BareField.hpp:298
iterator_if end_if()
Definition: BareField.h:100
#define FDPDBG(x)
bool touches(const NDIndex< Dim > &) const
#define FP_GATHER_TAG
Definition: Tags.h:64
const NDIndex< Dim > & getAllocated() const
Definition: LField.h:92
Definition: FFT.h:30
void getMessage(Message &m, T &t)
Definition: Message.h:580
NDIndex< Dim > intersect(const NDIndex< Dim > &) const
#define PAssert(c)
Definition: PAssert.h:117
Message & putMessage(Message &m) const
Definition: NDIndex.h:139
const GuardCellSizes< Dim > & getGuardCellSizes() const
Definition: BareField.h:146
const unsigned Dim
void putMessage(Message &m, const T &t)
Definition: Message.h:557
iterator_if begin_if()
Definition: BareField.h:99
Message * receive_block(int &node, int &tag)
Definition: Inform.h:41
static Communicate * Comm
Definition: IpplInfo.h:93
bool send(Message *, int node, int tag, bool delmsg=true)
Inform & endl(Inform &inf)
Definition: Inform.cpp:42