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  // Note: GCC 4.9 breaks even with C++11, so for now peg this on
366  // C++14 until we deprecate GCC 4.9 support.
367 #if !defined(__GNUC__) || (__GNUC__ >= 5)
368  // Realm's iterators are copyable by value so we can just always
369  // copy them in and out of some buffers
370  static_assert(std::is_trivially_copyable<
371  Realm::IndexSpaceIterator<MAX_RECT_DIM,coord_t> >::value, "very bad");
372  static_assert(std::is_trivially_copyable<
373  Realm::PointInRectIterator<MAX_RECT_DIM,coord_t> >::value,"very bad");
374 #endif
375  uint8_t is_iterator[
376  sizeof(Realm::IndexSpaceIterator<MAX_RECT_DIM,coord_t>)];
377  uint8_t rect_iterator[
378  sizeof(Realm::PointInRectIterator<MAX_RECT_DIM,coord_t>)];
379  TypeTag is_type;
380  bool is_valid, rect_valid;
381  };
382  protected:
383  public:
384  IDType is_id;
385  // For Realm index spaces we need to have a type tag to know
386  // what the type of the original sparsity map was
387  // Without it you can get undefined behavior trying to interpret
388  // the sparsity map incorrectly. This doesn't matter for the bounds
389  // data because we've done the conversion for ourselves.
390  // Technically this is redundant with the dimension since it also
391  // encodes the dimension, but we'll keep them separate for now for
392  // backwards compatibility
393  TypeTag is_type;
394 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
395  // Work around an internal nvcc bug by marking this volatile
396  volatile
397 #endif
398  int dim;
399  coord_t rect_data[2 * MAX_RECT_DIM];
400  private:
401  // Helper functor classes for demux-ing templates when we have
402  // non-trivial sparsity maps with unusual types
403  // User's should never need to look at these hence they are private
404  template<typename T> __CUDA_HD__
405  static inline coord_t check_for_overflow(const T &value);
406  struct ContainsFunctor {
407  public:
408  ContainsFunctor(const Domain &d, const DomainPoint &p, bool &res)
409  : domain(d), point(p), result(res) { }
410  template<typename N, typename T>
411  static inline void demux(ContainsFunctor *functor)
412  {
413  DomainT<N::N,T> is = functor->domain;
414  Point<N::N,T> p = functor->point;
415  functor->result = is.contains(p);
416  }
417  public:
418  const Domain &domain;
419  const DomainPoint &point;
420  bool &result;
421  };
422  struct VolumeFunctor {
423  public:
424  VolumeFunctor(const Domain &d, size_t &r)
425  : domain(d), result(r) { }
426  template<typename N, typename T>
427  static inline void demux(VolumeFunctor *functor)
428  {
429  DomainT<N::N,T> is = functor->domain;
430  functor->result = is.volume();
431  }
432  public:
433  const Domain &domain;
434  size_t &result;
435  };
436  struct IntersectionFunctor {
437  public:
438  IntersectionFunctor(const Domain &l, const Domain &r, Domain &res)
439  : lhs(l), rhs(r), result(res) { }
440  public:
441  template<typename N, typename T>
442  static inline void demux(IntersectionFunctor *functor)
443  {
444  DomainT<N::N,T> is1 = functor->lhs;
445  DomainT<N::N,T> is2 = functor->rhs;
446  Realm::ProfilingRequestSet dummy_requests;
447  DomainT<N::N,T> temp;
448  Internal::LgEvent wait_on(
449  DomainT<N::N,T>::compute_intersection(is1, is2,
450  temp, dummy_requests));
451  if (wait_on.exists())
452  wait_on.wait();
453  functor->result = Domain(temp.tighten());
454  temp.destroy();
455  }
456  public:
457  const Domain &lhs;
458  const Domain &rhs;
459  Domain &result;
460  };
461  struct IteratorInitFunctor {
462  public:
463  IteratorInitFunctor(const Domain &d, DomainPointIterator &i)
464  : domain(d), iterator(i) { }
465  public:
466  template<typename N, typename T>
467  static inline void demux(IteratorInitFunctor *functor)
468  {
469  DomainT<N::N,T> is = functor->domain;
470  Realm::IndexSpaceIterator<N::N,T> is_itr(is);
471  static_assert(sizeof(is_itr) <=
472  sizeof(functor->iterator.is_iterator), "very bad");
473  functor->iterator.is_valid = is_itr.valid;
474  if (is_itr.valid)
475  {
476  // Always use coord_t for the rect so we don't demux unnecessarily
477  Realm::Rect<N::N,coord_t> rect = is_itr.rect;
478  Realm::PointInRectIterator<N::N,coord_t> rect_itr(rect);
479  static_assert(sizeof(rect_itr) <=
480  sizeof(functor->iterator.rect_iterator), "very bad");
481  assert(rect_itr.valid);
482  functor->iterator.rect_valid = true;
483  functor->iterator.p = rect_itr.p;
484  memcpy(functor->iterator.rect_iterator, &rect_itr, sizeof(rect_itr));
485  memcpy(functor->iterator.is_iterator, &is_itr, sizeof(is_itr));
486  }
487  else
488  functor->iterator.rect_valid = false; \
489  }
490  public:
491  const Domain &domain;
492  DomainPointIterator &iterator;
493  };
494  struct IteratorStepFunctor {
495  public:
496  IteratorStepFunctor(DomainPointIterator &i)
497  : iterator(i) { }
498  public:
499  template<typename N, typename T>
500  static inline void demux(IteratorStepFunctor *functor)
501  {
502  // We already know the rect iterator is not valid here
503 #ifdef DEBUG_LEGION
504  assert(!functor->iterator.rect_valid);
505 #endif
506  Realm::IndexSpaceIterator<N::N,T> is_itr;
507  memcpy(&is_itr, functor->iterator.is_iterator, sizeof(is_itr));
508  is_itr.step(); \
509  functor->iterator.is_valid = is_itr.valid;
510  if (is_itr.valid)
511  {
512  // Convert to rect with coord_t
513  Realm::Rect<N::N,coord_t> rect = is_itr.rect;
514  Realm::PointInRectIterator<N::N,coord_t> new_rectitr(rect);
515 #ifdef DEBUG_LEGION
516  assert(new_rectitr.valid);
517 #endif
518  functor->iterator.rect_valid = true;
519  functor->iterator.p = new_rectitr.p;
520  memcpy(functor->iterator.rect_iterator, &new_rectitr,
521  sizeof(new_rectitr));
522  memcpy(functor->iterator.is_iterator, &is_itr, sizeof(is_itr));
523  }
524  }
525  public:
526  DomainPointIterator &iterator;
527  };
528  };
529 
530  template<int DIM, typename COORD_T = coord_t>
532  private:
533  static_assert(DIM > 0, "DIM must be positive");
534  static_assert(std::is_integral<COORD_T>::value, "must be integral type");
535  public:
536  __CUDA_HD__
537  PointInRectIterator(void);
538  __CUDA_HD__
539  PointInRectIterator(const Rect<DIM,COORD_T> &r,
540  bool column_major_order = true);
541  public:
542  __CUDA_HD__
543  inline bool valid(void) const;
544  __CUDA_HD__
545  inline bool step(void);
546  public:
547  __CUDA_HD__
548  inline bool operator()(void) const;
549  __CUDA_HD__
550  inline Point<DIM,COORD_T> operator*(void) const;
551  __CUDA_HD__
552  inline COORD_T operator[](unsigned index) const;
553  __CUDA_HD__
554  inline const Point<DIM,COORD_T>* operator->(void) const;
555  __CUDA_HD__
556  inline PointInRectIterator<DIM,COORD_T>& operator++(void);
557  __CUDA_HD__
558  inline PointInRectIterator<DIM,COORD_T> operator++(int/*postfix*/);
559  protected:
560  Realm::PointInRectIterator<DIM,COORD_T> itr;
561  };
562 
563  template<int DIM, typename COORD_T = coord_t>
565  private:
566  static_assert(DIM > 0, "DIM must be positive");
567  static_assert(std::is_integral<COORD_T>::value, "must be integral type");
568  public:
569  RectInDomainIterator(void);
570  RectInDomainIterator(const DomainT<DIM,COORD_T> &d);
571  public:
572  inline bool valid(void) const;
573  inline bool step(void);
574  public:
575  inline bool operator()(void) const;
576  inline Rect<DIM,COORD_T> operator*(void) const;
577  inline const Rect<DIM,COORD_T>* operator->(void) const;
578  inline RectInDomainIterator<DIM,COORD_T>& operator++(void);
579  inline RectInDomainIterator<DIM,COORD_T> operator++(int/*postfix*/);
580  protected:
581  Realm::IndexSpaceIterator<DIM,COORD_T> itr;
582  };
583 
584  template<int DIM, typename COORD_T = coord_t>
586  private:
587  static_assert(DIM > 0, "DIM must be positive");
588  static_assert(std::is_integral<COORD_T>::value, "must be integral type");
589  public:
590  PointInDomainIterator(void);
591  PointInDomainIterator(const DomainT<DIM,COORD_T> &d,
592  bool column_major_order = true);
593  public:
594  inline bool valid(void) const;
595  inline bool step(void);
596  public:
597  inline bool operator()(void) const;
598  inline Point<DIM,COORD_T> operator*(void) const;
599  inline COORD_T operator[](unsigned index) const;
600  inline const Point<DIM,COORD_T>* operator->(void) const;
601  inline PointInDomainIterator& operator++(void);
602  inline PointInDomainIterator operator++(int /*postfix*/);
603  protected:
606  bool column_major;
607  };
608 
615  public:
616  __CUDA_HD__
617  DomainTransform(void);
618  __CUDA_HD__
619  DomainTransform(const DomainTransform &rhs);
620  template<int M, int N, typename T> __CUDA_HD__
621  DomainTransform(const Transform<M,N,T> &rhs);
622  public:
623  __CUDA_HD__
624  DomainTransform& operator=(const DomainTransform &rhs);
625  template<int M, int N, typename T> __CUDA_HD__
626  DomainTransform& operator=(const Transform<M,N,T> &rhs);
627  __CUDA_HD__
628  bool operator==(const DomainTransform &rhs) const;
629  __CUDA_HD__
630  bool operator!=(const DomainTransform &rhs) const;
631  public:
632  template<int M, int N, typename T> __CUDA_HD__
633  operator Transform<M,N,T>(void) const;
634  public:
635  __CUDA_HD__
636  DomainPoint operator*(const DomainPoint &p) const;
637  __CUDA_HD__
638  Domain operator*(const Domain &domain) const;
639  __CUDA_HD__
640  DomainTransform operator*(const DomainTransform &transform) const;
641  public:
642  __CUDA_HD__
643  bool is_identity(void) const;
644  public:
645  int m, n;
646  coord_t matrix[LEGION_MAX_DIM * LEGION_MAX_DIM];
647  };
648 
655  public:
656  __CUDA_HD__
657  DomainAffineTransform(void);
658  __CUDA_HD__
660  __CUDA_HD__
662  template<int M, int N, typename T> __CUDA_HD__
664  public:
665  __CUDA_HD__
666  DomainAffineTransform& operator=(const DomainAffineTransform &rhs);
667  template<int M, int N, typename T> __CUDA_HD__
668  DomainAffineTransform& operator=(const AffineTransform<M,N,T> &rhs);
669  __CUDA_HD__
670  bool operator==(const DomainAffineTransform &rhs) const;
671  __CUDA_HD__
672  bool operator!=(const DomainAffineTransform &rhs) const;
673  public:
674  template<int M, int N, typename T> __CUDA_HD__
675  operator AffineTransform<M,N,T>(void) const;
676  public:
677  // Apply the transformation to a point
678  __CUDA_HD__
679  DomainPoint operator[](const DomainPoint &p) const;
680  // Test for the identity
681  __CUDA_HD__
682  bool is_identity(void) const;
683  public:
684  DomainTransform transform;
685  DomainPoint offset;
686  };
687 
694  public:
695  __CUDA_HD__
696  DomainScaleTransform(void);
697  __CUDA_HD__
699  __CUDA_HD__
700  DomainScaleTransform(const DomainTransform &transform,
701  const Domain &extent, const DomainPoint &divisor);
702  template<int M, int N, typename T> __CUDA_HD__
704  public:
705  __CUDA_HD__
706  DomainScaleTransform& operator=(const DomainScaleTransform &rhs);
707  template<int M, int N, typename T> __CUDA_HD__
708  DomainScaleTransform& operator=(const ScaleTransform<M,N,T> &rhs);
709  __CUDA_HD__
710  bool operator==(const DomainScaleTransform &rhs) const;
711  __CUDA_HD__
712  bool operator!=(const DomainScaleTransform &rhs) const;
713  public:
714  template<int M, int N, typename T> __CUDA_HD__
715  operator ScaleTransform<M,N,T>(void) const;
716  public:
717  // Apply the transformation to a point
718  __CUDA_HD__
719  Domain operator[](const DomainPoint &p) const;
720  // Test for the identity
721  __CUDA_HD__
722  bool is_identity(void) const;
723  public:
724  DomainTransform transform;
725  Domain extent;
726  DomainPoint divisor;
727  };
728 
737  template<typename FT, PrivilegeMode PM = LEGION_READ_WRITE>
738  class Span {
739  public:
740  class iterator {
741  public:
742  // explicitly set iterator traits
743  typedef std::random_access_iterator_tag iterator_category;
744  typedef FT value_type;
745  typedef std::ptrdiff_t difference_type;
746  typedef FT *pointer;
747  typedef FT& reference;
748 
749  iterator(void) : ptr(NULL), stride(0) { }
750  private:
751  iterator(uint8_t *p, size_t s) : ptr(p), stride(s) { }
752  public:
753  inline iterator& operator=(const iterator &rhs)
754  { ptr = rhs.ptr; stride = rhs.stride; return *this; }
755  inline iterator& operator+=(int rhs) { ptr += stride; return *this; }
756  inline iterator& operator-=(int rhs) { ptr -= stride; return *this; }
757  inline FT& operator*(void) const
758  {
759  FT *result = NULL;
760  static_assert(sizeof(result) == sizeof(ptr), "C++ is dumb");
761  memcpy(&result, &ptr, sizeof(result));
762  return *result;
763  }
764  inline FT* operator->(void) const
765  {
766  FT *result = NULL;
767  static_assert(sizeof(result) == sizeof(ptr), "C++ is dumb");
768  memcpy(&result, &ptr, sizeof(result));
769  return result;
770  }
771  inline FT& operator[](int rhs) const
772  {
773  FT *result = NULL;
774  uint8_t *ptr2 = ptr + rhs * stride;
775  static_assert(sizeof(result) == sizeof(ptr2), "C++ is dumb");
776  memcpy(&result, &ptr2, sizeof(result));
777  return *result;
778  }
779  public:
780  inline iterator& operator++(void) { ptr += stride; return *this; }
781  inline iterator& operator--(void) { ptr -= stride; return *this; }
782  inline iterator operator++(int)
783  { iterator it(ptr, stride); ptr += stride; return it; }
784  inline iterator operator--(int)
785  { iterator it(ptr, stride); ptr -= stride; return it; }
786  inline iterator operator+(int rhs) const
787  { return iterator(ptr + stride * rhs, stride); }
788  inline iterator operator-(int rhs) const
789  { return iterator(ptr - stride * rhs, stride); }
790  public:
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  inline bool operator<=(const iterator &rhs) const
800  { return (ptr <= rhs.ptr); }
801  inline bool operator>=(const iterator &rhs) const
802  { return (ptr >= rhs.ptr); }
803  private:
804  uint8_t *ptr;
805  size_t stride;
806  };
808  public:
809  // explicitly set iterator traits
810  typedef std::random_access_iterator_tag iterator_category;
811  typedef FT value_type;
812  typedef std::ptrdiff_t difference_type;
813  typedef FT *pointer;
814  typedef FT& reference;
815 
816  reverse_iterator(void) : ptr(NULL), stride(0) { }
817  private:
818  reverse_iterator(uint8_t *p, size_t s) : ptr(p), stride(s) { }
819  public:
820  inline reverse_iterator& operator=(const reverse_iterator &rhs)
821  { ptr = rhs.ptr; stride = rhs.stride; return *this; }
822  inline reverse_iterator& operator+=(int rhs)
823  { ptr -= stride; return *this; }
824  inline reverse_iterator& operator-=(int rhs)
825  { ptr += stride; return *this; }
826  inline FT& operator*(void) const
827  {
828  FT *result = NULL;
829  static_assert(sizeof(result) == sizeof(ptr), "C++ is dumb");
830  memcpy(&result, &ptr, sizeof(result));
831  return *result;
832  }
833  inline FT* operator->(void) const
834  {
835  FT *result = NULL;
836  static_assert(sizeof(result) == sizeof(ptr), "C++ is dumb");
837  memcpy(&result, &ptr, sizeof(result));
838  return result;
839  }
840  inline FT& operator[](int rhs) const
841  {
842  FT *result = NULL;
843  uint8_t *ptr2 = ptr - rhs * stride;
844  static_assert(sizeof(result) == sizeof(ptr2), "C++ is dumb");
845  memcpy(&result, &ptr2, sizeof(result));
846  return *result;
847  }
848  public:
849  inline reverse_iterator& operator++(void)
850  { ptr -= stride; return *this; }
851  inline reverse_iterator& operator--(void)
852  { ptr += stride; return *this; }
853  inline reverse_iterator operator++(int)
854  { reverse_iterator it(ptr, stride); ptr -= stride; return it; }
855  inline reverse_iterator operator--(int)
856  { reverse_iterator it(ptr, stride); ptr += stride; return it; }
857  inline reverse_iterator operator+(int rhs) const
858  { return reverse_iterator(ptr - stride * rhs, stride); }
859  inline reverse_iterator operator-(int rhs) const
860  { return reverse_iterator(ptr + stride * rhs, stride); }
861  public:
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  inline bool operator<=(const reverse_iterator &rhs) const
871  { return (ptr >= rhs.ptr); }
872  inline bool operator>=(const reverse_iterator &rhs) const
873  { return (ptr <= rhs.ptr); }
874  private:
875  uint8_t *ptr;
876  size_t stride;
877  };
878  public:
879  Span(void) : base(NULL), extent(0), stride(0) { }
880  Span(FT *b, size_t e, size_t s = sizeof(FT))
881  : base(NULL), extent(e), stride(s)
882  {
883  static_assert(sizeof(base) == sizeof(b), "C++ is dumb");
884  memcpy(&base, &b, sizeof(base));
885  }
886  public:
887  inline iterator begin(void) const { return iterator(base, stride); }
888  inline iterator end(void) const
889  { return iterator(base + extent*stride, stride); }
890  inline reverse_iterator rbegin(void) const
891  { return reverse_iterator(base + (extent-1) * stride, stride); }
892  inline reverse_iterator rend(void) const
893  { return reverse_iterator(base - stride, stride); }
894  public:
895  inline FT& front(void) const
896  {
897  FT *result = NULL;
898  static_assert(sizeof(result) == sizeof(base), "C++ is dumb");
899  memcpy(&result, &base, sizeof(result));
900  return *result;
901  }
902  inline FT& back(void) const
903  {
904  FT *result = NULL;
905  uint8_t *ptr = base + (extent-1)*stride;
906  static_assert(sizeof(result) == sizeof(ptr), "C++ is dumb");
907  memcpy(&result, &ptr, sizeof(result));
908  return *result;
909  }
910  inline FT& operator[](int index) const
911  {
912  FT *result = NULL;
913  uint8_t *ptr = base + index * stride;
914  static_assert(sizeof(result) == sizeof(ptr), "C++ is dumb");
915  memcpy(&result, &ptr, sizeof(result));
916  return *result;
917  }
918  inline FT* data(void) const
919  {
920  FT *result = NULL;
921  static_assert(sizeof(result) == sizeof(base), "C++ is dumb");
922  memcpy(&result, &base, sizeof(result));
923  return result;
924  }
925  inline uintptr_t get_base(void) const { return uintptr_t(base); }
926  public:
927  inline size_t size(void) const { return extent; }
928  inline size_t step(void) const { return stride; }
929  inline bool empty(void) const { return (extent == 0); }
930  private:
931  uint8_t *base;
932  size_t extent; // number of elements
933  size_t stride; // byte stride
934  };
935 
936 }; // namespace Legion
937 
938 #include "legion/legion_domain.inl"
939 
940 #endif // __LEGION_DOMAIN_H__
941 
Definition: legion_domain.h:351
Definition: legion_domain.h:654
Definition: legion_domain.h:253
Definition: legion_domain.h:132
Definition: legion_domain.h:693
Definition: legion_domain.h:614
Definition: legion_domain.h:585
Definition: legion_domain.h:531
Definition: legion_domain.h:564
Definition: legion_domain.h:740
Definition: legion_domain.h:807
Definition: legion_domain.h:738
Definition: legion_domain.h:46
Definition: legion_domain.h:209
Definition: legion_domain.h:92