Legion Runtime
legion_domain.h
Go to the documentation of this file.
1 /* Copyright 2024 Stanford University, NVIDIA Corporation
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef __LEGION_DOMAIN_H__
17 #define __LEGION_DOMAIN_H__
18 
19 #include "realm.h"
20 #include "legion/legion_types.h"
21 
29 namespace Legion {
30 
31  template<int DIM, typename T = coord_t>
32  using Point = Realm::Point<DIM,T>;
33  template<int DIM, typename T = coord_t>
34  using Rect = Realm::Rect<DIM,T>;
35  template<int M, int N, typename T = coord_t>
36  using Transform = Realm::Matrix<M,N,T>;
37 
45  template<int M, int N, typename T = coord_t>
46  struct AffineTransform {
47  private:
48  static_assert(M > 0, "M must be positive");
49  static_assert(N > 0, "N must be positive");
50  static_assert(std::is_integral<T>::value, "must be integral type");
51  public:
52  __CUDA_HD__
53  AffineTransform(void); // default to identity transform
54  // allow type coercions where possible
55  template<typename T2> __CUDA_HD__
57  template<typename T2, typename T3> __CUDA_HD__
58  AffineTransform(const Transform<M,N,T2> transform,
59  const Point<M,T3> offset);
60  public:
61  template<typename T2> __CUDA_HD__
62  AffineTransform<M,N,T>& operator=(const AffineTransform<M,N,T2> &rhs);
63  public:
64  // Apply the transformation to a point
65  template<typename T2> __CUDA_HD__
66  Point<M,T> operator[](const Point<N,T2> point) const;
67  // Compose the transform with another transform
68  template<int P> __CUDA_HD__
69  AffineTransform<M,P,T> operator()(const AffineTransform<N,P,T> &rhs) const;
70  // Test whether this is the identity transform
71  __CUDA_HD__
72  bool is_identity(void) const;
73  public:
74  // Transform = Ax + b
75  Transform<M,N,T> transform; // A
76  Point<M,T> offset; // b
77  };
78 
91  template<int M, int N, typename T = coord_t>
92  struct ScaleTransform {
93  private:
94  static_assert(M > 0, "M must be positive");
95  static_assert(M > 0, "N must be positive");
96  static_assert(std::is_integral<T>::value, "must be integral type");
97  public:
98  __CUDA_HD__
99  ScaleTransform(void); // default to identity transform
100  // allow type coercions where possible
101  template<typename T2> __CUDA_HD__
103  template<typename T2, typename T3, typename T4> __CUDA_HD__
104  ScaleTransform(const Transform<M,N,T2> transform,
105  const Rect<M,T3> extent,
106  const Point<M,T4> divisor);
107  public:
108  template<typename T2> __CUDA_HD__
109  ScaleTransform<M,N,T>& operator=(const ScaleTransform<M,N,T2> &rhs);
110  public:
111  // Apply the transformation to a point
112  template<typename T2> __CUDA_HD__
113  Rect<M,T> operator[](const Point<N,T2> point) const;
114  // Test whether this is the identity transform
115  __CUDA_HD__
116  bool is_identity(void) const;
117  public:
118  Transform<M,N,T> transform; // A
119  Rect<M,T> extent; // [b=lo, c=hi]
120  Point<M,T> divisor; // d
121  };
122 
123  // If we've got c++11 we can just include this directly
124  template<int DIM, typename T = coord_t>
125  using DomainT = Realm::IndexSpace<DIM,T>;
126 
132  class DomainPoint {
133  public:
134  static constexpr int MAX_POINT_DIM = LEGION_MAX_DIM;
135 
136  __CUDA_HD__
137  DomainPoint(void);
138  __CUDA_HD__
139  DomainPoint(coord_t index);
140  __CUDA_HD__
141  DomainPoint(const DomainPoint &rhs);
142  template<int DIM, typename T> __CUDA_HD__
143  DomainPoint(const Point<DIM,T> &rhs);
144 
145  template<int DIM, typename T> __CUDA_HD__
146  operator Point<DIM,T>(void) const;
147 
148  __CUDA_HD__
149  DomainPoint& operator=(const DomainPoint &rhs);
150  template<int DIM, typename T> __CUDA_HD__
151  DomainPoint& operator=(const Point<DIM,T> &rhs);
152  __CUDA_HD__
153  bool operator==(const DomainPoint &rhs) const;
154  __CUDA_HD__
155  bool operator!=(const DomainPoint &rhs) const;
156  __CUDA_HD__
157  bool operator<(const DomainPoint &rhs) const;
158 
159  __CUDA_HD__
160  DomainPoint operator+(coord_t scalar) const;
161  __CUDA_HD__
162  DomainPoint operator+(const DomainPoint &rhs) const;
163  __CUDA_HD__
164  DomainPoint& operator+=(coord_t scalar);
165  __CUDA_HD__
166  DomainPoint& operator+=(const DomainPoint &rhs);
167 
168  __CUDA_HD__
169  DomainPoint operator-(coord_t scalar) const;
170  __CUDA_HD__
171  DomainPoint operator-(const DomainPoint &rhs) const;
172  __CUDA_HD__
173  DomainPoint& operator-=(coord_t scalar);
174  __CUDA_HD__
175  DomainPoint& operator-=(const DomainPoint &rhs);
176 
177  __CUDA_HD__
178  DomainPoint operator*(coord_t scalar) const;
179  __CUDA_HD__
180  DomainPoint operator*(const DomainPoint &rhs) const;
181  __CUDA_HD__
182  DomainPoint& operator*=(coord_t scalar);
183  __CUDA_HD__
184  DomainPoint& operator*=(const DomainPoint &rhs);
185 
186  __CUDA_HD__
187  DomainPoint operator/(coord_t scalar) const;
188  __CUDA_HD__
189  DomainPoint operator/(const DomainPoint &rhs) const;
190  __CUDA_HD__
191  DomainPoint& operator/=(coord_t scalar);
192  __CUDA_HD__
193  DomainPoint& operator/=(const DomainPoint &rhs);
194 
195  __CUDA_HD__
196  DomainPoint operator%(coord_t scalar) const;
197  __CUDA_HD__
198  DomainPoint operator%(const DomainPoint &rhs) const;
199  __CUDA_HD__
200  DomainPoint& operator%=(coord_t scalar);
201  __CUDA_HD__
202  DomainPoint& operator%=(const DomainPoint &rhs);
203 
204  __CUDA_HD__
205  coord_t& operator[](unsigned index);
206  __CUDA_HD__
207  const coord_t& operator[](unsigned index) const;
208 
209  struct STLComparator {
210  __CUDA_HD__
211  bool operator()(const DomainPoint& a, const DomainPoint& b) const
212  {
213  if(a.dim < b.dim) return true;
214  if(a.dim > b.dim) return false;
215  for(int i = 0; (i == 0) || (i < a.dim); i++) {
216  if(a.point_data[i] < b.point_data[i]) return true;
217  if(a.point_data[i] > b.point_data[i]) return false;
218  }
219  return false;
220  }
221  };
222 
223  __CUDA_HD__
224  Color get_color(void) const;
225  __CUDA_HD__
226  coord_t get_index(void) const;
227  __CUDA_HD__
228  int get_dim(void) const;
229  __CUDA_HD__
230  inline bool exists(void) const { return (get_dim() > 0); }
231 
232  __CUDA_HD__
233  bool is_null(void) const;
234 
235  __CUDA_HD__
236  static DomainPoint nil(void);
237 
238  protected:
239  template<typename T> __CUDA_HD__
240  static inline coord_t check_for_overflow(const T &value);
241  public:
242  int dim;
243  coord_t point_data[MAX_POINT_DIM];
244 
245  friend std::ostream& operator<<(std::ostream& os, const DomainPoint& dp);
246  };
247 
253  class Domain {
254  public:
255  typedef ::realm_id_t IDType;
256  // Keep this in sync with legion_domain_max_rect_dim_t
257  // in legion_config.h
258  static constexpr int MAX_RECT_DIM = LEGION_MAX_DIM;
259  __CUDA_HD__
260  Domain(void);
261  __CUDA_HD__
262  Domain(const Domain& other);
263  __CUDA_HD__
264  Domain(Domain &&other) noexcept;
265  __CUDA_HD__
266  Domain(const DomainPoint &lo, const DomainPoint &hi);
267 
268  template<int DIM, typename T> __CUDA_HD__
269  Domain(const Rect<DIM,T> &other);
270 
271  template<int DIM, typename T> __CUDA_HD__
272  Domain(const DomainT<DIM,T> &other);
273 
274  __CUDA_HD__
275  Domain& operator=(const Domain& other);
276  __CUDA_HD__
277  Domain& operator=(Domain &&other) noexcept;
278  template<int DIM, typename T> __CUDA_HD__
279  Domain& operator=(const Rect<DIM,T> &other);
280  template<int DIM, typename T> __CUDA_HD__
281  Domain& operator=(const DomainT<DIM,T> &other);
282 
283  __CUDA_HD__
284  bool operator==(const Domain &rhs) const;
285  __CUDA_HD__
286  bool operator!=(const Domain &rhs) const;
287  __CUDA_HD__
288  bool operator<(const Domain &rhs) const;
289 
290  __CUDA_HD__
291  Domain operator+(const DomainPoint &point) const;
292  __CUDA_HD__
293  Domain& operator+=(const DomainPoint &point);
294 
295  __CUDA_HD__
296  Domain operator-(const DomainPoint &point) const;
297  __CUDA_HD__
298  Domain& operator-=(const DomainPoint &point);
299 
300  static const Domain NO_DOMAIN;
301 
302  __CUDA_HD__
303  bool exists(void) const;
304  __CUDA_HD__
305  bool dense(void) const;
306 
307  template<int DIM, typename T> __CUDA_HD__
308  Rect<DIM,T> bounds(void) const;
309 
310  template<int DIM, typename T> __CUDA_HD__
311  operator Rect<DIM,T>(void) const;
312 
313  template<int DIM, typename T>
314  operator DomainT<DIM,T>(void) const;
315 
316  // Only works for structured DomainPoint.
317  static Domain from_domain_point(const DomainPoint &p);
318 
319  // No longer supported
320  //Realm::IndexSpace get_index_space(void) const;
321 
322  __CUDA_HD__
323  bool is_valid(void) const;
324 
325  bool contains(const DomainPoint &point) const;
326 
327  // This will only check the bounds and not the sparsity map
328  __CUDA_HD__
329  bool contains_bounds_only(const DomainPoint &point) const;
330 
331  __CUDA_HD__
332  int get_dim(void) const;
333 
334  bool empty(void) const;
335 
336  size_t get_volume(void) const;
337 
338  __CUDA_HD__
339  DomainPoint lo(void) const;
340 
341  __CUDA_HD__
342  DomainPoint hi(void) const;
343 
344  // Intersects this Domain with another Domain and returns the result.
345  Domain intersection(const Domain &other) const;
346 
347  // Returns the bounding box for this Domain and a point.
348  // WARNING: only works with structured Domain.
349  Domain convex_hull(const DomainPoint &p) const;
350 
352  public:
353  DomainPointIterator(const Domain& d);
355 
356  bool step(void);
357 
358  operator bool(void) const;
359  DomainPoint& operator*(void);
360  DomainPointIterator& operator=(const DomainPointIterator &rhs);
361  DomainPointIterator& operator++(void);
362  DomainPointIterator operator++(int /*i am postfix*/);
363  public:
364  DomainPoint p;
365  // Realm's iterators are copyable by value so we can just always
366  // copy them in and out of some buffers
367  static_assert(std::is_trivially_copyable<
368  Realm::IndexSpaceIterator<MAX_RECT_DIM,coord_t> >::value);
369  static_assert(std::is_trivially_copyable<
370  Realm::PointInRectIterator<MAX_RECT_DIM,coord_t> >::value);
371  uint8_t is_iterator[
372  sizeof(Realm::IndexSpaceIterator<MAX_RECT_DIM,coord_t>)];
373  uint8_t rect_iterator[
374  sizeof(Realm::PointInRectIterator<MAX_RECT_DIM,coord_t>)];
375  TypeTag is_type;
376  bool is_valid, rect_valid;
377  };
378  protected:
379  public:
380  IDType is_id;
381  // For Realm index spaces we need to have a type tag to know
382  // what the type of the original sparsity map was
383  // Without it you can get undefined behavior trying to interpret
384  // the sparsity map incorrectly. This doesn't matter for the bounds
385  // data because we've done the conversion for ourselves.
386  // Technically this is redundant with the dimension since it also
387  // encodes the dimension, but we'll keep them separate for now for
388  // backwards compatibility
389  TypeTag is_type;
390 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
391  // Work around an internal nvcc bug by marking this volatile
392  volatile
393 #endif
394  int dim;
395  coord_t rect_data[2 * MAX_RECT_DIM];
396  private:
397  // Helper functor classes for demux-ing templates when we have
398  // non-trivial sparsity maps with unusual types
399  // User's should never need to look at these hence they are private
400  template<typename T> __CUDA_HD__
401  static inline coord_t check_for_overflow(const T &value);
402  struct ContainsFunctor {
403  public:
404  ContainsFunctor(const Domain &d, const DomainPoint &p, bool &res)
405  : domain(d), point(p), result(res) { }
406  template<typename N, typename T>
407  static inline void demux(ContainsFunctor *functor)
408  {
409  DomainT<N::N,T> is = functor->domain;
410  Point<N::N,T> p = functor->point;
411  functor->result = is.contains(p);
412  }
413  public:
414  const Domain &domain;
415  const DomainPoint &point;
416  bool &result;
417  };
418  struct VolumeFunctor {
419  public:
420  VolumeFunctor(const Domain &d, size_t &r)
421  : domain(d), result(r) { }
422  template<typename N, typename T>
423  static inline void demux(VolumeFunctor *functor)
424  {
425  DomainT<N::N,T> is = functor->domain;
426  functor->result = is.volume();
427  }
428  public:
429  const Domain &domain;
430  size_t &result;
431  };
432  struct IntersectionFunctor {
433  public:
434  IntersectionFunctor(const Domain &l, const Domain &r, Domain &res)
435  : lhs(l), rhs(r), result(res) { }
436  public:
437  template<typename N, typename T>
438  static inline void demux(IntersectionFunctor *functor)
439  {
440  DomainT<N::N,T> is1 = functor->lhs;
441  DomainT<N::N,T> is2 = functor->rhs;
442  Realm::ProfilingRequestSet dummy_requests;
443  DomainT<N::N,T> temp;
444  Internal::LgEvent wait_on(
445  DomainT<N::N,T>::compute_intersection(is1, is2,
446  temp, dummy_requests));
447  if (wait_on.exists())
448  wait_on.wait();
449  functor->result = Domain(temp.tighten());
450  temp.destroy();
451  }
452  public:
453  const Domain &lhs;
454  const Domain &rhs;
455  Domain &result;
456  };
457  struct IteratorInitFunctor {
458  public:
459  IteratorInitFunctor(const Domain &d, DomainPointIterator &i)
460  : domain(d), iterator(i) { }
461  public:
462  template<typename N, typename T>
463  static inline void demux(IteratorInitFunctor *functor)
464  {
465  DomainT<N::N,T> is = functor->domain;
466  Realm::IndexSpaceIterator<N::N,T> is_itr(is);
467  static_assert(sizeof(is_itr) <=
468  sizeof(functor->iterator.is_iterator));
469  functor->iterator.is_valid = is_itr.valid;
470  if (is_itr.valid)
471  {
472  // Always use coord_t for the rect so we don't demux unnecessarily
473  Realm::Rect<N::N,coord_t> rect = is_itr.rect;
474  Realm::PointInRectIterator<N::N,coord_t> rect_itr(rect);
475  static_assert(sizeof(rect_itr) <=
476  sizeof(functor->iterator.rect_iterator));
477  assert(rect_itr.valid);
478  functor->iterator.rect_valid = true;
479  functor->iterator.p = rect_itr.p;
480  memcpy(functor->iterator.rect_iterator, &rect_itr, sizeof(rect_itr));
481  memcpy(functor->iterator.is_iterator, &is_itr, sizeof(is_itr));
482  }
483  else
484  functor->iterator.rect_valid = false;
485  }
486  public:
487  const Domain &domain;
488  DomainPointIterator &iterator;
489  };
490  struct IteratorStepFunctor {
491  public:
492  IteratorStepFunctor(DomainPointIterator &i)
493  : iterator(i) { }
494  public:
495  template<typename N, typename T>
496  static inline void demux(IteratorStepFunctor *functor)
497  {
498  // We already know the rect iterator is not valid here
499 #ifdef DEBUG_LEGION
500  assert(!functor->iterator.rect_valid);
501 #endif
502  Realm::IndexSpaceIterator<N::N,T> is_itr;
503  memcpy(&is_itr, functor->iterator.is_iterator, sizeof(is_itr));
504  is_itr.step(); \
505  functor->iterator.is_valid = is_itr.valid;
506  if (is_itr.valid)
507  {
508  // Convert to rect with coord_t
509  Realm::Rect<N::N,coord_t> rect = is_itr.rect;
510  Realm::PointInRectIterator<N::N,coord_t> new_rectitr(rect);
511 #ifdef DEBUG_LEGION
512  assert(new_rectitr.valid);
513 #endif
514  functor->iterator.rect_valid = true;
515  functor->iterator.p = new_rectitr.p;
516  memcpy(functor->iterator.rect_iterator, &new_rectitr,
517  sizeof(new_rectitr));
518  memcpy(functor->iterator.is_iterator, &is_itr, sizeof(is_itr));
519  }
520  }
521  public:
522  DomainPointIterator &iterator;
523  };
524  };
525 
526  template<int DIM, typename COORD_T = coord_t>
528  private:
529  static_assert(DIM > 0, "DIM must be positive");
530  static_assert(std::is_integral<COORD_T>::value, "must be integral type");
531  public:
532  __CUDA_HD__
533  PointInRectIterator(void);
534  __CUDA_HD__
535  PointInRectIterator(const Rect<DIM,COORD_T> &r,
536  bool column_major_order = true);
537  public:
538  __CUDA_HD__
539  inline bool valid(void) const;
540  __CUDA_HD__
541  inline bool step(void);
542  public:
543  __CUDA_HD__
544  inline bool operator()(void) const;
545  __CUDA_HD__
546  inline Point<DIM,COORD_T> operator*(void) const;
547  __CUDA_HD__
548  inline COORD_T operator[](unsigned index) const;
549  __CUDA_HD__
550  inline const Point<DIM,COORD_T>* operator->(void) const;
551  __CUDA_HD__
552  inline PointInRectIterator<DIM,COORD_T>& operator++(void);
553  __CUDA_HD__
554  inline PointInRectIterator<DIM,COORD_T> operator++(int/*postfix*/);
555  protected:
556  Realm::PointInRectIterator<DIM,COORD_T> itr;
557  };
558 
559  template<int DIM, typename COORD_T = coord_t>
561  private:
562  static_assert(DIM > 0, "DIM must be positive");
563  static_assert(std::is_integral<COORD_T>::value, "must be integral type");
564  public:
565  RectInDomainIterator(void);
566  RectInDomainIterator(const DomainT<DIM,COORD_T> &d);
567  public:
568  inline bool valid(void) const;
569  inline bool step(void);
570  public:
571  inline bool operator()(void) const;
572  inline Rect<DIM,COORD_T> operator*(void) const;
573  inline const Rect<DIM,COORD_T>* operator->(void) const;
574  inline RectInDomainIterator<DIM,COORD_T>& operator++(void);
575  inline RectInDomainIterator<DIM,COORD_T> operator++(int/*postfix*/);
576  protected:
577  Realm::IndexSpaceIterator<DIM,COORD_T> itr;
578  };
579 
580  template<int DIM, typename COORD_T = coord_t>
582  private:
583  static_assert(DIM > 0, "DIM must be positive");
584  static_assert(std::is_integral<COORD_T>::value, "must be integral type");
585  public:
586  PointInDomainIterator(void);
587  PointInDomainIterator(const DomainT<DIM,COORD_T> &d,
588  bool column_major_order = true);
589  public:
590  inline bool valid(void) const;
591  inline bool step(void);
592  public:
593  inline bool operator()(void) const;
594  inline Point<DIM,COORD_T> operator*(void) const;
595  inline COORD_T operator[](unsigned index) const;
596  inline const Point<DIM,COORD_T>* operator->(void) const;
597  inline PointInDomainIterator& operator++(void);
598  inline PointInDomainIterator operator++(int /*postfix*/);
599  protected:
602  bool column_major;
603  };
604 
611  public:
612  __CUDA_HD__
613  DomainTransform(void);
614  __CUDA_HD__
615  DomainTransform(const DomainTransform &rhs);
616  template<int M, int N, typename T> __CUDA_HD__
617  DomainTransform(const Transform<M,N,T> &rhs);
618  public:
619  __CUDA_HD__
620  DomainTransform& operator=(const DomainTransform &rhs);
621  template<int M, int N, typename T> __CUDA_HD__
622  DomainTransform& operator=(const Transform<M,N,T> &rhs);
623  __CUDA_HD__
624  bool operator==(const DomainTransform &rhs) const;
625  __CUDA_HD__
626  bool operator!=(const DomainTransform &rhs) const;
627  public:
628  template<int M, int N, typename T> __CUDA_HD__
629  operator Transform<M,N,T>(void) const;
630  public:
631  __CUDA_HD__
632  DomainPoint operator*(const DomainPoint &p) const;
633  __CUDA_HD__
634  Domain operator*(const Domain &domain) const;
635  __CUDA_HD__
636  DomainTransform operator*(const DomainTransform &transform) const;
637  public:
638  __CUDA_HD__
639  bool is_identity(void) const;
640  public:
641  int m, n;
642  coord_t matrix[LEGION_MAX_DIM * LEGION_MAX_DIM];
643  };
644 
651  public:
652  __CUDA_HD__
653  DomainAffineTransform(void);
654  __CUDA_HD__
656  __CUDA_HD__
658  template<int M, int N, typename T> __CUDA_HD__
660  public:
661  __CUDA_HD__
662  DomainAffineTransform& operator=(const DomainAffineTransform &rhs);
663  template<int M, int N, typename T> __CUDA_HD__
664  DomainAffineTransform& operator=(const AffineTransform<M,N,T> &rhs);
665  __CUDA_HD__
666  bool operator==(const DomainAffineTransform &rhs) const;
667  __CUDA_HD__
668  bool operator!=(const DomainAffineTransform &rhs) const;
669  public:
670  template<int M, int N, typename T> __CUDA_HD__
671  operator AffineTransform<M,N,T>(void) const;
672  public:
673  // Apply the transformation to a point
674  __CUDA_HD__
675  DomainPoint operator[](const DomainPoint &p) const;
676  // Test for the identity
677  __CUDA_HD__
678  bool is_identity(void) const;
679  public:
680  DomainTransform transform;
681  DomainPoint offset;
682  };
683 
690  public:
691  __CUDA_HD__
692  DomainScaleTransform(void);
693  __CUDA_HD__
695  __CUDA_HD__
696  DomainScaleTransform(const DomainTransform &transform,
697  const Domain &extent, const DomainPoint &divisor);
698  template<int M, int N, typename T> __CUDA_HD__
700  public:
701  __CUDA_HD__
702  DomainScaleTransform& operator=(const DomainScaleTransform &rhs);
703  template<int M, int N, typename T> __CUDA_HD__
704  DomainScaleTransform& operator=(const ScaleTransform<M,N,T> &rhs);
705  __CUDA_HD__
706  bool operator==(const DomainScaleTransform &rhs) const;
707  __CUDA_HD__
708  bool operator!=(const DomainScaleTransform &rhs) const;
709  public:
710  template<int M, int N, typename T> __CUDA_HD__
711  operator ScaleTransform<M,N,T>(void) const;
712  public:
713  // Apply the transformation to a point
714  __CUDA_HD__
715  Domain operator[](const DomainPoint &p) const;
716  // Test for the identity
717  __CUDA_HD__
718  bool is_identity(void) const;
719  public:
720  DomainTransform transform;
721  Domain extent;
722  DomainPoint divisor;
723  };
724 
733  template<typename FT, PrivilegeMode PM = LEGION_READ_WRITE>
734  class Span {
735  public:
736  class iterator {
737  public:
738  // explicitly set iterator traits
739  typedef std::random_access_iterator_tag iterator_category;
740  typedef FT value_type;
741  typedef std::ptrdiff_t difference_type;
742  typedef FT *pointer;
743  typedef FT& reference;
744 
745  iterator(void) : ptr(NULL), stride(0) { }
746  private:
747  iterator(uint8_t *p, size_t s) : ptr(p), stride(s) { }
748  public:
749  inline iterator& operator=(const iterator &rhs)
750  { ptr = rhs.ptr; stride = rhs.stride; return *this; }
751  inline iterator& operator+=(int rhs) { ptr += stride; return *this; }
752  inline iterator& operator-=(int rhs) { ptr -= stride; return *this; }
753  inline FT& operator*(void) const
754  {
755  FT *result = NULL;
756  static_assert(sizeof(result) == sizeof(ptr));
757  memcpy(&result, &ptr, sizeof(result));
758  return *result;
759  }
760  inline FT* operator->(void) const
761  {
762  FT *result = NULL;
763  static_assert(sizeof(result) == sizeof(ptr));
764  memcpy(&result, &ptr, sizeof(result));
765  return result;
766  }
767  inline FT& operator[](int rhs) const
768  {
769  FT *result = NULL;
770  uint8_t *ptr2 = ptr + rhs * stride;
771  static_assert(sizeof(result) == sizeof(ptr2));
772  memcpy(&result, &ptr2, sizeof(result));
773  return *result;
774  }
775  public:
776  inline iterator& operator++(void) { ptr += stride; return *this; }
777  inline iterator& operator--(void) { ptr -= stride; return *this; }
778  inline iterator operator++(int)
779  { iterator it(ptr, stride); ptr += stride; return it; }
780  inline iterator operator--(int)
781  { iterator it(ptr, stride); ptr -= stride; return it; }
782  inline iterator operator+(int rhs) const
783  { return iterator(ptr + stride * rhs, stride); }
784  inline iterator operator-(int rhs) const
785  { return iterator(ptr - stride * rhs, stride); }
786  public:
787  inline bool operator==(const iterator &rhs) const
788  { return (ptr == rhs.ptr); }
789  inline bool operator!=(const iterator &rhs) const
790  { return (ptr != rhs.ptr); }
791  inline bool operator<(const iterator &rhs) const
792  { return (ptr < rhs.ptr); }
793  inline bool operator>(const iterator &rhs) const
794  { return (ptr > rhs.ptr); }
795  inline bool operator<=(const iterator &rhs) const
796  { return (ptr <= rhs.ptr); }
797  inline bool operator>=(const iterator &rhs) const
798  { return (ptr >= rhs.ptr); }
799  private:
800  uint8_t *ptr;
801  size_t stride;
802  };
804  public:
805  // explicitly set iterator traits
806  typedef std::random_access_iterator_tag iterator_category;
807  typedef FT value_type;
808  typedef std::ptrdiff_t difference_type;
809  typedef FT *pointer;
810  typedef FT& reference;
811 
812  reverse_iterator(void) : ptr(NULL), stride(0) { }
813  private:
814  reverse_iterator(uint8_t *p, size_t s) : ptr(p), stride(s) { }
815  public:
816  inline reverse_iterator& operator=(const reverse_iterator &rhs)
817  { ptr = rhs.ptr; stride = rhs.stride; return *this; }
818  inline reverse_iterator& operator+=(int rhs)
819  { ptr -= stride; return *this; }
820  inline reverse_iterator& operator-=(int rhs)
821  { ptr += stride; return *this; }
822  inline FT& operator*(void) const
823  {
824  FT *result = NULL;
825  static_assert(sizeof(result) == sizeof(ptr));
826  memcpy(&result, &ptr, sizeof(result));
827  return *result;
828  }
829  inline FT* operator->(void) const
830  {
831  FT *result = NULL;
832  static_assert(sizeof(result) == sizeof(ptr));
833  memcpy(&result, &ptr, sizeof(result));
834  return result;
835  }
836  inline FT& operator[](int rhs) const
837  {
838  FT *result = NULL;
839  uint8_t *ptr2 = ptr - rhs * stride;
840  static_assert(sizeof(result) == sizeof(ptr2));
841  memcpy(&result, &ptr2, sizeof(result));
842  return *result;
843  }
844  public:
845  inline reverse_iterator& operator++(void)
846  { ptr -= stride; return *this; }
847  inline reverse_iterator& operator--(void)
848  { ptr += stride; return *this; }
849  inline reverse_iterator operator++(int)
850  { reverse_iterator it(ptr, stride); ptr -= stride; return it; }
851  inline reverse_iterator operator--(int)
852  { reverse_iterator it(ptr, stride); ptr += stride; return it; }
853  inline reverse_iterator operator+(int rhs) const
854  { return reverse_iterator(ptr - stride * rhs, stride); }
855  inline reverse_iterator operator-(int rhs) const
856  { return reverse_iterator(ptr + stride * rhs, stride); }
857  public:
858  inline bool operator==(const reverse_iterator &rhs) const
859  { return (ptr == rhs.ptr); }
860  inline bool operator!=(const reverse_iterator &rhs) const
861  { return (ptr != rhs.ptr); }
862  inline bool operator<(const reverse_iterator &rhs) const
863  { return (ptr > rhs.ptr); }
864  inline bool operator>(const reverse_iterator &rhs) const
865  { return (ptr < rhs.ptr); }
866  inline bool operator<=(const reverse_iterator &rhs) const
867  { return (ptr >= rhs.ptr); }
868  inline bool operator>=(const reverse_iterator &rhs) const
869  { return (ptr <= rhs.ptr); }
870  private:
871  uint8_t *ptr;
872  size_t stride;
873  };
874  public:
875  Span(void) : base(NULL), extent(0), stride(0) { }
876  Span(FT *b, size_t e, size_t s = sizeof(FT))
877  : base(NULL), extent(e), stride(s)
878  {
879  static_assert(sizeof(base) == sizeof(b));
880  memcpy(&base, &b, sizeof(base));
881  }
882  public:
883  inline iterator begin(void) const { return iterator(base, stride); }
884  inline iterator end(void) const
885  { return iterator(base + extent*stride, stride); }
886  inline reverse_iterator rbegin(void) const
887  { return reverse_iterator(base + (extent-1) * stride, stride); }
888  inline reverse_iterator rend(void) const
889  { return reverse_iterator(base - stride, stride); }
890  public:
891  inline FT& front(void) const
892  {
893  FT *result = NULL;
894  static_assert(sizeof(result) == sizeof(base));
895  memcpy(&result, &base, sizeof(result));
896  return *result;
897  }
898  inline FT& back(void) const
899  {
900  FT *result = NULL;
901  uint8_t *ptr = base + (extent-1)*stride;
902  static_assert(sizeof(result) == sizeof(ptr));
903  memcpy(&result, &ptr, sizeof(result));
904  return *result;
905  }
906  inline FT& operator[](int index) const
907  {
908  FT *result = NULL;
909  uint8_t *ptr = base + index * stride;
910  static_assert(sizeof(result) == sizeof(ptr));
911  memcpy(&result, &ptr, sizeof(result));
912  return *result;
913  }
914  inline FT* data(void) const
915  {
916  FT *result = NULL;
917  static_assert(sizeof(result) == sizeof(base));
918  memcpy(&result, &base, sizeof(result));
919  return result;
920  }
921  inline uintptr_t get_base(void) const { return uintptr_t(base); }
922  public:
923  inline size_t size(void) const { return extent; }
924  inline size_t step(void) const { return stride; }
925  inline bool empty(void) const { return (extent == 0); }
926  private:
927  uint8_t *base;
928  size_t extent; // number of elements
929  size_t stride; // byte stride
930  };
931 
932 }; // namespace Legion
933 
934 #include "legion/legion_domain.inl"
935 
936 #endif // __LEGION_DOMAIN_H__
937 
Definition: legion_domain.h:351
Definition: legion_domain.h:650
Definition: legion_domain.h:253
Definition: legion_domain.h:132
Definition: legion_domain.h:689
Definition: legion_domain.h:610
Definition: legion_domain.h:581
Definition: legion_domain.h:527
Definition: legion_domain.h:560
Definition: legion_domain.h:736
Definition: legion_domain.h:803
Definition: legion_domain.h:734
Definition: legion_domain.h:46
Definition: legion_domain.h:209
Definition: legion_domain.h:92