Legion Runtime
 All Classes Namespaces Files Functions Variables Typedefs Macros Pages
legion_domain.h
Go to the documentation of this file.
1 /* Copyright 2023 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__
56  AffineTransform(const AffineTransform<M,N,T2> &rhs);
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__
102  ScaleTransform(const ScaleTransform<M,N,T2> &rhs);
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<unsigned DIM>
146  operator LegionRuntime::Arrays::Point<DIM>(void) const;
147  template<int DIM, typename T> __CUDA_HD__
148  operator Point<DIM,T>(void) const;
149 
150  __CUDA_HD__
151  DomainPoint& operator=(const DomainPoint &rhs);
152  template<int DIM, typename T> __CUDA_HD__
153  DomainPoint& operator=(const Point<DIM,T> &rhs);
154  __CUDA_HD__
155  bool operator==(const DomainPoint &rhs) const;
156  __CUDA_HD__
157  bool operator!=(const DomainPoint &rhs) const;
158  __CUDA_HD__
159  bool operator<(const DomainPoint &rhs) const;
160 
161  __CUDA_HD__
162  DomainPoint operator+(coord_t scalar) const;
163  __CUDA_HD__
164  DomainPoint operator+(const DomainPoint &rhs) const;
165  __CUDA_HD__
166  DomainPoint& operator+=(coord_t scalar);
167  __CUDA_HD__
168  DomainPoint& operator+=(const DomainPoint &rhs);
169 
170  __CUDA_HD__
171  DomainPoint operator-(coord_t scalar) const;
172  __CUDA_HD__
173  DomainPoint operator-(const DomainPoint &rhs) const;
174  __CUDA_HD__
175  DomainPoint& operator-=(coord_t scalar);
176  __CUDA_HD__
177  DomainPoint& operator-=(const DomainPoint &rhs);
178 
179  __CUDA_HD__
180  DomainPoint operator*(coord_t scalar) const;
181  __CUDA_HD__
182  DomainPoint operator*(const DomainPoint &rhs) const;
183  __CUDA_HD__
184  DomainPoint& operator*=(coord_t scalar);
185  __CUDA_HD__
186  DomainPoint& operator*=(const DomainPoint &rhs);
187 
188  __CUDA_HD__
189  DomainPoint operator/(coord_t scalar) const;
190  __CUDA_HD__
191  DomainPoint operator/(const DomainPoint &rhs) const;
192  __CUDA_HD__
193  DomainPoint& operator/=(coord_t scalar);
194  __CUDA_HD__
195  DomainPoint& operator/=(const DomainPoint &rhs);
196 
197  __CUDA_HD__
198  DomainPoint operator%(coord_t scalar) const;
199  __CUDA_HD__
200  DomainPoint operator%(const DomainPoint &rhs) const;
201  __CUDA_HD__
202  DomainPoint& operator%=(coord_t scalar);
203  __CUDA_HD__
204  DomainPoint& operator%=(const DomainPoint &rhs);
205 
206  __CUDA_HD__
207  coord_t& operator[](unsigned index);
208  __CUDA_HD__
209  const coord_t& operator[](unsigned index) const;
210 
211  struct STLComparator {
212  __CUDA_HD__
213  bool operator()(const DomainPoint& a, const DomainPoint& b) const
214  {
215  if(a.dim < b.dim) return true;
216  if(a.dim > b.dim) return false;
217  for(int i = 0; (i == 0) || (i < a.dim); i++) {
218  if(a.point_data[i] < b.point_data[i]) return true;
219  if(a.point_data[i] > b.point_data[i]) return false;
220  }
221  return false;
222  }
223  };
224 
225  template<int DIM>
226  static DomainPoint from_point(
227  typename LegionRuntime::Arrays::Point<DIM> p);
228 
229  __CUDA_HD__
230  Color get_color(void) const;
231  __CUDA_HD__
232  coord_t get_index(void) const;
233  __CUDA_HD__
234  int get_dim(void) const;
235 
236  template <int DIM>
237  LegionRuntime::Arrays::Point<DIM> get_point(void) const;
238 
239  __CUDA_HD__
240  bool is_null(void) const;
241 
242  __CUDA_HD__
243  static DomainPoint nil(void);
244 
245  protected:
246  template<typename T> __CUDA_HD__
247  static inline coord_t check_for_overflow(const T &value);
248  public:
249  int dim;
250  coord_t point_data[MAX_POINT_DIM];
251 
252  friend std::ostream& operator<<(std::ostream& os, const DomainPoint& dp);
253  };
254 
260  class Domain {
261  public:
262  typedef ::realm_id_t IDType;
263  // Keep this in sync with legion_domain_max_rect_dim_t
264  // in legion_config.h
265  static constexpr int MAX_RECT_DIM = LEGION_MAX_DIM;
266  __CUDA_HD__
267  Domain(void);
268  __CUDA_HD__
269  Domain(const Domain& other);
270  __CUDA_HD__
271  Domain(const DomainPoint &lo, const DomainPoint &hi);
272 
273  template<int DIM, typename T> __CUDA_HD__
274  Domain(const Rect<DIM,T> &other);
275 
276  template<int DIM, typename T> __CUDA_HD__
277  Domain(const DomainT<DIM,T> &other);
278 
279  __CUDA_HD__
280  Domain& operator=(const Domain& other);
281  template<int DIM, typename T> __CUDA_HD__
282  Domain& operator=(const Rect<DIM,T> &other);
283  template<int DIM, typename T> __CUDA_HD__
284  Domain& operator=(const DomainT<DIM,T> &other);
285 
286  __CUDA_HD__
287  bool operator==(const Domain &rhs) const;
288  __CUDA_HD__
289  bool operator!=(const Domain &rhs) const;
290  __CUDA_HD__
291  bool operator<(const Domain &rhs) const;
292 
293  __CUDA_HD__
294  Domain operator+(const DomainPoint &point) const;
295  __CUDA_HD__
296  Domain& operator+=(const DomainPoint &point);
297 
298  __CUDA_HD__
299  Domain operator-(const DomainPoint &point) const;
300  __CUDA_HD__
301  Domain& operator-=(const DomainPoint &point);
302 
303  static const Domain NO_DOMAIN;
304 
305  __CUDA_HD__
306  bool exists(void) const;
307  __CUDA_HD__
308  bool dense(void) const;
309 
310  template<int DIM, typename T> __CUDA_HD__
311  Rect<DIM,T> bounds(void) const;
312 
313  template<int DIM>
314  static Domain from_rect(typename LegionRuntime::Arrays::Rect<DIM> r);
315 
316  template<int DIM>
317  static Domain from_point(typename LegionRuntime::Arrays::Point<DIM> p);
318 
319  template<int DIM>
320  operator LegionRuntime::Arrays::Rect<DIM>(void) const;
321 
322  template<int DIM, typename T> __CUDA_HD__
323  operator Rect<DIM,T>(void) const;
324 
325  template<int DIM, typename T>
326  operator DomainT<DIM,T>(void) const;
327 
328  // Only works for structured DomainPoint.
329  static Domain from_domain_point(const DomainPoint &p);
330 
331  // No longer supported
332  //Realm::IndexSpace get_index_space(void) const;
333 
334  __CUDA_HD__
335  bool is_valid(void) const;
336 
337  bool contains(const DomainPoint &point) const;
338 
339  // This will only check the bounds and not the sparsity map
340  __CUDA_HD__
341  bool contains_bounds_only(const DomainPoint &point) const;
342 
343  __CUDA_HD__
344  int get_dim(void) const;
345 
346  bool empty(void) const;
347 
348  size_t get_volume(void) const;
349 
350  __CUDA_HD__
351  DomainPoint lo(void) const;
352 
353  __CUDA_HD__
354  DomainPoint hi(void) const;
355 
356  // Intersects this Domain with another Domain and returns the result.
357  Domain intersection(const Domain &other) const;
358 
359  // Returns the bounding box for this Domain and a point.
360  // WARNING: only works with structured Domain.
361  Domain convex_hull(const DomainPoint &p) const;
362 
363  template <int DIM>
364  LegionRuntime::Arrays::Rect<DIM> get_rect(void) const;
365 
367  public:
368  DomainPointIterator(const Domain& d);
370 
371  bool step(void);
372 
373  operator bool(void) const;
374  DomainPoint& operator*(void);
375  DomainPointIterator& operator=(const DomainPointIterator &rhs);
376  DomainPointIterator& operator++(void);
377  DomainPointIterator operator++(int /*i am postfix*/);
378  public:
379  DomainPoint p;
380  // Note: GCC 4.9 breaks even with C++11, so for now peg this on
381  // C++14 until we deprecate GCC 4.9 support.
382 #if __cplusplus >= 201402L
383  // Realm's iterators are copyable by value so we can just always
384  // copy them in and out of some buffers
385  static_assert(std::is_trivially_copyable<
386  Realm::IndexSpaceIterator<MAX_RECT_DIM,coord_t> >::value, "very bad");
387  static_assert(std::is_trivially_copyable<
388  Realm::PointInRectIterator<MAX_RECT_DIM,coord_t> >::value,"very bad");
389 #endif
390  uint8_t is_iterator[
391  sizeof(Realm::IndexSpaceIterator<MAX_RECT_DIM,coord_t>)];
392  uint8_t rect_iterator[
393  sizeof(Realm::PointInRectIterator<MAX_RECT_DIM,coord_t>)];
394  TypeTag is_type;
395  bool is_valid, rect_valid;
396  };
397  protected:
398  public:
399  IDType is_id;
400  // For Realm index spaces we need to have a type tag to know
401  // what the type of the original sparsity map was
402  // Without it you can get undefined behavior trying to interpret
403  // the sparsity map incorrectly. This doesn't matter for the bounds
404  // data because we've done the conversion for ourselves.
405  // Technically this is redundant with the dimension since it also
406  // encodes the dimension, but we'll keep them separate for now for
407  // backwards compatibility
408  TypeTag is_type;
409 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
410  // Work around an internal nvcc bug by marking this volatile
411  volatile
412 #endif
413  int dim;
414  coord_t rect_data[2 * MAX_RECT_DIM];
415  private:
416  // Helper functor classes for demux-ing templates when we have
417  // non-trivial sparsity maps with unusual types
418  // User's should never need to look at these hence they are private
419  template<typename T> __CUDA_HD__
420  static inline coord_t check_for_overflow(const T &value);
421  struct ContainsFunctor {
422  public:
423  ContainsFunctor(const Domain &d, const DomainPoint &p, bool &res)
424  : domain(d), point(p), result(res) { }
425  template<typename N, typename T>
426  static inline void demux(ContainsFunctor *functor)
427  {
428  DomainT<N::N,T> is = functor->domain;
429  Point<N::N,T> p = functor->point;
430  functor->result = is.contains(p);
431  }
432  public:
433  const Domain &domain;
434  const DomainPoint &point;
435  bool &result;
436  };
437  struct VolumeFunctor {
438  public:
439  VolumeFunctor(const Domain &d, size_t &r)
440  : domain(d), result(r) { }
441  template<typename N, typename T>
442  static inline void demux(VolumeFunctor *functor)
443  {
444  DomainT<N::N,T> is = functor->domain;
445  functor->result = is.volume();
446  }
447  public:
448  const Domain &domain;
449  size_t &result;
450  };
451  struct IntersectionFunctor {
452  public:
453  IntersectionFunctor(const Domain &l, const Domain &r, Domain &res)
454  : lhs(l), rhs(r), result(res) { }
455  public:
456  template<typename N, typename T>
457  static inline void demux(IntersectionFunctor *functor)
458  {
459  DomainT<N::N,T> is1 = functor->lhs;
460  DomainT<N::N,T> is2 = functor->rhs;
461  Realm::ProfilingRequestSet dummy_requests;
462  DomainT<N::N,T> temp;
463  Internal::LgEvent wait_on(
464  DomainT<N::N,T>::compute_intersection(is1, is2,
465  temp, dummy_requests));
466  if (wait_on.exists())
467  wait_on.wait();
468  functor->result = Domain(temp.tighten());
469  temp.destroy();
470  }
471  public:
472  const Domain &lhs;
473  const Domain &rhs;
474  Domain &result;
475  };
476  struct IteratorInitFunctor {
477  public:
478  IteratorInitFunctor(const Domain &d, DomainPointIterator &i)
479  : domain(d), iterator(i) { }
480  public:
481  template<typename N, typename T>
482  static inline void demux(IteratorInitFunctor *functor)
483  {
484  DomainT<N::N,T> is = functor->domain;
485  Realm::IndexSpaceIterator<N::N,T> is_itr(is);
486  static_assert(sizeof(is_itr) <=
487  sizeof(functor->iterator.is_iterator), "very bad");
488  functor->iterator.is_valid = is_itr.valid;
489  if (is_itr.valid)
490  {
491  // Always use coord_t for the rect so we don't demux unnecessarily
492  Realm::Rect<N::N,coord_t> rect = is_itr.rect;
493  Realm::PointInRectIterator<N::N,coord_t> rect_itr(rect);
494  static_assert(sizeof(rect_itr) <=
495  sizeof(functor->iterator.rect_iterator), "very bad");
496  assert(rect_itr.valid);
497  functor->iterator.rect_valid = true;
498  functor->iterator.p = rect_itr.p;
499  memcpy(functor->iterator.rect_iterator, &rect_itr, sizeof(rect_itr));
500  memcpy(functor->iterator.is_iterator, &is_itr, sizeof(is_itr));
501  }
502  else
503  functor->iterator.rect_valid = false; \
504  }
505  public:
506  const Domain &domain;
507  DomainPointIterator &iterator;
508  };
509  struct IteratorStepFunctor {
510  public:
511  IteratorStepFunctor(DomainPointIterator &i)
512  : iterator(i) { }
513  public:
514  template<typename N, typename T>
515  static inline void demux(IteratorStepFunctor *functor)
516  {
517  // We already know the rect iterator is not valid here
518 #ifdef DEBUG_LEGION
519  assert(!functor->iterator.rect_valid);
520 #endif
521  Realm::IndexSpaceIterator<N::N,T> is_itr;
522  memcpy(&is_itr, functor->iterator.is_iterator, sizeof(is_itr));
523  is_itr.step(); \
524  functor->iterator.is_valid = is_itr.valid;
525  if (is_itr.valid)
526  {
527  // Convert to rect with coord_t
528  Realm::Rect<N::N,coord_t> rect = is_itr.rect;
529  Realm::PointInRectIterator<N::N,coord_t> new_rectitr(rect);
530 #ifdef DEBUG_LEGION
531  assert(new_rectitr.valid);
532 #endif
533  functor->iterator.rect_valid = true;
534  functor->iterator.p = new_rectitr.p;
535  memcpy(functor->iterator.rect_iterator, &new_rectitr,
536  sizeof(new_rectitr));
537  memcpy(functor->iterator.is_iterator, &is_itr, sizeof(is_itr));
538  }
539  }
540  public:
541  DomainPointIterator &iterator;
542  };
543  };
544 
545  template<int DIM, typename COORD_T = coord_t>
547  private:
548  static_assert(DIM > 0, "DIM must be positive");
549  static_assert(std::is_integral<COORD_T>::value, "must be integral type");
550  public:
551  __CUDA_HD__
552  PointInRectIterator(void);
553  __CUDA_HD__
554  PointInRectIterator(const Rect<DIM,COORD_T> &r,
555  bool column_major_order = true);
556  public:
557  __CUDA_HD__
558  inline bool valid(void) const;
559  __CUDA_HD__
560  inline bool step(void);
561  public:
562  __CUDA_HD__
563  inline bool operator()(void) const;
564  __CUDA_HD__
565  inline Point<DIM,COORD_T> operator*(void) const;
566  __CUDA_HD__
567  inline COORD_T operator[](unsigned index) const;
568  __CUDA_HD__
569  inline const Point<DIM,COORD_T>* operator->(void) const;
570  __CUDA_HD__
571  inline PointInRectIterator<DIM,COORD_T>& operator++(void);
572  __CUDA_HD__
573  inline PointInRectIterator<DIM,COORD_T> operator++(int/*postfix*/);
574  protected:
575  Realm::PointInRectIterator<DIM,COORD_T> itr;
576  };
577 
578  template<int DIM, typename COORD_T = coord_t>
580  private:
581  static_assert(DIM > 0, "DIM must be positive");
582  static_assert(std::is_integral<COORD_T>::value, "must be integral type");
583  public:
584  RectInDomainIterator(void);
585  RectInDomainIterator(const DomainT<DIM,COORD_T> &d);
586  public:
587  inline bool valid(void) const;
588  inline bool step(void);
589  public:
590  inline bool operator()(void) const;
591  inline Rect<DIM,COORD_T> operator*(void) const;
592  inline const Rect<DIM,COORD_T>* operator->(void) const;
593  inline RectInDomainIterator<DIM,COORD_T>& operator++(void);
594  inline RectInDomainIterator<DIM,COORD_T> operator++(int/*postfix*/);
595  protected:
596  Realm::IndexSpaceIterator<DIM,COORD_T> itr;
597  };
598 
599  template<int DIM, typename COORD_T = coord_t>
601  private:
602  static_assert(DIM > 0, "DIM must be positive");
603  static_assert(std::is_integral<COORD_T>::value, "must be integral type");
604  public:
605  PointInDomainIterator(void);
606  PointInDomainIterator(const DomainT<DIM,COORD_T> &d,
607  bool column_major_order = true);
608  public:
609  inline bool valid(void) const;
610  inline bool step(void);
611  public:
612  inline bool operator()(void) const;
613  inline Point<DIM,COORD_T> operator*(void) const;
614  inline COORD_T operator[](unsigned index) const;
615  inline const Point<DIM,COORD_T>* operator->(void) const;
616  inline PointInDomainIterator& operator++(void);
617  inline PointInDomainIterator operator++(int /*postfix*/);
618  protected:
621  bool column_major;
622  };
623 
630  public:
631  __CUDA_HD__
632  DomainTransform(void);
633  __CUDA_HD__
634  DomainTransform(const DomainTransform &rhs);
635  template<int M, int N, typename T> __CUDA_HD__
636  DomainTransform(const Transform<M,N,T> &rhs);
637  public:
638  __CUDA_HD__
639  DomainTransform& operator=(const DomainTransform &rhs);
640  template<int M, int N, typename T> __CUDA_HD__
641  DomainTransform& operator=(const Transform<M,N,T> &rhs);
642  __CUDA_HD__
643  bool operator==(const DomainTransform &rhs) const;
644  __CUDA_HD__
645  bool operator!=(const DomainTransform &rhs) const;
646  public:
647  template<int M, int N, typename T> __CUDA_HD__
648  operator Transform<M,N,T>(void) const;
649  public:
650  __CUDA_HD__
651  DomainPoint operator*(const DomainPoint &p) const;
652  __CUDA_HD__
653  Domain operator*(const Domain &domain) const;
654  __CUDA_HD__
655  DomainTransform operator*(const DomainTransform &transform) const;
656  public:
657  __CUDA_HD__
658  bool is_identity(void) const;
659  public:
660  int m, n;
661  coord_t matrix[LEGION_MAX_DIM * LEGION_MAX_DIM];
662  };
663 
670  public:
671  __CUDA_HD__
672  DomainAffineTransform(void);
673  __CUDA_HD__
674  DomainAffineTransform(const DomainAffineTransform &rhs);
675  __CUDA_HD__
676  DomainAffineTransform(const DomainTransform &t, const DomainPoint &p);
677  template<int M, int N, typename T> __CUDA_HD__
678  DomainAffineTransform(const AffineTransform<M,N,T> &transform);
679  public:
680  __CUDA_HD__
681  DomainAffineTransform& operator=(const DomainAffineTransform &rhs);
682  template<int M, int N, typename T> __CUDA_HD__
683  DomainAffineTransform& operator=(const AffineTransform<M,N,T> &rhs);
684  __CUDA_HD__
685  bool operator==(const DomainAffineTransform &rhs) const;
686  __CUDA_HD__
687  bool operator!=(const DomainAffineTransform &rhs) const;
688  public:
689  template<int M, int N, typename T> __CUDA_HD__
690  operator AffineTransform<M,N,T>(void) const;
691  public:
692  // Apply the transformation to a point
693  __CUDA_HD__
694  DomainPoint operator[](const DomainPoint &p) const;
695  // Test for the identity
696  __CUDA_HD__
697  bool is_identity(void) const;
698  public:
699  DomainTransform transform;
700  DomainPoint offset;
701  };
702 
709  public:
710  __CUDA_HD__
711  DomainScaleTransform(void);
712  __CUDA_HD__
713  DomainScaleTransform(const DomainScaleTransform &rhs);
714  __CUDA_HD__
715  DomainScaleTransform(const DomainTransform &transform,
716  const Domain &extent, const DomainPoint &divisor);
717  template<int M, int N, typename T> __CUDA_HD__
718  DomainScaleTransform(const ScaleTransform<M,N,T> &transform);
719  public:
720  __CUDA_HD__
721  DomainScaleTransform& operator=(const DomainScaleTransform &rhs);
722  template<int M, int N, typename T> __CUDA_HD__
723  DomainScaleTransform& operator=(const ScaleTransform<M,N,T> &rhs);
724  __CUDA_HD__
725  bool operator==(const DomainScaleTransform &rhs) const;
726  __CUDA_HD__
727  bool operator!=(const DomainScaleTransform &rhs) const;
728  public:
729  template<int M, int N, typename T> __CUDA_HD__
730  operator ScaleTransform<M,N,T>(void) const;
731  public:
732  // Apply the transformation to a point
733  __CUDA_HD__
734  Domain operator[](const DomainPoint &p) const;
735  // Test for the identity
736  __CUDA_HD__
737  bool is_identity(void) const;
738  public:
739  DomainTransform transform;
740  Domain extent;
741  DomainPoint divisor;
742  };
743 
752  template<typename FT, PrivilegeMode PM = LEGION_READ_WRITE>
753  class Span {
754  public:
755  class iterator {
756  public:
757  // explicitly set iterator traits
758  typedef std::random_access_iterator_tag iterator_category;
759  typedef FT value_type;
760  typedef std::ptrdiff_t difference_type;
761  typedef FT *pointer;
762  typedef FT& reference;
763 
764  iterator(void) : ptr(NULL), stride(0) { }
765  private:
766  iterator(uint8_t *p, size_t s) : ptr(p), stride(s) { }
767  public:
768  inline iterator& operator=(const iterator &rhs)
769  { ptr = rhs.ptr; stride = rhs.stride; return *this; }
770  inline iterator& operator+=(int rhs) { ptr += stride; return *this; }
771  inline iterator& operator-=(int rhs) { ptr -= stride; return *this; }
772  inline FT& operator*(void) const
773  {
774  FT *result = NULL;
775  static_assert(sizeof(result) == sizeof(ptr), "C++ is dumb");
776  memcpy(&result, &ptr, sizeof(result));
777  return *result;
778  }
779  inline FT* operator->(void) const
780  {
781  FT *result = NULL;
782  static_assert(sizeof(result) == sizeof(ptr), "C++ is dumb");
783  memcpy(&result, &ptr, sizeof(result));
784  return result;
785  }
786  inline FT& operator[](int rhs) const
787  {
788  FT *result = NULL;
789  uint8_t *ptr2 = ptr + rhs * stride;
790  static_assert(sizeof(result) == sizeof(ptr2), "C++ is dumb");
791  memcpy(&result, &ptr2, sizeof(result));
792  return *result;
793  }
794  public:
795  inline iterator& operator++(void) { ptr += stride; return *this; }
796  inline iterator& operator--(void) { ptr -= stride; return *this; }
797  inline iterator operator++(int)
798  { iterator it(ptr, stride); ptr += stride; return it; }
799  inline iterator operator--(int)
800  { iterator it(ptr, stride); ptr -= stride; return it; }
801  inline iterator operator+(int rhs) const
802  { return iterator(ptr + stride * rhs, stride); }
803  inline iterator operator-(int rhs) const
804  { return iterator(ptr - stride * rhs, stride); }
805  public:
806  inline bool operator==(const iterator &rhs) const
807  { return (ptr == rhs.ptr); }
808  inline bool operator!=(const iterator &rhs) const
809  { return (ptr != rhs.ptr); }
810  inline bool operator<(const iterator &rhs) const
811  { return (ptr < rhs.ptr); }
812  inline bool operator>(const iterator &rhs) const
813  { return (ptr > rhs.ptr); }
814  inline bool operator<=(const iterator &rhs) const
815  { return (ptr <= rhs.ptr); }
816  inline bool operator>=(const iterator &rhs) const
817  { return (ptr >= rhs.ptr); }
818  private:
819  uint8_t *ptr;
820  size_t stride;
821  };
823  public:
824  // explicitly set iterator traits
825  typedef std::random_access_iterator_tag iterator_category;
826  typedef FT value_type;
827  typedef std::ptrdiff_t difference_type;
828  typedef FT *pointer;
829  typedef FT& reference;
830 
831  reverse_iterator(void) : ptr(NULL), stride(0) { }
832  private:
833  reverse_iterator(uint8_t *p, size_t s) : ptr(p), stride(s) { }
834  public:
835  inline reverse_iterator& operator=(const reverse_iterator &rhs)
836  { ptr = rhs.ptr; stride = rhs.stride; return *this; }
837  inline reverse_iterator& operator+=(int rhs)
838  { ptr -= stride; return *this; }
839  inline reverse_iterator& operator-=(int rhs)
840  { ptr += stride; return *this; }
841  inline FT& operator*(void) const
842  {
843  FT *result = NULL;
844  static_assert(sizeof(result) == sizeof(ptr), "C++ is dumb");
845  memcpy(&result, &ptr, sizeof(result));
846  return *result;
847  }
848  inline FT* operator->(void) const
849  {
850  FT *result = NULL;
851  static_assert(sizeof(result) == sizeof(ptr), "C++ is dumb");
852  memcpy(&result, &ptr, sizeof(result));
853  return result;
854  }
855  inline FT& operator[](int rhs) const
856  {
857  FT *result = NULL;
858  uint8_t *ptr2 = ptr - rhs * stride;
859  static_assert(sizeof(result) == sizeof(ptr2), "C++ is dumb");
860  memcpy(&result, &ptr2, sizeof(result));
861  return *result;
862  }
863  public:
864  inline reverse_iterator& operator++(void)
865  { ptr -= stride; return *this; }
866  inline reverse_iterator& operator--(void)
867  { ptr += stride; return *this; }
868  inline reverse_iterator operator++(int)
869  { reverse_iterator it(ptr, stride); ptr -= stride; return it; }
870  inline reverse_iterator operator--(int)
871  { reverse_iterator it(ptr, stride); ptr += stride; return it; }
872  inline reverse_iterator operator+(int rhs) const
873  { return reverse_iterator(ptr - stride * rhs, stride); }
874  inline reverse_iterator operator-(int rhs) const
875  { return reverse_iterator(ptr + stride * rhs, stride); }
876  public:
877  inline bool operator==(const reverse_iterator &rhs) const
878  { return (ptr == rhs.ptr); }
879  inline bool operator!=(const reverse_iterator &rhs) const
880  { return (ptr != rhs.ptr); }
881  inline bool operator<(const reverse_iterator &rhs) const
882  { return (ptr > rhs.ptr); }
883  inline bool operator>(const reverse_iterator &rhs) const
884  { return (ptr < rhs.ptr); }
885  inline bool operator<=(const reverse_iterator &rhs) const
886  { return (ptr >= rhs.ptr); }
887  inline bool operator>=(const reverse_iterator &rhs) const
888  { return (ptr <= rhs.ptr); }
889  private:
890  uint8_t *ptr;
891  size_t stride;
892  };
893  public:
894  Span(void) : base(NULL), extent(0), stride(0) { }
895  Span(FT *b, size_t e, size_t s = sizeof(FT))
896  : base(NULL), extent(e), stride(s)
897  {
898  static_assert(sizeof(base) == sizeof(b), "C++ is dumb");
899  memcpy(&base, &b, sizeof(base));
900  }
901  public:
902  inline iterator begin(void) const { return iterator(base, stride); }
903  inline iterator end(void) const
904  { return iterator(base + extent*stride, stride); }
905  inline reverse_iterator rbegin(void) const
906  { return reverse_iterator(base + (extent-1) * stride, stride); }
907  inline reverse_iterator rend(void) const
908  { return reverse_iterator(base - stride, stride); }
909  public:
910  inline FT& front(void) const
911  {
912  FT *result = NULL;
913  static_assert(sizeof(result) == sizeof(base), "C++ is dumb");
914  memcpy(&result, &base, sizeof(result));
915  return *result;
916  }
917  inline FT& back(void) const
918  {
919  FT *result = NULL;
920  uint8_t *ptr = base + (extent-1)*stride;
921  static_assert(sizeof(result) == sizeof(ptr), "C++ is dumb");
922  memcpy(&result, &ptr, sizeof(result));
923  return *result;
924  }
925  inline FT& operator[](int index) const
926  {
927  FT *result = NULL;
928  uint8_t *ptr = base + index * stride;
929  static_assert(sizeof(result) == sizeof(ptr), "C++ is dumb");
930  memcpy(&result, &ptr, sizeof(result));
931  return *result;
932  }
933  inline FT* data(void) const
934  {
935  FT *result = NULL;
936  static_assert(sizeof(result) == sizeof(base), "C++ is dumb");
937  memcpy(&result, &base, sizeof(result));
938  return result;
939  }
940  inline uintptr_t get_base(void) const { return uintptr_t(base); }
941  public:
942  inline size_t size(void) const { return extent; }
943  inline size_t step(void) const { return stride; }
944  inline bool empty(void) const { return (extent == 0); }
945  private:
946  uint8_t *base;
947  size_t extent; // number of elements
948  size_t stride; // byte stride
949  };
950 
951 }; // namespace Legion
952 
953 #include "legion/legion_domain.inl"
954 
955 #endif // __LEGION_DOMAIN_H__
956 
Definition: legion_domain.h:366
Definition: legion_domain.h:822
Definition: legion_domain.h:211
Definition: legion_domain.h:579
Definition: legion_domain.h:629
Definition: legion_domain.h:260
Definition: legion_domain.h:46
Definition: legion_domain.h:708
Definition: legion_domain.h:753
Definition: legion_domain.h:132
Definition: legion_domain.h:600
Definition: legion_domain.h:546
Definition: legion_domain.h:92
Definition: legion_domain.h:669
Definition: legion_domain.h:755