Legion Runtime
Loading...
Searching...
No Matches
geometry.h
Go to the documentation of this file.
1/* Copyright 2026 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_GEOMETRY_H__
17#define __LEGION_GEOMETRY_H__
18
24#include <cstring>
25#include "legion/api/types.h"
26
27namespace Legion {
28
35 public:
36 static constexpr int MAX_POINT_DIM = LEGION_MAX_DIM;
37
38 __LEGION_CUDA_HD__
39 DomainPoint(void);
40 __LEGION_CUDA_HD__
41 DomainPoint(coord_t index);
42 __LEGION_CUDA_HD__
43 DomainPoint(const DomainPoint& rhs);
44 template<int DIM, typename T>
45 __LEGION_CUDA_HD__ DomainPoint(const Point<DIM, T>& rhs);
46
47 template<int DIM, typename T>
48 __LEGION_CUDA_HD__ operator Point<DIM, T>(void) const;
49
50 __LEGION_CUDA_HD__
51 DomainPoint& operator=(const DomainPoint& rhs);
52 template<int DIM, typename T>
53 __LEGION_CUDA_HD__ DomainPoint& operator=(const Point<DIM, T>& rhs);
54 __LEGION_CUDA_HD__
55 bool operator==(const DomainPoint& rhs) const;
56 __LEGION_CUDA_HD__
57 bool operator!=(const DomainPoint& rhs) const;
58 __LEGION_CUDA_HD__
59 bool operator<(const DomainPoint& rhs) const;
60
61 __LEGION_CUDA_HD__
62 DomainPoint operator+(coord_t scalar) const;
63 __LEGION_CUDA_HD__
64 DomainPoint operator+(const DomainPoint& rhs) const;
65 __LEGION_CUDA_HD__
66 DomainPoint& operator+=(coord_t scalar);
67 __LEGION_CUDA_HD__
68 DomainPoint& operator+=(const DomainPoint& rhs);
69
70 __LEGION_CUDA_HD__
71 DomainPoint operator-(coord_t scalar) const;
72 __LEGION_CUDA_HD__
73 DomainPoint operator-(const DomainPoint& rhs) const;
74 __LEGION_CUDA_HD__
75 DomainPoint& operator-=(coord_t scalar);
76 __LEGION_CUDA_HD__
77 DomainPoint& operator-=(const DomainPoint& rhs);
78
79 __LEGION_CUDA_HD__
80 DomainPoint operator*(coord_t scalar) const;
81 __LEGION_CUDA_HD__
82 DomainPoint operator*(const DomainPoint& rhs) const;
83 __LEGION_CUDA_HD__
84 DomainPoint& operator*=(coord_t scalar);
85 __LEGION_CUDA_HD__
86 DomainPoint& operator*=(const DomainPoint& rhs);
87
88 __LEGION_CUDA_HD__
89 DomainPoint operator/(coord_t scalar) const;
90 __LEGION_CUDA_HD__
91 DomainPoint operator/(const DomainPoint& rhs) const;
92 __LEGION_CUDA_HD__
93 DomainPoint& operator/=(coord_t scalar);
94 __LEGION_CUDA_HD__
95 DomainPoint& operator/=(const DomainPoint& rhs);
96
97 __LEGION_CUDA_HD__
98 DomainPoint operator%(coord_t scalar) const;
99 __LEGION_CUDA_HD__
100 DomainPoint operator%(const DomainPoint& rhs) const;
101 __LEGION_CUDA_HD__
102 DomainPoint& operator%=(coord_t scalar);
103 __LEGION_CUDA_HD__
104 DomainPoint& operator%=(const DomainPoint& rhs);
105
106 __LEGION_CUDA_HD__
107 coord_t& operator[](unsigned index);
108 __LEGION_CUDA_HD__
109 const coord_t& operator[](unsigned index) const;
110
112 __LEGION_CUDA_HD__
113 bool operator()(const DomainPoint& a, const DomainPoint& b) const
114 {
115 if (a.dim < b.dim)
116 return true;
117 if (a.dim > b.dim)
118 return false;
119 for (int i = 0; (i == 0) || (i < a.dim); i++)
120 {
121 if (a.point_data[i] < b.point_data[i])
122 return true;
123 if (a.point_data[i] > b.point_data[i])
124 return false;
125 }
126 return false;
127 }
128 };
129
130 __LEGION_CUDA_HD__
131 Color get_color(void) const;
132 __LEGION_CUDA_HD__
133 coord_t get_index(void) const;
134 __LEGION_CUDA_HD__
135 int get_dim(void) const;
136 __LEGION_CUDA_HD__
137 inline bool exists(void) const { return (get_dim() > 0); }
138
139 __LEGION_CUDA_HD__
140 bool is_null(void) const;
141
142 __LEGION_CUDA_HD__
143 static DomainPoint nil(void);
144 protected:
145 template<typename T>
146 __LEGION_CUDA_HD__ static inline coord_t check_for_overflow(const T& value);
147 public:
148 int dim;
149 coord_t point_data[MAX_POINT_DIM];
150
151 friend std::ostream& operator<<(std::ostream& os, const DomainPoint& dp);
152 };
153
159 class Domain {
160 public:
161 // Keep this in sync with legion_domain_max_rect_dim_t
162 // in legion_config.h
163 static constexpr int MAX_RECT_DIM = LEGION_MAX_DIM;
164 __LEGION_CUDA_HD__
165 Domain(void);
166 __LEGION_CUDA_HD__
167 Domain(const Domain& other);
168 __LEGION_CUDA_HD__
169 Domain(Domain&& other) noexcept;
170 __LEGION_CUDA_HD__
171 Domain(const DomainPoint& lo, const DomainPoint& hi);
172
173 template<int DIM, typename T>
174 __LEGION_CUDA_HD__ Domain(const Rect<DIM, T>& other);
175
176 template<int DIM, typename T>
177 __LEGION_CUDA_HD__ Domain(const DomainT<DIM, T>& other);
178
179 __LEGION_CUDA_HD__
180 Domain& operator=(const Domain& other);
181 __LEGION_CUDA_HD__
182 Domain& operator=(Domain&& other) noexcept;
183 template<int DIM, typename T>
184 __LEGION_CUDA_HD__ Domain& operator=(const Rect<DIM, T>& other);
185 template<int DIM, typename T>
186 __LEGION_CUDA_HD__ Domain& operator=(const DomainT<DIM, T>& other);
187
188 __LEGION_CUDA_HD__
189 bool operator==(const Domain& rhs) const;
190 __LEGION_CUDA_HD__
191 bool operator!=(const Domain& rhs) const;
192 __LEGION_CUDA_HD__
193 bool operator<(const Domain& rhs) const;
194
195 __LEGION_CUDA_HD__
196 Domain operator+(const DomainPoint& point) const;
197 __LEGION_CUDA_HD__
198 Domain& operator+=(const DomainPoint& point);
199
200 __LEGION_CUDA_HD__
201 Domain operator-(const DomainPoint& point) const;
202 __LEGION_CUDA_HD__
203 Domain& operator-=(const DomainPoint& point);
204
205 static const Domain NO_DOMAIN;
206
207 __LEGION_CUDA_HD__
208 bool exists(void) const;
209 __LEGION_CUDA_HD__
210 bool dense(void) const;
211
212 template<int DIM, typename T>
213 __LEGION_CUDA_HD__ Rect<DIM, T> bounds(void) const;
214
215 template<int DIM, typename T>
216 __LEGION_CUDA_HD__ operator Rect<DIM, T>(void) const;
217
218 template<int DIM, typename T>
219 operator DomainT<DIM, T>(void) const;
220
221 // Only works for structured DomainPoint.
222 static Domain from_domain_point(const DomainPoint& p);
223
224 // No longer supported
225 // Realm::IndexSpace get_index_space(void) const;
226
227 __LEGION_CUDA_HD__
228 bool is_valid(void) const;
229
230 bool contains(const DomainPoint& point) const;
231
232 // This will only check the bounds and not the sparsity map
233 __LEGION_CUDA_HD__
234 bool contains_bounds_only(const DomainPoint& point) const;
235
236 __LEGION_CUDA_HD__
237 int get_dim(void) const;
238
239 bool empty(void) const;
240
241 // Will destroy the underlying Realm index space
242 void destroy(Realm::Event wait_on = Realm::Event::NO_EVENT);
243
244 size_t get_volume(void) const;
245
246 __LEGION_CUDA_HD__
247 DomainPoint lo(void) const;
248
249 __LEGION_CUDA_HD__
250 DomainPoint hi(void) const;
251
252 // Intersects this Domain with another Domain and returns the result.
253 Domain intersection(const Domain& other) const;
254
255 // Returns the bounding box for this Domain and a point.
256 // WARNING: only works with structured Domain.
257 Domain convex_hull(const DomainPoint& p) const;
258 private:
259 struct IteratorInitFunctor;
260 struct IteratorStepFunctor;
261 public:
263 public:
264 DomainPointIterator(const Domain& d, bool fortran_order = true);
266
267 bool step(void);
268
269 operator bool(void) const;
270 DomainPoint& operator*(void);
271 DomainPointIterator& operator=(const DomainPointIterator& rhs);
272 DomainPointIterator& operator++(void);
273 DomainPointIterator operator++(int /*i am postfix*/);
274 public:
275 DomainPoint p;
276 private:
277 friend struct IteratorInitFunctor;
278 friend struct IteratorStepFunctor;
279 // Realm's iterators are copyable by value so we can just always
280 // copy them in and out of some buffers
281 static_assert(std::is_trivially_copyable<
282 Realm::IndexSpaceIterator<MAX_RECT_DIM, coord_t> >::value);
283 uint8_t
284 is_iterator[sizeof(Realm::IndexSpaceIterator<MAX_RECT_DIM, coord_t>)];
285 DomainPoint rect_lo, rect_hi;
286 TypeTag is_type = 0;
287 bool iter_valid = false;
288 bool rect_valid = false;
289 bool fortran_order = true;
290 };
291 protected:
292 public:
293 IDType is_id;
294 // For Realm index spaces we need to have a type tag to know
295 // what the type of the original sparsity map was
296 // Without it you can get undefined behavior trying to interpret
297 // the sparsity map incorrectly. This doesn't matter for the bounds
298 // data because we've done the conversion for ourselves.
299 // Technically this is redundant with the dimension since it also
300 // encodes the dimension, but we'll keep them separate for now for
301 // backwards compatibility
302 TypeTag is_type;
303 int dim;
304 coord_t rect_data[2 * MAX_RECT_DIM];
305 private:
306 // Helper functor classes for demux-ing templates when we have
307 // non-trivial sparsity maps with unusual types
308 // User's should never need to look at these hence they are private
309 template<typename T>
310 __LEGION_CUDA_HD__ static inline coord_t check_for_overflow(const T& value);
311 struct ContainsFunctor {
312 public:
313 ContainsFunctor(const Domain& d, const DomainPoint& p, bool& res)
314 : domain(d), point(p), result(res)
315 { }
316 template<typename N, typename T>
317 static inline void demux(ContainsFunctor* functor)
318 {
319 DomainT<N::N, T> is = functor->domain;
320 Point<N::N, T> p = functor->point;
321 functor->result = is.contains(p);
322 }
323 public:
324 const Domain& domain;
325 const DomainPoint& point;
326 bool& result;
327 };
328 struct VolumeFunctor {
329 public:
330 VolumeFunctor(const Domain& d, size_t& r) : domain(d), result(r) { }
331 template<typename N, typename T>
332 static inline void demux(VolumeFunctor* functor)
333 {
334 DomainT<N::N, T> is = functor->domain;
335 functor->result = is.volume();
336 }
337 public:
338 const Domain& domain;
339 size_t& result;
340 };
341 struct DestroyFunctor {
342 public:
343 DestroyFunctor(const Domain& d, Realm::Event e) : domain(d), event(e) { }
344 template<typename N, typename T>
345 static inline void demux(DestroyFunctor* functor)
346 {
347 DomainT<N::N, T> is = functor->domain;
348 is.destroy(functor->event);
349 }
350 public:
351 const Domain& domain;
352 const Realm::Event event;
353 };
354 struct IntersectionFunctor {
355 public:
356 IntersectionFunctor(const Domain& l, const Domain& r, Domain& res)
357 : lhs(l), rhs(r), result(res)
358 { }
359 public:
360 template<typename N, typename T>
361 static inline void demux(IntersectionFunctor* functor)
362 {
363 DomainT<N::N, T> is1 = functor->lhs;
364 DomainT<N::N, T> is2 = functor->rhs;
365 assert(is1.dense() || is2.dense());
366 // Intersect the index spaces
367 DomainT<N::N, T> result;
368 result.bounds = is1.bounds.intersection(is2.bounds);
369 if (!result.bounds.empty())
370 {
371 if (!is1.dense())
372 result.sparsity = is1.sparsity;
373 else if (!is2.dense())
374 result.sparsity = is2.sparsity;
375 else
376 result.sparsity.id = 0;
377 }
378 else
379 result.sparsity.id = 0;
380 functor->result = Domain(result);
381 }
382 public:
383 const Domain& lhs;
384 const Domain& rhs;
385 Domain& result;
386 };
387 struct IteratorInitFunctor {
388 public:
389 IteratorInitFunctor(const Domain& d, DomainPointIterator& i)
390 : domain(d), iterator(i)
391 { }
392 public:
393 template<typename N, typename T>
394 static inline void demux(IteratorInitFunctor* functor)
395 {
396 DomainT<N::N, T> is = functor->domain;
397 Realm::IndexSpaceIterator<N::N, T> is_itr(is);
398 static_assert(N::N <= LEGION_MAX_DIM);
399 static_assert(sizeof(T) <= sizeof(coord_t));
400 static_assert(sizeof(is_itr) <= sizeof(functor->iterator.is_iterator));
401 functor->iterator.rect_valid = is_itr.valid;
402 if (is_itr.valid)
403 {
404 functor->iterator.rect_lo = is_itr.rect.lo;
405 functor->iterator.rect_hi = is_itr.rect.hi;
406 functor->iterator.p = is_itr.rect.lo;
407 if (is_itr.step())
408 {
409 functor->iterator.iter_valid = true;
410 std::memcpy(functor->iterator.is_iterator, &is_itr, sizeof(is_itr));
411 }
412 else
413 functor->iterator.iter_valid = false;
414 }
415 else
416 functor->iterator.iter_valid = false;
417 }
418 public:
419 const Domain& domain;
420 DomainPointIterator& iterator;
421 };
422 struct IteratorStepFunctor {
423 public:
424 IteratorStepFunctor(DomainPointIterator& i) : iterator(i) { }
425 public:
426 template<typename N, typename T>
427 static inline void demux(IteratorStepFunctor* functor)
428 {
429 Realm::IndexSpaceIterator<N::N, T> is_itr;
430 std::memcpy(&is_itr, functor->iterator.is_iterator, sizeof(is_itr));
431 legion_assert(is_itr.valid);
432 functor->iterator.p = is_itr.rect.lo;
433 functor->iterator.rect_lo = is_itr.rect.lo;
434 functor->iterator.rect_hi = is_itr.rect.hi;
435 is_itr.step();
436 functor->iterator.iter_valid = is_itr.valid;
437 if (is_itr.valid)
438 std::memcpy(functor->iterator.is_iterator, &is_itr, sizeof(is_itr));
439 }
440 public:
441 DomainPointIterator& iterator;
442 };
443 };
444
445 template<int DIM, typename COORD_T = coord_t>
447 private:
448 static_assert(DIM > 0, "DIM must be positive");
449 static_assert(std::is_integral<COORD_T>::value, "must be integral type");
450 public:
451 __LEGION_CUDA_HD__
453 __LEGION_CUDA_HD__
455 const Rect<DIM, COORD_T>& r, bool column_major_order = true);
456 public:
457 __LEGION_CUDA_HD__
458 inline bool valid(void) const;
459 __LEGION_CUDA_HD__
460 inline bool step(void);
461 public:
462 __LEGION_CUDA_HD__
463 inline bool operator()(void) const;
464 __LEGION_CUDA_HD__
465 inline Point<DIM, COORD_T> operator*(void) const;
466 __LEGION_CUDA_HD__
467 inline COORD_T operator[](unsigned index) const;
468 __LEGION_CUDA_HD__
469 inline const Point<DIM, COORD_T>* operator->(void) const;
470 __LEGION_CUDA_HD__
471 inline PointInRectIterator<DIM, COORD_T>& operator++(void);
472 __LEGION_CUDA_HD__
473 inline PointInRectIterator<DIM, COORD_T> operator++(int /*postfix*/);
474 protected:
475 Realm::PointInRectIterator<DIM, COORD_T> itr;
476 };
477
478 template<int DIM, typename COORD_T = coord_t>
480 private:
481 static_assert(DIM > 0, "DIM must be positive");
482 static_assert(std::is_integral<COORD_T>::value, "must be integral type");
483 public:
485 RectInDomainIterator(const DomainT<DIM, COORD_T>& d);
486 public:
487 inline bool valid(void) const;
488 inline bool step(void);
489 public:
490 inline bool operator()(void) const;
491 inline Rect<DIM, COORD_T> operator*(void) const;
492 inline const Rect<DIM, COORD_T>* operator->(void) const;
493 inline RectInDomainIterator<DIM, COORD_T>& operator++(void);
494 inline RectInDomainIterator<DIM, COORD_T> operator++(int /*postfix*/);
495 protected:
496 Realm::IndexSpaceIterator<DIM, COORD_T> itr;
497 };
498
499 template<int DIM, typename COORD_T = coord_t>
501 private:
502 static_assert(DIM > 0, "DIM must be positive");
503 static_assert(std::is_integral<COORD_T>::value, "must be integral type");
504 public:
507 const DomainT<DIM, COORD_T>& d, bool column_major_order = true);
508 public:
509 inline bool valid(void) const;
510 inline bool step(void);
511 public:
512 inline bool operator()(void) const;
513 inline Point<DIM, COORD_T> operator*(void) const;
514 inline COORD_T operator[](unsigned index) const;
515 inline const Point<DIM, COORD_T>* operator->(void) const;
516 inline PointInDomainIterator& operator++(void);
517 inline PointInDomainIterator operator++(int /*postfix*/);
518 protected:
519 RectInDomainIterator<DIM, COORD_T> rect_itr;
520 PointInRectIterator<DIM, COORD_T> point_itr;
521 bool column_major;
522 };
523
524} // namespace Legion
525
526#include "legion/api/geometry.inl"
527
528#endif // __LEGION_GEOMETRY_H__
Definition geometry.h:262
Definition geometry.h:159
Definition geometry.h:34
Definition geometry.h:500
Definition geometry.h:446
Definition geometry.h:479
Definition accessors.h:29
Definition geometry.h:111