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