OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
FieldLayout.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  *
4  * The IPPL Framework
5  *
6  *
7  * Visit http://people.web.psi.ch/adelmann/ for more details
8  *
9  ***************************************************************************/
10 
11 #ifndef FIELD_LAYOUT_H
12 #define FIELD_LAYOUT_H
13 
14 // FieldLayout describes how a given index space (represented by an NDIndex
15 // object) is partitioned into vnodes. It performs the initial partitioning,
16 // and stores a list of local and remote vnodes. The user may request that a
17 // particular dimension not be partitioned by flagging that axis as 'SERIAL'
18 // (instead of 'PARALLEL').
19 
20 // For a power-of-two number of vnodes, using the basic constructor, the
21 // partitioning is done using a recursive bisection method which makes cuts
22 // along whole hyperplanes in the global index space. For non-power-of-two
23 // vnodes with the basic constructor, the cuts do not necessarily go all the
24 // way across all the elements in all directions. There is also a constructor
25 // with extra arguments specifying the numbers of vnodes along each direction;
26 // this one makes the specified number of cuts to divide up the given
27 // directions. This last constructor obviously only works for numbers of vnodes
28 // expressible as products of N numbers (in ND), though 1 is an allowable
29 // number so it really allows any number of vnodes.
30 
31 // include files
33 #include "FieldLayout/Vnode.h"
34 #include "DomainMap/DomainMap.h"
35 #include "Index/NDIndex.h"
36 #include "Field/GuardCellSizes.h"
37 #include "Utility/IpplInfo.h"
38 #include "Utility/UserList.h"
39 #include "Utility/vmap.h"
40 #include "Utility/Unique.h"
41 #include "Utility/my_auto_ptr.h"
42 #include "Utility/RefCounted.h"
43 
44 // #include "source/grid/brick.h"
45 
46 
47 #include <iostream>
48 
49 // forward declarations
50 template <unsigned Dim> class FieldLayout;
51 template <unsigned Dim>
52 std::ostream& operator<<(std::ostream&, const FieldLayout<Dim>&);
53 
54 // enumeration used to select serial or parallel axes
55 enum e_dim_tag { SERIAL=0, PARALLEL=1 } ;
56 
57 
58 // class definition ... inheritance is private, so that we hide the
59 // UserList checkin routines and instead replace them with our own
60 template<unsigned Dim>
61 class FieldLayout : private UserList
62 {
63 
64 public:
65  // Typedefs for containers.
71 
72  // Typedefs for iterators.
77  typedef std::pair<touch_iterator_dv,touch_iterator_dv> touch_range_dv;
81 
82 private:
83  // utility to return a zero-guard cell structure.
84  static GuardCellSizes<Dim> gc0() { return GuardCellSizes<Dim>(0U); }
85 
86 public:
87  //
88  // constructors and destructors
89  //
90 
91  // Default constructor, which should only be used if you are going to
92  // call 'initialize' soon after (before using in any context)
93  FieldLayout();
94 
95  // Constructor which reads in FieldLayout data from a file. If the
96  // file contains data for an equal number of nodes as we are running on,
97  // then that vnode -> pnode mapping will be used. If the file does not
98  // contain info for the same number of pnodes, the vnodes will be
99  // distributed in some other manner.
100  FieldLayout(const char *filename);
101 
102  // Constructors for 1 ... 6 dimensions
103  // These specify only a total number of vnodes, allowing the constructor
104  // complete control on how to do the vnode partitioning of the index space:
105  FieldLayout(const Index& i1,
106  e_dim_tag p1=PARALLEL, int vnodes=-1);
107  FieldLayout(const Index& i1, const Index& i2,
108  e_dim_tag p1=PARALLEL, e_dim_tag p2=PARALLEL, int vnodes=-1);
109  FieldLayout(const Index& i1, const Index& i2, const Index& i3,
111  e_dim_tag p3=PARALLEL, int vnodes=-1);
112  FieldLayout(const Index& i1, const Index& i2, const Index& i3,
113  const Index& i4,
116  int vnodes=-1);
117  FieldLayout(const Index& i1, const Index& i2, const Index& i3,
118  const Index& i4, const Index& i5,
121  e_dim_tag p5=PARALLEL,
122  int vnodes=-1);
123  FieldLayout(const Index& i1, const Index& i2, const Index& i3,
124  const Index& i4, const Index& i5, const Index& i6,
128  int vnodes=-1);
129 
130  // These specify both the total number of vnodes and the numbers of vnodes
131  // along each dimension for the partitioning of the index space. Obviously
132  // this restricts the number of vnodes to be a product of the numbers along
133  // each dimension (the constructor implementation checks this):
134  FieldLayout(const Index& i1,
135  e_dim_tag p1,
136  unsigned vnodes1,
137  bool recurse=false,
138  int vnodes=-1);
139  FieldLayout(const Index& i1, const Index& i2,
140  e_dim_tag p1, e_dim_tag p2,
141  unsigned vnodes1, unsigned vnodes2,
142  bool recurse=false,int vnodes=-1);
143  FieldLayout(const Index& i1, const Index& i2, const Index& i3,
144  e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
145  unsigned vnodes1, unsigned vnodes2, unsigned vnodes3,
146  bool recurse=false, int vnodes=-1);
147  FieldLayout(const Index& i1, const Index& i2, const Index& i3,
148  const Index& i4,
149  e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
150  e_dim_tag p4,
151  unsigned vnodes1, unsigned vnodes2, unsigned vnodes3,
152  unsigned vnodes4,
153  bool recurse=false, int vnodes=-1);
154  FieldLayout(const Index& i1, const Index& i2, const Index& i3,
155  const Index& i4, const Index& i5,
156  e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
157  e_dim_tag p4, e_dim_tag p5,
158  unsigned vnodes1, unsigned vnodes2, unsigned vnodes3,
159  unsigned vnodes4, unsigned vnodes5,
160  bool recurse=false, int vnodes=-1);
161  FieldLayout(const Index& i1, const Index& i2, const Index& i3,
162  const Index& i4, const Index& i5, const Index& i6,
163  e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
164  e_dim_tag p4, e_dim_tag p5, e_dim_tag p6,
165  unsigned vnodes1, unsigned vnodes2, unsigned vnodes3,
166  unsigned vnodes4, unsigned vnodes5, unsigned vnodes6,
167  bool recurse=false, int vnodes=-1);
168 
169  // Next we have one for arbitrary dimension.
170  // This one specifies only a total number of vnodes, allowing the constructor
171  // complete control on how to do the vnode partitioning of the index space:
172  FieldLayout(const NDIndex<Dim>& domain, e_dim_tag *p=0, int vnodes=-1) {
173  initialize(domain,p,vnodes);
174  }
175 
176  // This one specifies both the total number of vnodes and the numbers of
177  // vnodes along each dimension for the partitioning of the index
178  // space. Obviously this restricts the number of vnodes to be a product of
179  // the numbers along each dimension (the constructor implementation checks
180  // this):
181  //
182  // The last argument is a bool for the algorithm to use for assigning vnodes
183  // to processors. If it is false, hand the vnodes to the processors in a
184  // very simple but probably inefficient manner. If it is true, use a binary
185  // recursive algorithm. This will usually be more efficient because it will
186  // generate less communication, but it will sometimes fail, particularly
187  // near the case of one vnode per processor. Because this can fail, it is
188  // not the default. This algorithm should only be used when you have 4 or
189  // more vnodes per processor.
190 
191  FieldLayout(const NDIndex<Dim>& domain, e_dim_tag *p,
192  unsigned* vnodesPerDirection,
193  bool recurse=false, int vnodes=-1 ) {
194  initialize(domain,p,vnodesPerDirection,recurse,vnodes);
195  }
196 
197  // Build a FieldLayout given the whole domain and
198  // begin and end iterators for the set of domains for the local Vnodes.
199  // It does a collective computation to find the remote Vnodes.
201  const NDIndex<Dim>* begin, const NDIndex<Dim>* end);
202 
203  // Build a FieldLayout given the whole domain and
204  // begin and end iterators for the set of Vnodes for the local Vnodes.
205  // It does a collective computation to find the remote Vnodes.
206  // This differs from the previous ctor in that it allows preservation of
207  // global Vnode integer ID numbers associated with the input Vnodes. --tjw
209  const Vnode<Dim>* begin, const Vnode<Dim>* end);
210 
211  // Constructor that takes a whole domain, and a pair of iterators over
212  // a list of NDIndex's and nodes so that the user specifies the entire
213  // decomposition. No communication is done
214  // so these lists must match on all nodes. A bit of error checking
215  // is done for overlapping blocks and illegal nodes, but not exhaustive
216  // error checking.
218  const NDIndex<Dim>* dombegin, const NDIndex<Dim>* domend,
219  const int *nbegin, const int *nend);
220 
221  // Destructor: Everything deletes itself automatically ... the base
222  // class destructors inform all the FieldLayoutUser's we're going away.
223  virtual ~FieldLayout();
224 
225  // Initialization functions, only to be called by the user of FieldLayout
226  // objects when the FieldLayout was created using the default constructor;
227  // otherwise these are only called internally by the various non-default
228  // FieldLayout constructors:
229 
230  // These specify only a total number of vnodes, allowing the constructor
231  // complete control on how to do the vnode partitioning of the index space:
232  void initialize(const Index& i1,
233  e_dim_tag p1=PARALLEL, int vnodes=-1);
234  void initialize(const Index& i1, const Index& i2,
235  e_dim_tag p1=PARALLEL, e_dim_tag p2=PARALLEL, int vnodes=-1);
236  void initialize(const Index& i1, const Index& i2, const Index& i3,
238  e_dim_tag p3=PARALLEL, int vnodes=-1);
239  void initialize(const Index& i1, const Index& i2, const Index& i3,
240  const Index& i4,
243  int vnodes=-1);
244  void initialize(const Index& i1, const Index& i2, const Index& i3,
245  const Index& i4, const Index& i5,
248  e_dim_tag p5=PARALLEL,
249  int vnodes=-1);
250  void initialize(const Index& i1, const Index& i2, const Index& i3,
251  const Index& i4, const Index& i5, const Index& i6,
255  int vnodes=-1);
256  void initialize(const NDIndex<Dim>& domain, e_dim_tag *p=0, int vnodes=-1);
257 
258  // These specify both the total number of vnodes and the numbers of vnodes
259  // along each dimension for the partitioning of the index space. Obviously
260  // this restricts the number of vnodes to be a product of the numbers along
261  // each dimension (the constructor implementation checks this):
262  void initialize(const Index& i1,
263  e_dim_tag p1,
264  unsigned vnodes1,
265  bool recurse=false, int vnodes=-1);
266  void initialize(const Index& i1, const Index& i2,
267  e_dim_tag p1, e_dim_tag p2,
268  unsigned vnodes1, unsigned vnodes2,
269  bool recurse=false, int vnodes=-1);
270  void initialize(const Index& i1, const Index& i2, const Index& i3,
271  e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
272  unsigned vnodes1, unsigned vnodes2, unsigned vnodes3,
273  bool recurse=false, int vnodes=-1);
274  void initialize(const Index& i1, const Index& i2, const Index& i3,
275  const Index& i4,
276  e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
277  e_dim_tag p4,
278  unsigned vnodes1, unsigned vnodes2, unsigned vnodes3,
279  unsigned vnodes4,
280  bool recurse=false, int vnodes=-1);
281  void initialize(const Index& i1, const Index& i2, const Index& i3,
282  const Index& i4, const Index& i5,
283  e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
284  e_dim_tag p4, e_dim_tag p5,
285  unsigned vnodes1, unsigned vnodes2, unsigned vnodes3,
286  unsigned vnodes4, unsigned vnodes5,
287  bool recurse=false, int vnodes=-1);
288  void initialize(const Index& i1, const Index& i2, const Index& i3,
289  const Index& i4, const Index& i5, const Index& i6,
290  e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
291  e_dim_tag p4, e_dim_tag p5, e_dim_tag p6,
292  unsigned vnodes1, unsigned vnodes2, unsigned vnodes3,
293  unsigned vnodes4, unsigned vnodes5, unsigned vnodes6,
294  bool recurse=false, int vnodes=-1);
295  void initialize(const NDIndex<Dim>& domain, e_dim_tag *p,
296  unsigned* vnodesPerDirection,
297  bool recurse=false, int vnodes=-1);
298 
299  // Initialize that takes a whole domain, and a pair of iterators over
300  // a list of NDIndex's and nodes so that the user specifies the entire
301  // decomposition. No communication is done
302  // so these lists must match on all nodes. A bit of error checking
303  // is done for overlapping blocks and illegal nodes, but not exhaustive
304  // error checking.
305  void initialize(const NDIndex<Dim>& Domain,
306  const NDIndex<Dim>* dombegin, const NDIndex<Dim>* domend,
307  const int *nbegin, const int *nend);
308 
309  //
310  // FieldLayout operations and information
311  //
312 
313  // Let the user set the local vnodes.
314  // this does everything necessary to realign all the fields
315  // associated with this FieldLayout!
316  // It inputs begin and end iterators for the local vnodes.
317  void Repartition(const NDIndex<Dim>*, const NDIndex<Dim>*);
318  void Repartition(const NDIndex<Dim>& domain) { Repartition(&domain,(&domain)+1); }
319 
320  // This differs from the previous prototype in that it allows preservation of
321  // global Vnode integer ID numbers associated with the input Vnodes. --tjw
322  void Repartition(const Vnode<Dim>*, const Vnode<Dim>*);
323 
324  // Return the domain.
325  const NDIndex<Dim>& getDomain() const { return Domain; }
326 
327 //tjw // Compare FieldLayouts to see if they represent the same domain.
328 //tjw bool operator==(const FieldLayout<Dim>& x) const {
329 //tjw return Domain == x.Domain;
330 //tjw }
331 
332  // Compare FieldLayouts to see if they represent the same domain; if
333  // dimensionalities are different, the NDIndex operator==() will return
334  // false:
335  template <unsigned Dim2>
336  bool operator==(const FieldLayout<Dim2>& x) const {
337  return Domain == x.getDomain();
338  }
339 
340  // Read information from the given file on how to repartition the data.
341  // This works just like it does when constructing a FieldLayout from a
342  // file, in fact this routine is called by the FieldLayout(const char *)
343  // constructor. Only node 0 will actually read the file. Return success.
344  bool read(const char *filename);
345 
346  // Write out info about this layout to the given file. Only node 0 will
347  // actually write a file. Return success.
348  bool write(const char *filename);
349 
350  //
351  // local vnode, remote vnode, touch range, and FieldLayoutUser iterators
352  //
353  int numVnodes(void) const {
354  return (size_iv() + size_rdv());
355  }
356 
357  // Accessors for the locals by Id.
358  typename ac_id_vnodes::size_type size_iv() const;
361  const_iterator_iv begin_iv() const;
362  const_iterator_iv end_iv() const;
363 
364  // Accessors for the remote vnode containers.
365  typename ac_gc_domain_vnodes::size_type size_rgdv() const;
368 
369  // Accessors for the remote vnodes themselves.
371  size_rdv(const GuardCellSizes<Dim>& gc = gc0()) const;
375  const GuardCellSizes<Dim>& gc = gc0()) const;
376 
377  // Accessors for the users accessing this FieldLayout
378  size_type_if size_if() const { return getNumUsers(); }
380  iterator_if end_if() { return end_user(); }
381 
382  //
383  // Query for information about the vnode sizes
384  //
385 
386  // check if the vnode sizes are OK, to match the given GuardCellSizes
387  bool fitsGuardCells(const GuardCellSizes<Dim>& gc) const {
388  for (unsigned int d=0; d < Dim; ++d)
389  if (MinWidth[d] < gc.left(d) || MinWidth[d] < gc.right(d))
390  return false;
391  return true;
392  }
393 
394  // for the requested dimension, report if the distribution is
395  // SERIAL or PARALLEL
396  e_dim_tag getDistribution(unsigned int d) const {
397  e_dim_tag retval = PARALLEL;
398  if (MinWidth[d] == (unsigned int) Domain[d].length())
399  retval = SERIAL;
400  return retval;
401  }
402 
403  // for the requested dimension, report if the distribution was requested to
404  // be SERIAL or PARALLEL
405  e_dim_tag getRequestedDistribution(unsigned int d) const {
406  return RequestedLayout[d];
407  }
408 
409  // When stored, return number of vnodes along a direction:
410  unsigned getVnodesPerDirection(unsigned dir);
411 
412  //
413  // UserList operations
414  //
415 
416  // Return our ID, as generated by UserList.
417  UserList::ID_t get_Id() const { return getUserListID(); }
418 
419  // Tell the FieldLayout that a FieldLayoutUser has been declared on it.
420  // This is different than the checkinUser from UserList,
421  // since we have the GuardCellSizes argument.
422  void checkin(FieldLayoutUser& f, const GuardCellSizes<Dim>& gc = gc0());
423 
424  // Tell the FieldLayout that a FieldLayoutUser is no longer using it.
425  // This is different than the checkoutUser from UserList,
426  // for symmetry with checkin
427  void checkout(FieldLayoutUser& f);
428 
430 
431  //
432  // I/O
433  //
434 
435  // Print it out.
436  void write(std::ostream&) const;
437 
438 private:
439  // Container definitions.
442 
443  // Record the domain.
445 
446  // The minimum width of vnodes in each dimension, and the type of
447  // layout that the user requested (this might not be the case anymore).
448  unsigned int MinWidth[Dim];
450 
451  // Store the numbers of vnodes along each direction, when appropriate
452  // constructors were called; otherwise leave pointer unset for assertion
453  // checks.
455 
456  // calculate the minimum vnode sizes in each dimension
457  void calcWidths();
458 
459  // utility to return a zero-guard cell structure.
460  void new_gc_layout(const GuardCellSizes<Dim>&);
461 
462  // The routine which actually sets things up.
463  void setup(const NDIndex<Dim>&, e_dim_tag *, int);
464  void setup(const NDIndex<Dim>&, e_dim_tag *, unsigned*, bool, int);
465 };
466 
467 
469 
470 // Definitions for the specialized constructors.
471 // Just turn it into a call to the general ctor.
472 
473 //-----------------------------------------------------------------------------
474 // These specify only a total number of vnodes, allowing the constructor
475 // complete control on how to do the vnode partitioning of the index space:
476 
477 template<unsigned Dim>
478 inline
480 {
481  initialize(i1, p1, vnodes);
482 }
483 
484 template<unsigned Dim>
485 inline
487  e_dim_tag p1, e_dim_tag p2, int vnodes)
488 {
489  initialize(i1, i2, p1, p2, vnodes);
490 }
491 
492 template<unsigned Dim>
493 inline
495  const Index& i3,
496  e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
497  int vnodes)
498 {
499  initialize(i1, i2, i3, p1, p2, p3, vnodes);
500 }
501 
502 template<unsigned Dim>
503 inline
505  const Index& i3, const Index& i4,
506  e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
507  e_dim_tag p4,
508  int vnodes)
509 {
510  initialize(i1, i2, i3, i4, p1, p2, p3, p4, vnodes);
511 }
512 
513 template<unsigned Dim>
514 inline
516  const Index& i3, const Index& i4,
517  const Index& i5,
518  e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
519  e_dim_tag p4, e_dim_tag p5,
520  int vnodes)
521 {
522  initialize(i1, i2, i3, i4, i5, p1, p2, p3, p4, p5, vnodes);
523 }
524 
525 template<unsigned Dim>
526 inline
528  const Index& i3, const Index& i4,
529  const Index& i5, const Index& i6,
530  e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
531  e_dim_tag p4, e_dim_tag p5, e_dim_tag p6,
532  int vnodes)
533 {
534  initialize(i1, i2, i3, i4, i5, i6, p1, p2, p3, p4, p5, p6, vnodes);
535 }
536 //-----------------------------------------------------------------------------
537 
538 //-----------------------------------------------------------------------------
539 // These specify both the total number of vnodes and the numbers of vnodes
540 // along each dimension for the partitioning of the index space. Obviously
541 // this restricts the number of vnodes to be a product of the numbers along
542 // each dimension (the constructor implementation checks this):
543 
544 template<unsigned Dim>
545 inline
547  e_dim_tag p1,
548  unsigned vnodes1,
549  bool recurse, int vnodes)
550 {
551  // Default to correct total vnodes:
552  if (vnodes == -1) vnodes = vnodes1;
553  // Verify than total vnodes is product of per-dimension vnode counts:
554  if ((unsigned int) vnodes != vnodes1) {
555  ERRORMSG("FieldLayout constructor: "
556  << "(vnodes1 != vnodes)"
557  << " ; vnodes1 = " << vnodes1
558  << " ; vnodes = " << vnodes << endl);
559  }
560  initialize(i1, p1, vnodes1, recurse,vnodes);
561 }
562 
563 template<unsigned Dim>
564 inline
566  e_dim_tag p1, e_dim_tag p2,
567  unsigned vnodes1, unsigned vnodes2,
568  bool recurse, int vnodes)
569 {
570  // Default to correct total vnodes:
571  if (vnodes == -1) vnodes = vnodes1*vnodes2;
572  // Verify than total vnodes is product of per-dimension vnode counts:
573  if ((unsigned int) vnodes != vnodes1*vnodes2) {
574  ERRORMSG("FieldLayout constructor: "
575  << "(vnodes != vnodes1*vnodes2)"
576  << " ; vnodes1 = " << vnodes1 << " ; vnodes2 = " << vnodes2
577  << " ; vnodes = " << vnodes << endl);
578  }
579  initialize(i1, i2, p1, p2, vnodes1, vnodes2, recurse, vnodes);
580 }
581 
582 template<unsigned Dim>
583 inline
585  const Index& i3,
586  e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
587  unsigned vnodes1, unsigned vnodes2,
588  unsigned vnodes3,
589  bool recurse, int vnodes)
590 {
591  // Default to correct total vnodes:
592  if (vnodes == -1) vnodes = vnodes1*vnodes2*vnodes3;
593  // Verify than total vnodes is product of per-dimension vnode counts:
594  if ((unsigned int) vnodes != vnodes1*vnodes2*vnodes3) {
595  ERRORMSG("FieldLayout constructor: "
596  << "(vnodes != vnodes1*vnodes2*vnodes3)"
597  << " ; vnodes1 = " << vnodes1 << " ; vnodes2 = " << vnodes2
598  << " ; vnodes3 = " << vnodes3
599  << " ; vnodes = " << vnodes << endl);
600  }
601  initialize(i1, i2, i3, p1, p2, p3, vnodes1, vnodes2, vnodes3, recurse, vnodes);
602 }
603 
604 template<unsigned Dim>
605 inline
607  const Index& i3, const Index& i4,
608  e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
609  e_dim_tag p4,
610  unsigned vnodes1, unsigned vnodes2,
611  unsigned vnodes3, unsigned vnodes4,
612  bool recurse, int vnodes)
613 {
614  // Default to correct total vnodes:
615  if (vnodes == -1) vnodes = vnodes1*vnodes2*vnodes3*vnodes4;
616  // Verify than total vnodes is product of per-dimension vnode counts:
617  if ((unsigned int) vnodes != vnodes1*vnodes2*vnodes3*vnodes4) {
618  ERRORMSG("FieldLayout constructor: "
619  << "(vnodes != vnodes1*vnodes2*vnodes3*vnodes4)"
620  << " ; vnodes1 = " << vnodes1 << " ; vnodes2 = " << vnodes2
621  << " ; vnodes3 = " << vnodes3 << " ; vnodes4 = " << vnodes4
622  << " ; vnodes = " << vnodes << endl);
623  }
624  initialize(i1, i2, i3, i4, p1, p2, p3, p4,
625  vnodes1, vnodes2, vnodes3, recurse, vnodes);
626 }
627 
628 template<unsigned Dim>
629 inline
631  const Index& i3, const Index& i4,
632  const Index& i5,
633  e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
634  e_dim_tag p4, e_dim_tag p5,
635  unsigned vnodes1, unsigned vnodes2,
636  unsigned vnodes3, unsigned vnodes4,
637  unsigned vnodes5,
638  bool recurse, int vnodes)
639 {
640  // Default to correct total vnodes:
641  if (vnodes == -1) vnodes = vnodes1*vnodes2*vnodes3*vnodes4*vnodes5;
642  // Verify than total vnodes is product of per-dimension vnode counts:
643  if ((unsigned int) vnodes != vnodes1*vnodes2*vnodes3*vnodes4*vnodes5) {
644  ERRORMSG("FieldLayout constructor: "
645  << "(vnodes != vnodes1*vnodes2*vnodes3*vnodes4*vnodes5)"
646  << " ; vnodes1 = " << vnodes1 << " ; vnodes2 = " << vnodes2
647  << " ; vnodes3 = " << vnodes3 << " ; vnodes4 = " << vnodes4
648  << " ; vnodes5 = " << vnodes5
649  << " ; vnodes = " << vnodes << endl);
650  }
651  initialize(i1, i2, i3, i4, i5, p1, p2, p3, p4, p5,
652  vnodes1, vnodes2, vnodes3, vnodes4, vnodes5, recurse, vnodes);
653 }
654 
655 template<unsigned Dim>
656 inline
658  const Index& i3, const Index& i4,
659  const Index& i5, const Index& i6,
660  e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
661  e_dim_tag p4, e_dim_tag p5, e_dim_tag p6,
662  unsigned vnodes1, unsigned vnodes2,
663  unsigned vnodes3, unsigned vnodes4,
664  unsigned vnodes5, unsigned vnodes6,
665  bool recurse, int vnodes)
666 {
667  // Default to correct total vnodes:
668  if (vnodes == -1) vnodes = vnodes1*vnodes2*vnodes3*vnodes4*vnodes5*vnodes6;
669  // Verify than total vnodes is product of per-dimension vnode counts:
670  if ((unsigned int) vnodes != vnodes1*vnodes2*vnodes3*vnodes4*vnodes5*vnodes6) {
671  ERRORMSG("FieldLayout constructor: "
672  << "(vnodes != vnodes1*vnodes2*vnodes3*vnodes4*vnodes5*vnodes6)"
673  << " ; vnodes1 = " << vnodes1 << " ; vnodes2 = " << vnodes2
674  << " ; vnodes3 = " << vnodes3 << " ; vnodes4 = " << vnodes4
675  << " ; vnodes5 = " << vnodes5 << " ; vnodes6 = " << vnodes6
676  << " ; vnodes = " << vnodes << endl);
677  }
678  initialize(i1, i2, i3, i4, i5, i6, p1, p2, p3, p4, p5, p6,
679  vnodes1, vnodes2, vnodes3, vnodes4, vnodes5, vnodes6, recurse, vnodes);
680 }
681 
682 template<unsigned Dim>
683 inline
685  const NDIndex<Dim> *dombegin,
686  const NDIndex<Dim> *domend,
687  const int *nbegin,
688  const int *nend)
689 {
690  initialize(Domain, dombegin, domend, nbegin, nend);
691 }
692 
693 //-----------------------------------------------------------------------------
694 
695 
697 
698 // Accessor definitions.
699 
700 template<unsigned Dim>
703 {
704  return Local_ac.size();
705 }
706 
707 template<unsigned Dim>
708 inline typename FieldLayout<Dim>::iterator_iv
710 {
711  return Local_ac.begin();
712 }
713 
714 template<unsigned Dim>
715 inline typename FieldLayout<Dim>::iterator_iv
717 {
718  return Local_ac.end();
719 }
720 
721 template<unsigned Dim>
724 {
725  return Local_ac.begin();
726 }
727 
728 template<unsigned Dim>
731 {
732  return Local_ac.end();
733 }
734 
735 template<unsigned Dim>
738 {
739  return Remotes_ac.size();
740 }
741 
742 template<unsigned Dim>
743 inline typename FieldLayout<Dim>::iterator_gdv
745 {
746  return Remotes_ac.begin();
747 }
748 
749 template<unsigned Dim>
750 inline typename FieldLayout<Dim>::iterator_gdv
752 {
753  return Remotes_ac.end();
754 }
755 
756 template<unsigned Dim>
759 {
760  return Remotes_ac[gc]->size();
761 }
762 
763 template<unsigned Dim>
764 inline typename FieldLayout<Dim>::iterator_dv
766 {
767  return Remotes_ac[gc]->begin();
768 }
769 
770 template<unsigned Dim>
771 inline typename FieldLayout<Dim>::iterator_dv
773 {
774  return Remotes_ac[gc]->end();
775 }
776 
777 template<unsigned Dim>
778 inline
781  const GuardCellSizes<Dim>& gc) const
782 {
783  return Remotes_ac[gc]->touch_range(domain);
784 }
785 
786 
787 // I/O
788 
789 template<unsigned Dim>
790 inline
791 std::ostream& operator<<(std::ostream& out, const FieldLayout<Dim>& f) {
792 
793 
794 
795  f.write(out);
796  return out;
797 }
798 
799 
801 
802 #endif // FIELD_LAYOUT_H
803 
804 /***************************************************************************
805  * $RCSfile: FieldLayout.h,v $ $Author: adelmann $
806  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:27 $
807  * IPPL_VERSION_ID: $Id: FieldLayout.h,v 1.1.1.1 2003/01/23 07:40:27 adelmann Exp $
808  ***************************************************************************/
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
const unsigned Dim
std::ostream & operator<<(std::ostream &, const FieldLayout< Dim > &)
Definition: FieldLayout.h:791
e_dim_tag
Definition: FieldLayout.h:55
@ PARALLEL
Definition: FieldLayout.h:55
@ SERIAL
Definition: FieldLayout.h:55
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
unsigned size_type
Definition: DomainMap.h:75
iterator_iv end_iv()
Definition: FieldLayout.h:716
void Repartition(const NDIndex< Dim > &domain)
Definition: FieldLayout.h:318
bool write(const char *filename)
NDIndex< Dim > Domain
Definition: FieldLayout.h:444
touch_range_dv touch_range_rdv(const NDIndex< Dim > &domain, const GuardCellSizes< Dim > &gc=gc0()) const
Definition: FieldLayout.h:780
const NDIndex< Dim > & getDomain() const
Definition: FieldLayout.h:325
iterator_dv begin_rdv(const GuardCellSizes< Dim > &gc=gc0())
Definition: FieldLayout.h:765
UserList::ID_t get_Id() const
Definition: FieldLayout.h:417
void new_gc_layout(const GuardCellSizes< Dim > &)
int numVnodes(void) const
Definition: FieldLayout.h:353
FieldLayout(const NDIndex< Dim > &domain, e_dim_tag *p=0, int vnodes=-1)
Definition: FieldLayout.h:172
static GuardCellSizes< Dim > gc0()
Definition: FieldLayout.h:84
void Repartition(const NDIndex< Dim > *, const NDIndex< Dim > *)
bool read(const char *filename)
iterator_if begin_if()
Definition: FieldLayout.h:379
NDIndex< Dim > getLocalNDIndex()
bool fitsGuardCells(const GuardCellSizes< Dim > &gc) const
Definition: FieldLayout.h:387
iterator_gdv begin_rgdv()
Definition: FieldLayout.h:744
ac_gc_domain_vnodes Remotes_ac
Definition: FieldLayout.h:441
void checkout(FieldLayoutUser &f)
unsigned getVnodesPerDirection(unsigned dir)
ac_domain_vnodes::iterator iterator_dv
Definition: FieldLayout.h:75
iterator_dv end_rdv(const GuardCellSizes< Dim > &gc=gc0())
Definition: FieldLayout.h:772
ac_gc_domain_vnodes::iterator iterator_gdv
Definition: FieldLayout.h:78
void calcWidths()
ac_id_vnodes::const_iterator const_iterator_iv
Definition: FieldLayout.h:74
e_dim_tag RequestedLayout[Dim]
Definition: FieldLayout.h:449
virtual ~FieldLayout()
Definition: FieldLayout.hpp:90
ac_gc_domain_vnodes::size_type size_rgdv() const
Definition: FieldLayout.h:737
ac_domain_vnodes::touch_iterator touch_iterator_dv
Definition: FieldLayout.h:76
FieldLayout(const NDIndex< Dim > &domain, e_dim_tag *p, unsigned *vnodesPerDirection, bool recurse=false, int vnodes=-1)
Definition: FieldLayout.h:191
unsigned * vnodesPerDirection_m
Definition: FieldLayout.h:454
DomainMap< NDIndex< Dim >, RefCountedP< Vnode< Dim > >, Touches< Dim >, Contains< Dim >, Split< Dim > > ac_domain_vnodes
Definition: FieldLayout.h:68
unsigned int MinWidth[Dim]
Definition: FieldLayout.h:448
std::pair< touch_iterator_dv, touch_iterator_dv > touch_range_dv
Definition: FieldLayout.h:77
void initialize(const Index &i1, e_dim_tag p1=PARALLEL, int vnodes=-1)
size_type_if size_if() const
Definition: FieldLayout.h:378
ac_id_vnodes Local_ac
Definition: FieldLayout.h:440
void setup(const NDIndex< Dim > &, e_dim_tag *, int)
ac_id_vnodes::size_type size_iv() const
Definition: FieldLayout.h:702
iterator_if end_if()
Definition: FieldLayout.h:380
iterator_user iterator_if
Definition: FieldLayout.h:79
void checkin(FieldLayoutUser &f, const GuardCellSizes< Dim > &gc=gc0())
vmap< GuardCellSizes< Dim >, my_auto_ptr< ac_domain_vnodes > > ac_gc_domain_vnodes
Definition: FieldLayout.h:70
iterator_gdv end_rgdv()
Definition: FieldLayout.h:751
vmap< Unique::type, my_auto_ptr< Vnode< Dim > > > ac_id_vnodes
Definition: FieldLayout.h:66
ac_id_vnodes::iterator iterator_iv
Definition: FieldLayout.h:73
e_dim_tag getRequestedDistribution(unsigned int d) const
Definition: FieldLayout.h:405
ac_domain_vnodes::size_type size_rdv(const GuardCellSizes< Dim > &gc=gc0()) const
Definition: FieldLayout.h:758
size_type_user size_type_if
Definition: FieldLayout.h:80
iterator_iv begin_iv()
Definition: FieldLayout.h:709
e_dim_tag getDistribution(unsigned int d) const
Definition: FieldLayout.h:396
bool operator==(const FieldLayout< Dim2 > &x) const
Definition: FieldLayout.h:336
unsigned left(unsigned d) const
unsigned right(unsigned d) const
Definition: Vnode.h:38
Definition: Index.h:237
Definition: NDIndex.h:284
iterator_user begin_user()
Definition: UserList.cpp:77
ID_t getUserListID() const
Definition: UserList.cpp:54
UserList_t::iterator iterator_user
Definition: UserList.h:43
iterator_user end_user()
Definition: UserList.cpp:84
User::ID_t ID_t
Definition: UserList.h:46
size_type_user getNumUsers() const
Definition: UserList.cpp:47
UserList_t::size_type size_type_user
Definition: UserList.h:45
Definition: vmap.h:59
rep_type::const_iterator const_iterator
Definition: vmap.h:99