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