OPAL (Object Oriented Parallel Accelerator Library) 2022.1
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"
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
50template <unsigned Dim> class FieldLayout;
51template <unsigned Dim>
52std::ostream& operator<<(std::ostream&, const FieldLayout<Dim>&);
53
54// enumeration used to select serial or parallel axes
55enum 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
60template<unsigned Dim>
61class FieldLayout : private UserList
62{
63
64public:
65 // Typedefs for containers.
71
72 // Typedefs for iterators.
77 typedef std::pair<touch_iterator_dv,touch_iterator_dv> touch_range_dv;
81
82private:
83 // utility to return a zero-guard cell structure.
85
86public:
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)
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,
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
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,
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;
363
364 // Accessors for the remote vnode containers.
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(); }
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
438private:
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.
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
477template<unsigned Dim>
478inline
480{
481 initialize(i1, p1, vnodes);
482}
483
484template<unsigned Dim>
485inline
487 e_dim_tag p1, e_dim_tag p2, int vnodes)
488{
489 initialize(i1, i2, p1, p2, vnodes);
490}
491
492template<unsigned Dim>
493inline
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
502template<unsigned Dim>
503inline
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
513template<unsigned Dim>
514inline
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
525template<unsigned Dim>
526inline
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
544template<unsigned Dim>
545inline
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
563template<unsigned Dim>
564inline
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
582template<unsigned Dim>
583inline
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
604template<unsigned Dim>
605inline
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
628template<unsigned Dim>
629inline
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
655template<unsigned Dim>
656inline
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
682template<unsigned Dim>
683inline
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
700template<unsigned Dim>
703{
704 return Local_ac.size();
705}
706
707template<unsigned Dim>
708inline typename FieldLayout<Dim>::iterator_iv
710{
711 return Local_ac.begin();
712}
713
714template<unsigned Dim>
715inline typename FieldLayout<Dim>::iterator_iv
717{
718 return Local_ac.end();
719}
720
721template<unsigned Dim>
724{
725 return Local_ac.begin();
726}
727
728template<unsigned Dim>
731{
732 return Local_ac.end();
733}
734
735template<unsigned Dim>
738{
739 return Remotes_ac.size();
740}
741
742template<unsigned Dim>
743inline typename FieldLayout<Dim>::iterator_gdv
745{
746 return Remotes_ac.begin();
747}
748
749template<unsigned Dim>
750inline typename FieldLayout<Dim>::iterator_gdv
752{
753 return Remotes_ac.end();
754}
755
756template<unsigned Dim>
759{
760 return Remotes_ac[gc]->size();
761}
762
763template<unsigned Dim>
764inline typename FieldLayout<Dim>::iterator_dv
766{
767 return Remotes_ac[gc]->begin();
768}
769
770template<unsigned Dim>
771inline typename FieldLayout<Dim>::iterator_dv
773{
774 return Remotes_ac[gc]->end();
775}
776
777template<unsigned Dim>
778inline
781 const GuardCellSizes<Dim>& gc) const
782{
783 return Remotes_ac[gc]->touch_range(domain);
784}
785
786
787// I/O
788
789template<unsigned Dim>
790inline
791std::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
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
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
static GuardCellSizes< Dim > gc0()
Definition: FieldLayout.h:84
const NDIndex< Dim > & getDomain() const
Definition: FieldLayout.h:325
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