Chombo + EB  3.2
Copier.H
Go to the documentation of this file.
1 #ifdef CH_LANG_CC
2 /*
3  * _______ __
4  * / ___/ / ___ __ _ / / ___
5  * / /__/ _ \/ _ \/ V \/ _ \/ _ \
6  * \___/_//_/\___/_/_/_/_.__/\___/
7  * Please refer to Copyright.txt, in Chombo's root directory.
8  */
9 #endif
10 
11 #ifndef _COPIER_H_
12 #define _COPIER_H_
13 
14 #include "DisjointBoxLayout.H"
15 #include "Pool.H"
16 #include "Vector.H"
17 #include "ProblemDomain.H"
18 #include <unordered_map>
19 #include <cstdint>
20 #include "NamespaceHeader.H"
21 
22 
23 typedef std::unordered_map<uint64_t, LayoutIndex> LMap;
24 
25 
26 class CopyIterator;
27 
28 // These classes are public because I can't find a nice
29 // way to make a class a friend of all the instantiations
30 // of a template class. These classes are not part of
31 // the public interface for the Array API.
32 //
33 // Later, if MotionItem shows up in the profiler, we
34 // can start using a pool allocation scheme and placement new
35 
37 {
38 public:
42  int procID;
43  // this constructor will probably eventually go away
44  MotionItem(const DataIndex& a_from,
45  const DataIndex& a_to,
46  const Box& a_region);
47  MotionItem(const DataIndex& a_from,
48  const DataIndex& a_to,
49  const Box& a_fromRegion,
50  const Box& a_toRegion);
51  void reverse();
52 
53  bool operator==(const MotionItem& rhs)
54  { return fromIndex == rhs.fromIndex && toIndex == rhs.toIndex &&
55  fromRegion == rhs.fromRegion && toRegion == rhs.toRegion &&
56  procID == rhs.procID;}
57 };
58 
60 {
61 public:
62 
63  ///null constructor, copy constructor and operator= can be compiler defined.
65  m_recbuffer(NULL), m_reccapacity(0)
66  {}
67 
68  ///
69  virtual ~CopierBuffer();
70 
71  void clear();
72 
73  bool isDefined(int ncomps) const
74  { return ncomps == m_ncomps;}
75 
76  mutable int m_ncomps;
77 
78  mutable void* m_sendbuffer; // pointer member OK here,
79  // since LevelData<T> has no copy
80  mutable size_t m_sendcapacity;
81  mutable void* m_recbuffer; // pointer member OK here,
82  // since LevelData<T> has no copy
83  mutable size_t m_reccapacity;
84 
85 #ifndef DOXYGEN
86 
87  struct bufEntry
88  {
89  void* bufPtr; // pointer into contiguous m_buffer
90  size_t size;
91  const MotionItem* item;
92  unsigned int procID;
93  bool operator < (const bufEntry& rhs) const
94  {
95  if (procID == rhs.procID)
96  {
97  const Box& left = item->toRegion;
98  const Box& right= rhs.item->toRegion;
99  if (left.smallEnd() == right.smallEnd())
100  {
101  return left.bigEnd().lexLT(right.bigEnd());
102  }
103  else
104  {
105  return item->toRegion < rhs.item->toRegion;
106  }
107  }
108  //else
109  return procID < rhs.procID;
110  }
111  };
112 
113 #endif
114  mutable std::vector<bufEntry> m_fromMe;
115  mutable std::vector<bufEntry> m_toMe;
116  mutable std::vector<std::vector<bufEntry> > m_toMeUnpack;
117 
118 
119 protected:
120 
121 };
122 
123 /// A strange but true thing to make copying from one boxlayoutdata to another fast
124 /**
125  class to handle the organization of data from a LevelData to a BoxLayoutData
126  defined over the same index space. The idea behind this object
127  is twofold:
128  A) there is a significant amount of information that can be
129  computed once and reused from one copy to the next for
130  a LevelData and BoxLayoutData that have unchanging BoxLayouts
131  underneath them. In these cases, LevelData::copyTo methods
132  has an optional argument. That way, in cases where the operation
133  is only performed a single time, we do not waste our time building
134  optimizing data, etc.
135  B) when we interface with KeLP, this class maps quite well
136  with the existing KeLP API (class MotionPlan).
137 
138  pains have been taken to not have this class be templated. Thus
139  it does not actually perform the copying itself (which would require
140  knowledge of the template class type). It provides an iterator
141  interface to MotionItems that specify the required work. LevelData
142  provides the copyTo methods.
143 */
144 
145 class Copier
146 {
147 public:
148 
149  ///null constructor, copy constructor and operator= can be compiler defined.
151  {}
152 
153  Copier(const Copier& a_rhs);
154 
155  ///
156  Copier(const DisjointBoxLayout& a_level,
157  const BoxLayout& a_dest,
158  bool a_exchange = false,
159  IntVect a_shift = IntVect::Zero);
160 
161  /// this constructor contains support for periodic BC's
162  Copier(const DisjointBoxLayout& a_level,
163  const BoxLayout& a_dest,
164  const ProblemDomain& a_domain,
165  bool a_exchange = false,
166  IntVect a_shift = IntVect::Zero);
167 
168  /// Copier to copy data into the valid and invalid regions of a_dest from a_level
169  Copier(const DisjointBoxLayout& a_level,
170  const BoxLayout& a_dest,
171  const IntVect& a_destGhost,
172  bool a_exchange = false,
173  IntVect a_shift = IntVect::Zero);
174 
175  /// Copier to copy data into the valid and invalid regions of a_dest from a_level with support for periodic BCs
176  Copier(const DisjointBoxLayout& a_level,
177  const BoxLayout& a_dest,
178  const ProblemDomain& a_domain,
179  const IntVect& a_destGhost,
180  bool a_exchange = false,
181  IntVect a_shift = IntVect::Zero);
182 
183  ///
184  virtual ~Copier();
185 
186  ///
187  virtual void define(const DisjointBoxLayout& a_level,
188  const BoxLayout& a_dest,
189  bool a_exchange = false,
190  IntVect a_shift = IntVect::Zero);
191 
192  /// contains support for periodic BCs
193  virtual void define(const DisjointBoxLayout& a_level,
194  const BoxLayout& a_dest,
195  const ProblemDomain& a_domain,
196  bool a_exchange = false,
197  IntVect a_shift = IntVect::Zero);
198 
199  ///
200  virtual void define(const DisjointBoxLayout& a_level,
201  const BoxLayout& a_dest,
202  const IntVect& a_destGhost,
203  bool a_exchange = false,
204  IntVect a_shift = IntVect::Zero);
205 
206  /// contains support for periodic BCs
207  virtual void define(const BoxLayout& a_level,
208  const BoxLayout& a_dest,
209  const ProblemDomain& a_domain,
210  const IntVect& a_destGhost,
211  bool a_exchange = false,
212  IntVect a_shift = IntVect::Zero);
213 
214  /// alternative version of define for exchange copiers that uses new optimized neighborIterator
215  virtual void exchangeDefine(const DisjointBoxLayout& a_grids,
216  const IntVect& a_ghost,
217  bool a_includeSelf=false);
218 
219  void defineFixedBoxSize(const DisjointBoxLayout& a_src,
220  const LMap& a_lmap,
221  const IntVect& a_ghost,
222  const ProblemDomain& a_domain,
223  bool a_includeSelf=false,
224  bool a_reverse=false);
225 
226  void defineFixedSizeNodesCollect(const DisjointBoxLayout& a_layout,
227  const LMap& a_lmap,
228  const IntVect& a_ghostSrc,
229  const IntVect& a_ghostDst,
230  const ProblemDomain& a_domain);
231 
232  /// performs the computation necessary for moving from ghost+valid cells to all valid cells in a_dest
233  /** instead of copying from the valid of a_src to the valid+ghost of a_dest,
234  this routine defines a Copier that moves data from the ghost+valid region
235  of a_src to a_dest. This is used by LevelFluxRegister.
236  */
237  void ghostDefine(const DisjointBoxLayout& a_src,
238  const DisjointBoxLayout& a_dest,
239  const ProblemDomain& a_domain,
240  const IntVect& a_srcGhost);
241 
242  /// performs the computation necessary for moving from ghost+valid cells to all valid+ghost cells in a_dest
243  /** instead of copying from the valid of a_src to the valid+ghost of a_dest,
244  this routine defines a Copier that moves data from the ghost+valid region
245  of a_src to valid+ghost a_dest. This is used by BlockBaseRegister. Note that this does not handle
246  periodic matchings here. That is handled by different code in the MappedMultiBlock libraries.
247  Sending in a null-constructed ProblemDomain just results in a computation that ignores domain boundaries.
248  */
249  void ghostDefine(const DisjointBoxLayout& a_src,
250  const DisjointBoxLayout& a_dest,
251  const ProblemDomain& a_domain,
252  const IntVect& a_srcGhost,
253  const IntVect& a_destGhost);
254 
255  ///
256  virtual void clear();
257 
258  ///
259  /**
260  The assignment operator.
261 
262  */
263  Copier& operator= (const Copier& b);
264 
265  ///
266  /**
267  reverse the communication of this Copier.
268  */
269  void reverse();
270 
271  ///
272  /**
273  Under the right algorithmic circumstances, a user might know that they no not
274  need corner cells filled in exchanges, what they really need are just sufficient
275  ghost cells in each CH_SPACEDIM direction for each valid cell. This operation
276  eliminates copy operations that do not contribute to such cells. Under reasonable
277  3D configurations this can eliminate more than half the copy operations.
278  */
279  void trimEdges(const DisjointBoxLayout& a_exchangedLayout, const IntVect& ghost);
280 
281  ///
282  /*
283  OK, if you *really* know what you are doing (!) you can coarsen a Copier in place of
284  building a new Copier on a coarsened DisjointBoxLayout. The trick is when you do have
285  ghost cells and working out on paper for yourself that the coarsening is valid. One
286  common configuration is an exchange Copier with *one* ghost cell. A particular
287  case where coarsen will do the *wrong* thing is an exchange Copier with more than one
288  ghost cell.
289  **/
290  void coarsen(int a_refRatio);
291 
292  ///
293  /* check equality of two Copiers. Full check of every MotionItem
294  */
295  bool operator==(const Copier& rhs) const;
296 
297  int print() const;
298 
299  bool bufferAllocated() const;
300  void setBufferAllocated(bool arg) const;
301 
302  int numLocalCellsToCopy() const;
303  int numFromCellsToCopy() const;
304  int numToCellsToCopy() const;
305 
306  bool isDefined() const
307  { return m_isDefined;}
308 
310 
311  std::vector<IndexTM<int,2> > m_range;
312 protected:
313 
314  friend class CopyIterator;
315 
316 
320 
321  friend void dumpmemoryatexit();
323  mutable bool buffersAllocated;
324 
325  // keep a refcounted reference around for debugging purposes, we can
326  // decide afterwards if we want to eliminate it.
329 
331 
332  void trimMotion(const DisjointBoxLayout& a_exchangedLayout, const IntVect& a_ghost,
333  const Vector<MotionItem*>& a_oldItems, Vector<MotionItem*>& a_newItems);
334 
335  void sort();
336 
337  // sneaky end-around to problem of getting physDomains in derived classes
338  const ProblemDomain& getPhysDomain(const DisjointBoxLayout& a_level) const;
339 };
340 
341 std::ostream& operator<<(std::ostream& os, const Copier& copier);
342 
343 //===========================================================================
344 // end of public interface for Copier.
345 //===========================================================================
346 
347 inline MotionItem::MotionItem(const DataIndex& a_from,
348  const DataIndex& a_to,
349  const Box& a_region)
350  :fromIndex(a_from), toIndex(a_to), fromRegion(a_region),
351  toRegion(a_region), procID(-1)
352 {
353 }
354 
355 inline MotionItem::MotionItem(const DataIndex& a_from,
356  const DataIndex& a_to,
357  const Box& a_fromRegion,
358  const Box& a_toRegion)
359  :fromIndex(a_from), toIndex(a_to), fromRegion(a_fromRegion),
360  toRegion(a_toRegion), procID(-1)
361 {
362 }
363 
364 inline
366 {
367  Box tmp(fromRegion);
369  toRegion=tmp;
370  DataIndex tmpIndex(fromIndex);
371  fromIndex = toIndex;
372  toIndex = tmpIndex;
373 }
374 
376 {
377 public:
379  {
383  };
384 
385  inline CopyIterator(const Copier& a_copier, local_from_to);
386 
387  inline const MotionItem& operator()() const;
388 
389  inline const MotionItem& operator[](size_t index) const;
390 
391  inline void operator++();
392 
393  inline bool ok() const;
394 
395  inline void reset();
396 
397  inline size_t size(){ return m_motionplanPtr->size();}
398 
399 private:
401  unsigned int m_current;
402 };
403 
404 //====== inlined functions====================================
405 
406 inline CopyIterator::CopyIterator(const Copier& a_copier, local_from_to type)
407  :m_current(0)
408 {
409  switch(type)
410  {
411  case LOCAL:
412  m_motionplanPtr = &(a_copier.m_localMotionPlan);
413  break;
414  case FROM:
415  m_motionplanPtr = &(a_copier.m_fromMotionPlan);
416  break;
417  case TO:
418  m_motionplanPtr = &(a_copier.m_toMotionPlan);
419  break;
420  default:
421  MayDay::Error("illegal local_from_to option for CopyIterator");
422  }
423 }
424 
426 {
427  CH_assert(m_current < m_motionplanPtr->size());
428  return *(m_motionplanPtr->operator[](m_current));
429 }
430 
431 inline const MotionItem& CopyIterator::operator[](size_t a_index) const
432 {
433  CH_assert(a_index < m_motionplanPtr->size());
434  return *(m_motionplanPtr->operator[](a_index));
435 }
436 
438 {
439  ++m_current;
440 }
441 
442 inline bool CopyIterator::ok() const
443 {
444  return m_current < m_motionplanPtr->size();
445 }
446 
447 inline void CopyIterator::reset()
448 {
449  m_current = 0;
450 }
451 
452 #include "NamespaceFooter.H"
453 #endif
void ghostDefine(const DisjointBoxLayout &a_src, const DisjointBoxLayout &a_dest, const ProblemDomain &a_domain, const IntVect &a_srcGhost)
performs the computation necessary for moving from ghost+valid cells to all valid cells in a_dest ...
std::vector< IndexTM< int, 2 > > m_range
Definition: Copier.H:311
int numLocalCellsToCopy() const
void sort()
void reset()
Definition: Copier.H:447
#define CH_assert(cond)
Definition: CHArray.H:37
A class to facilitate interaction with physical boundary conditions.
Definition: ProblemDomain.H:141
CopierBuffer m_buffers
Definition: Copier.H:309
Vector< MotionItem * > m_fromMotionPlan
Definition: Copier.H:318
int m_ncomps
Definition: Copier.H:76
bool bufferAllocated() const
virtual void exchangeDefine(const DisjointBoxLayout &a_grids, const IntVect &a_ghost, bool a_includeSelf=false)
alternative version of define for exchange copiers that uses new optimized neighborIterator ...
std::unordered_map< uint64_t, LayoutIndex > LMap
Definition: Copier.H:23
void defineFixedBoxSize(const DisjointBoxLayout &a_src, const LMap &a_lmap, const IntVect &a_ghost, const ProblemDomain &a_domain, bool a_includeSelf=false, bool a_reverse=false)
A not-necessarily-disjoint collective of boxes.
Definition: BoxLayout.H:145
void reverse()
A strange but true thing to make copying from one boxlayoutdata to another fast.
Definition: Copier.H:145
std::ostream & operator<<(std::ostream &os, const Copier &copier)
std::vector< std::vector< bufEntry > > m_toMeUnpack
Definition: Copier.H:116
void defineFixedSizeNodesCollect(const DisjointBoxLayout &a_layout, const LMap &a_lmap, const IntVect &a_ghostSrc, const IntVect &a_ghostDst, const ProblemDomain &a_domain)
std::vector< bufEntry > m_fromMe
Definition: Copier.H:114
DisjointBoxLayout m_originPlan
Definition: Copier.H:327
Definition: Copier.H:381
bool m_isDefined
Definition: Copier.H:330
const MotionItem & operator()() const
Definition: Copier.H:425
Definition: Copier.H:59
size_t m_sendcapacity
Definition: Copier.H:80
bool isDefined(int ncomps) const
Definition: Copier.H:73
size_t size()
Definition: Copier.H:397
void reverse()
Definition: Copier.H:365
static Pool s_motionItemPool
Definition: Copier.H:322
Definition: Copier.H:382
Definition: Copier.H:36
bool operator==(const Copier &rhs) const
int procID
Definition: Copier.H:42
DataIndex toIndex
Definition: Copier.H:39
BoxLayout m_dest
Definition: Copier.H:328
Vector< MotionItem * > m_toMotionPlan
Definition: Copier.H:319
size_t m_reccapacity
Definition: Copier.H:83
void * m_recbuffer
Definition: Copier.H:81
MotionItem(const DataIndex &a_from, const DataIndex &a_to, const Box &a_region)
Definition: Copier.H:347
void coarsen(int a_refRatio)
void * m_sendbuffer
Definition: Copier.H:78
int numToCellsToCopy() const
void trimMotion(const DisjointBoxLayout &a_exchangedLayout, const IntVect &a_ghost, const Vector< MotionItem * > &a_oldItems, Vector< MotionItem * > &a_newItems)
bool operator<(const FaceIndex &f1, const FaceIndex &f2)
Definition: FaceIndex.H:212
const IntVect & bigEnd() const
Definition: Box.H:1768
Pool is a class to optimize memory allocation.
Definition: Pool.H:63
bool lexLT(const IntVect &s) const
Definition: IntVect.H:889
bool buffersAllocated
Definition: Copier.H:323
A BoxLayout that has a concept of disjointedness.
Definition: DisjointBoxLayout.H:30
CopierBuffer()
null constructor, copy constructor and operator= can be compiler defined.
Definition: Copier.H:64
Vector< MotionItem * > m_localMotionPlan
Definition: Copier.H:317
const ProblemDomain & getPhysDomain(const DisjointBoxLayout &a_level) const
Box toRegion
Definition: Copier.H:41
static void Error(const char *const a_msg=m_nullString, int m_exitCode=CH_DEFAULT_ERROR_CODE)
Print out message to cerr and exit with the specified exit code.
unsigned int m_current
Definition: Copier.H:401
void operator++()
Definition: Copier.H:437
void trimEdges(const DisjointBoxLayout &a_exchangedLayout, const IntVect &ghost)
static const IntVect Zero
Definition: IntVect.H:654
int numFromCellsToCopy() const
A Rectangular Domain on an Integer Lattice.
Definition: Box.H:465
Copier & operator=(const Copier &b)
Definition: DataIndex.H:112
bool ok() const
Definition: Copier.H:442
const MotionItem & operator[](size_t index) const
Definition: Copier.H:431
Copier()
null constructor, copy constructor and operator= can be compiler defined.
Definition: Copier.H:150
void setBufferAllocated(bool arg) const
local_from_to
Definition: Copier.H:378
An integer Vector in SpaceDim-dimensional space.
Definition: CHArray.H:42
virtual ~CopierBuffer()
size_t size() const
Definition: Vector.H:192
virtual void clear()
virtual ~Copier()
Definition: Copier.H:380
friend void dumpmemoryatexit()
bool isDefined() const
Definition: Copier.H:306
virtual void define(const DisjointBoxLayout &a_level, const BoxLayout &a_dest, bool a_exchange=false, IntVect a_shift=IntVect::Zero)
const Vector< MotionItem * > * m_motionplanPtr
Definition: Copier.H:400
DataIndex fromIndex
Definition: Copier.H:39
bool operator==(const MotionItem &rhs)
Definition: Copier.H:53
int print() const
const IntVect & smallEnd() const
{ Accessors}
Definition: Box.H:1754
int procID()
local process ID
Box fromRegion
Definition: Copier.H:40
CopyIterator(const Copier &a_copier, local_from_to)
Definition: Copier.H:406
std::vector< bufEntry > m_toMe
Definition: Copier.H:115
Definition: Copier.H:375