Legion Runtime
Loading...
Searching...
No Matches
types.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_TYPES_H__
17#define __LEGION_TYPES_H__
18
19#include <cassert>
20#include <limits>
21#include <optional>
22#include <functional>
23
24#include "realm.h"
25#include "realm/id.h"
26#include "realm/dynamic_templates.h"
27#include "legion/api/config.h"
28
29// Sanity check that the build knows what it is doing
30static_assert(
31 REALM_MAX_DIM == LEGION_MAX_DIM,
32 "LEGION_MAX_DIM and REALM_MAX_DIM must be the same");
33
34#ifdef LEGION_REDOP_COMPLEX
35#ifdef LEGION_REDOP_HALF
36#define COMPLEX_HALF
37#endif
38#include "mathtypes/complex.h"
39#endif
40
41#ifdef LEGION_REDOP_HALF
42#include "mathtypes/half.h"
43#endif
44
45#ifndef LEGION_DEPRECATED
46// This is from before Legion required c++17
47#define LEGION_DEPRECATED(x) [[deprecated(x)]]
48#endif
49
50// clang-format off
51// Macros for disabling and re-enabling deprecated warnings
52#if defined(__PGIC__)
53// PGI has to go first because it also responds to GCC defines
54#define LEGION_DISABLE_DEPRECATED_WARNINGS \
55 _Pragma("warning (push)") \
56 _Pragma("diag_suppress 1445")
57#define LEGION_REENABLE_DEPRECATED_WARNINGS \
58 _Pragma("warning (pop)")
59#elif defined(__GNUC__)
60#define LEGION_DISABLE_DEPRECATED_WARNINGS \
61 _Pragma("GCC diagnostic push") \
62 _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
63#define LEGION_REENABLE_DEPRECATED_WARNINGS \
64 _Pragma("GCC diagnostic pop")
65#elif defined(__clang__)
66#define LEGION_DISABLE_DEPRECATED_WARNINGS \
67 _Pragma("clang diagnostic push") \
68 _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
69#define LEGION_REENABLE_DEPRECATED_WARNINGS \
70 _Pragma("clang diagnostic pop")
71#elif defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER)
72#define LEGION_DISABLE_DEPRECATED_WARNINGS \
73 _Pragma("warning push") \
74 _Pragma("warning disable 1478")
75#define LEGION_REENABLE_DEPRECATED_WARNINGS \
76 _Pragma("warning pop")
77#else
78#warning "Don't know how to suppress deprecated warnings for this compiler"
79#define LEGION_DISABLE_DEPRECATED_WARNINGS
80#define LEGION_REENABLE_DEPRECATED_WARNINGS
81#endif
82// clang-format on
83
84#ifdef LEGION_DEBUG
85#define legion_assert(expr) assert(expr)
86#ifndef NDEBUG
87#define legion_no_skip_assert(expr) assert(expr)
88#else
89#error \
90 "Why are you trying to build a debug version of Legion while also defining NDEBUG?"
91#endif
92template<typename T1, typename T2>
93inline T1 legion_safe_cast(T2* ptr)
94{
95 T1 result = dynamic_cast<T1>(ptr);
96 legion_assert(result != nullptr);
97 return result;
98}
99#else // !LEGION_DEBUG
100#define legion_assert(expr) ((void)0)
101#define legion_no_skip_assert(expr) ((void)(expr))
102template<typename T1, typename T2>
103inline T1 legion_safe_cast(T2* ptr)
104{
105 return static_cast<T1>(ptr);
106}
107#endif
108
109namespace Legion {
110
111 // Pull C types into the C++ namespace
112 typedef ::realm_id_t IDType;
113 typedef ::legion_privilege_mode_t PrivilegeMode;
114 typedef ::legion_allocate_mode_t AllocateMode;
115 typedef ::legion_coherence_property_t CoherenceProperty;
116 typedef ::legion_region_flags_t RegionFlags;
117 typedef ::legion_projection_type_t ProjectionType;
118 typedef ::legion_partition_kind_t PartitionKind;
119 typedef ::legion_external_resource_t ExternalResource;
120 typedef ::legion_timing_measurement_t TimingMeasurement;
121 typedef ::legion_dependence_type_t DependenceType;
122 typedef ::legion_mappable_type_id_t MappableType;
123 typedef ::legion_file_mode_t LegionFileMode;
124 typedef ::legion_execution_constraint_t ExecutionConstraintKind;
125 typedef ::legion_layout_constraint_t LayoutConstraintKind;
126 typedef ::legion_equality_kind_t EqualityKind;
127 typedef ::legion_dimension_kind_t DimensionKind;
128 typedef ::legion_isa_kind_t ISAKind;
129 typedef ::legion_resource_constraint_t ResourceKind;
130 typedef ::legion_launch_constraint_t LaunchKind;
131 typedef ::legion_specialized_constraint_t SpecializedKind;
132 typedef ::legion_unbounded_pool_scope_t UnboundPoolScope;
133 typedef ::legion_projection_type_t HandleType;
134 typedef ::legion_address_space_t AddressSpace;
135 typedef ::legion_task_priority_t TaskPriority;
136 typedef ::legion_task_priority_t RealmPriority;
137 typedef ::legion_garbage_collection_priority_t GCPriority;
138 typedef ::legion_color_t Color;
139 typedef ::legion_field_id_t FieldID;
140 typedef ::legion_trace_id_t TraceID;
141 typedef ::legion_mapper_id_t MapperID;
142 typedef ::legion_context_id_t ContextID;
143 typedef ::legion_instance_id_t InstanceID;
144 typedef ::legion_index_tree_id_t IndexTreeID;
145 typedef ::legion_generation_id_t GenerationID;
146 typedef ::legion_type_handle TypeHandle;
147 typedef ::legion_projection_id_t ProjectionID;
148 typedef ::legion_sharding_id_t ShardingID;
149 typedef ::legion_concurrent_id_t ConcurrentID;
150 typedef ::legion_exception_handler_id_t ExceptionHandlerID;
151 typedef ::legion_region_tree_id_t RegionTreeID;
152 typedef ::legion_distributed_id_t DistributedID;
153 typedef ::legion_address_space_t AddressSpaceID;
154 typedef ::legion_tunable_id_t TunableID;
155 typedef ::legion_local_variable_id_t LocalVariableID;
156 typedef ::legion_mapping_tag_id_t MappingTagID;
157 typedef ::legion_semantic_tag_t SemanticTag;
158 typedef ::legion_variant_id_t VariantID;
159 typedef ::legion_code_descriptor_id_t CodeDescriptorID;
160 typedef ::legion_unique_id_t UniqueID;
161 typedef ::legion_version_id_t VersionID;
162 typedef ::legion_projection_epoch_id_t ProjectionEpochID;
163 typedef ::legion_task_id_t TaskID;
164 typedef ::legion_layout_constraint_id_t LayoutConstraintID;
165 typedef ::legion_shard_id_t ShardID;
166 typedef ::legion_provenance_id_t ProvenanceID;
167 typedef ::legion_internal_color_t LegionColor;
168 typedef ::legion_reduction_op_id_t ReductionOpID;
169 typedef ::legion_custom_serdez_id_t CustomSerdezID;
170 typedef ::legion_coord_t coord_t;
171
172 // Pull Realm types into the Legion namespace
173 typedef Realm::Runtime RealmRuntime;
174 typedef Realm::Machine Machine;
175 typedef Realm::Memory Memory;
176 typedef Realm::Processor Processor;
177 typedef Realm::ProcessorGroup ProcessorGroup;
178 typedef Realm::CodeDescriptor CodeDescriptor;
179 typedef Realm::Reservation Reservation;
180 typedef Realm::CompletionQueue CompletionQueue;
181 typedef Realm::ReductionOpUntyped ReductionOp;
182 typedef Realm::CustomSerdezUntyped SerdezOp;
183 typedef Realm::Machine::ProcessorMemoryAffinity ProcessorMemoryAffinity;
184 typedef Realm::Machine::MemoryMemoryAffinity MemoryMemoryAffinity;
185 typedef Realm::DynamicTemplates::TagType TypeTag;
186 typedef Realm::Logger Logger;
187 template<int DIM, typename T = coord_t>
188 using Point = Realm::Point<DIM, T>;
189 template<int DIM, typename T = coord_t>
190 using Rect = Realm::Rect<DIM, T>;
191 template<int DIM, typename T = coord_t>
192 using DomainT = Realm::IndexSpace<DIM, T>;
193 template<int M, int N, typename T = coord_t>
194 using Transform = Realm::Matrix<M, N, T>;
195
196 // Forward declarations of types in the public interface
197 class IndexSpace;
198 template<int DIM, typename T>
199 class IndexSpaceT;
200 class IndexPartition;
201 template<int DIM, typename T>
202 class IndexPartitionT;
203 class FieldSpace;
204 class LogicalRegion;
205 template<int DIM, typename T>
206 class LogicalRegionT;
207 class LogicalPartition;
208 template<int DIM, typename T>
209 class LogicalPartitionT;
210 class IndexAllocator;
211 class FieldAllocator;
212 class UntypedBuffer;
213 class ArgumentMap;
214 class Lock;
215 struct LockRequest;
216 class Grant;
217 class PhaseBarrier;
218 struct RegionRequirement;
219 struct OutputRequirement;
220 struct IndexSpaceRequirement;
221 struct FieldSpaceRequirement;
222 struct TaskLauncher;
223 struct IndexTaskLauncher;
224 typedef IndexTaskLauncher IndexLauncher; // for backwards compatibility
225 struct InlineLauncher;
226 struct CopyLauncher;
227 struct AcquireLauncher;
228 struct ReleaseLauncher;
229 struct FillLauncher;
230 struct LayoutConstraintRegistrar;
231 struct TaskVariantRegistrar;
232 struct PoolBounds;
233 class Future;
234 class FutureMap;
235 class Predicate;
236 class PhysicalRegion;
237 class OutputRegion;
238 class ExternalResources;
239 class UntypedDeferredValue;
240 template<typename>
241 class DeferredValue;
242 template<typename, bool>
243 class DeferredReduction;
244 template<typename, int, typename, bool>
245 class DeferredBuffer;
246 template<typename COORD_T>
247 class UntypedDeferredBuffer;
248 template<PrivilegeMode, typename, int, typename, typename, bool>
249 class FieldAccessor;
250 template<typename, bool, int, typename, typename, bool>
251 class ReductionAccessor;
252 template<typename, int, typename, typename, bool>
253 class PaddingAccessor;
254#ifdef LEGION_MULTI_REGION_ACCESSOR
255 template<typename, int, typename, typename, bool, bool, int>
256 class MultiRegionAccessor;
257#endif
258 template<typename, int, typename, typename>
260 namespace ArraySyntax {
261 template<typename, PrivilegeMode>
263 template<typename>
265 } // namespace ArraySyntax
266 class PieceIterator;
267 template<int, typename>
268 class PieceIteratorT;
269 template<PrivilegeMode, typename, int, typename>
270 class SpanIterator;
271 struct InputArgs;
273 class ProjectionFunctor;
274 class ShardingFunctor;
275 class ExceptionHandler;
276 class Task;
277 class Copy;
278 class InlineMapping;
279 class Acquire;
280 class Release;
281 class Close;
282 class Fill;
283 class Partition;
284 class MustEpoch;
286 class Runtime;
287 class LegionHandshake;
288 class MPILegionHandshake;
289 // Helper for saving instantiated template functions
290 struct SerdezRedopFns;
291 // Some typedefs for making things nicer for users with C++11 support
292 template<typename FT, int N, typename T = ::legion_coord_t>
293 using GenericAccessor = Realm::GenericAccessor<FT, N, T>;
294 template<typename FT, int N, typename T = ::legion_coord_t>
295 using AffineAccessor = Realm::AffineAccessor<FT, N, T>;
296 template<typename FT, int N, typename T = ::legion_coord_t>
297 using MultiAffineAccessor = Realm::MultiAffineAccessor<FT, N, T>;
298 class LegionTaskWrapper;
299 class LegionSerialization;
300 class CObjectWrapper;
301 class DomainPoint;
302 class Domain;
303 class ISAConstraint;
305 class ResourceConstraint;
306 class LaunchConstraint;
310 class MemoryConstraint;
311 class FieldConstraint;
312 class PaddingConstraint;
313 class OrderingConstraint;
314 class TilingConstraint;
317 class OffsetConstraint;
318 class PointerConstraint;
321 class Mappable;
322 class Task;
323 class Copy;
324 class Fill;
325 class InlineMapping;
326 class Acquire;
327 class Release;
328 class Partition;
329 class Close;
330 class MustEpoch;
331
332 // A class for preventing serialization of Legion objects
333 // which cannot be serialized
334 class Unserializable { };
335 class Serializer;
336 class Deserializer;
337
338 // Typedefs that are needed everywhere
339 typedef std::map<CustomSerdezID, const Realm::CustomSerdezUntyped*>
340 SerdezOpTable;
341 typedef std::map<Realm::ReductionOpID, Realm::ReductionOpUntyped*>
342 ReductionOpTable;
343 typedef void (*SerdezInitFnptr)(const ReductionOp*, void*&, size_t&);
344 typedef void (*SerdezFoldFnptr)(
345 const ReductionOp*, void*&, size_t&, const void*);
346 using SerdezInitFunc =
347 std::function<void(const ReductionOp*, void*&, size_t&)>;
348 using SerdezFoldFunc =
349 std::function<void(const ReductionOp*, void*&, size_t&, const void*)>;
350 typedef std::map<Realm::ReductionOpID, SerdezRedopFns> SerdezRedopTable;
351
352 typedef void (*RegistrationCallbackFnptr)(
353 Machine machine, Runtime* rt, const std::set<Processor>& local_procs);
354 using RegistrationCallback =
355 std::function<void(Machine, Runtime*, const std::set<Processor>&)>;
356 typedef void (*RegistrationWithArgsCallbackFnptr)(
357 const RegistrationCallbackArgs& args);
358 using RegistrationWithArgsCallback =
359 std::function<void(const RegistrationCallbackArgs&)>;
360 typedef LogicalRegion (*RegionProjectionFnptr)(
361 LogicalRegion parent, const DomainPoint&, Runtime* rt);
362 typedef LogicalRegion (*PartitionProjectionFnptr)(
363 LogicalPartition parent, const DomainPoint&, Runtime* rt);
364
365 // Forward declarations for the mapping namespace
366 namespace Mapping {
367 class PhysicalInstance;
368 class CollectiveView;
369 class MapperEvent;
370 class ProfilingRequestSet;
371 class Mapper;
372 class MapperRuntime;
373 class AutoLock;
374 class DefaultMapper;
375 class ShimMapper;
376 class TestMapper;
377 class DebugMapper;
378 class ReplayMapper;
379
380 // The following types are effectively overlaid on the Realm versions
381 // to allow for Legion-specific profiling measurements
382 enum ProfilingMeasurementID {
383 PMID_LEGION_FIRST = Realm::PMID_REALM_LAST,
384 PMID_RUNTIME_OVERHEAD,
385 };
386 } // namespace Mapping
387
388 namespace Internal {
389 class LocalLock;
390 class AutoLock;
391 class AutoTryLock;
392 class LgEvent; // base event type for legion
393 class ApEvent; // application event
394 class ApUserEvent; // application user event
395 class ApBarrier; // application barrier
396 class RtEvent; // runtime event
397 class RtUserEvent; // runtime user event
398 class RtBarrier;
399
400 struct RegionUsage;
401 class Collectable;
402 class FieldAllocatorImpl;
403 class ArgumentMapImpl;
404 class FutureCreateInstanceRequest;
405 class FutureMapFutureRequest;
406 class FutureImpl;
407 class FutureInstance;
408 class FutureMapImpl;
409 class ReplFutureMapImpl;
410 class PhysicalRegionImpl;
411 class OutputRegionImpl;
412 class ExternalResourcesImpl;
413 class PieceIteratorImpl;
414 class GrantImpl;
415 class PredicateImpl;
416 class HandshakeImpl;
417 typedef HandshakeImpl LegionHandshakeImpl;
418 class MessageManager;
419 class ShutdownManager;
420 class ProcessorManager;
421 class MemoryManager;
422 class MemoryPool;
423 class VirtualChannel;
424 class MessageManager;
425 class ShutdownManager;
426 class TaskImpl;
427 class VariantImpl;
428 class LayoutConstraints;
429 class ProjectionFunction;
430 class ShardingFunction;
431 class Runtime;
432
433 class Provenance;
434 class Operation;
435 class MemoizableOp;
436 class PredicatedOp;
437 class MapOp;
438 class CopyOp;
439 class IndexCopyOp;
440 class PointCopyOp;
441 class FenceOp;
442 class FrameOp;
443 class CreationOp;
444 class DeletionOp;
445 class InternalOp;
446 class CloseOp;
447 class MergeCloseOp;
448 class PostCloseOp;
449 class RefinementOp;
450 class ResetOp;
451 class AcquireOp;
452 class ReleaseOp;
453 class DynamicCollectiveOp;
454 class FuturePredOp;
455 class NotPredOp;
456 class AndPredOp;
457 class OrPredOp;
458 class MustEpochOp;
459 class PendingPartitionOp;
460 class DependentPartitionOp;
461 class PointDepPartOp;
462 class FillOp;
463 class IndexFillOp;
464 class PointFillOp;
465 class DiscardOp;
466 class AttachOp;
467 class IndexAttachOp;
468 class PointAttachOp;
469 class DetachOp;
470 class IndexDetachOp;
471 class PointDetachOp;
472 class TimingOp;
473 class TunableOp;
474 class AllReduceOp;
475 class BeginOp;
476 class CompleteOp;
477 class RecurrentOp;
478 class ExternalMappable;
479 class RemoteOp;
480 class RemoteMapOp;
481 class RemoteCopyOp;
482 class RemoteCloseOp;
483 class RemoteAcquireOp;
484 class RemoteReleaseOp;
485 class RemoteFillOp;
486 class RemotePartitionOp;
487 class RemoteReplayOp;
488 class RemoteSummaryOp;
489 template<typename OP>
491 template<typename OP>
493 struct PointwiseDependence;
494
495 class ExternalTask;
496 class TaskOp;
497 class RemoteTaskOp;
498 class SingleTask;
499 class MultiTask;
500 class IndividualTask;
501 class PointTask;
502 class ShardTask;
503 class IndexTask;
504 class SliceTask;
505 class RemoteTask;
506
507 class TaskContext;
508 class InnerContext;
509 class TopLevelContext;
510 class ReplicateContext;
511 class RemoteContext;
512 class LeafContext;
513
514 class LogicalTrace;
515 class TraceBeginOp;
516 class TraceRecurrentOp;
517 class TraceCompleteOp;
518 class PhysicalTrace;
519 class TraceViewSet;
520 class TraceConditionSet;
521 class PhysicalTemplate;
522 class ShardedPhysicalTemplate;
523 class Instruction;
524 class GetTermEvent;
525 class ReplayMapping;
526 class CreateApUserEvent;
527 class TriggerEvent;
528 class MergeEvent;
529 class AssignFenceCompletion;
530 class IssueCopy;
531 class IssueFill;
532 class IssueAcross;
533 class GetOpTermEvent;
534 class SetOpSyncEvent;
535 class SetEffects;
536 class CompleteReplay;
537 class AcquireReplay;
538 class ReleaseReplay;
539 class BarrierArrival;
540 class BarrierAdvance;
541 class TraceRecognizer;
542 class TraceHashRecorder;
543
544 class CopyAcrossExecutor;
545 class CopyAcrossUnstructured;
546 class IndexSpaceExpression;
547 class IndexSpaceOperation;
548 template<int DIM, typename T>
550 template<int DIM, typename T>
552 template<int DIM, typename T>
554 template<int DIM, typename T>
556 class ExpressionTrieNode;
557 class IndexTreeNode;
558 class IndexSpaceNode;
559 template<int DIM, typename T>
561 class IndexPartNode;
562 template<int DIM, typename T>
564 class FieldSpaceNode;
565 class RegionTreeNode;
566 class RegionNode;
567 class PartitionNode;
568 class ColorSpaceIterator;
569 template<int DIM, typename T>
571 class KDTree;
572 template<int DIM, typename T, typename RT = void>
573 class KDNode;
574 class EqKDTree;
575 template<int DIM, typename T>
577
578 class RegionTreePath;
579 class PathTraverser;
580 class NodeTraverser;
581
582 class LogicalState;
583 class LogicalAnalysis;
584 class PhysicalAnalysis;
585 class ValidInstAnalysis;
586 class InvalidInstAnalysis;
587 class AntivalidInstAnalysis;
588 class RegistrationAnalysis;
589 class CollectiveAnalysis;
590 class UpdateAnalysis;
591 class CopyAcrossAnalysis;
592 class AcquireAnalysis;
593 class ReleaseAnalysis;
594 class OverwriteAnalysis;
595 class FilterAnalysis;
596 class EquivalenceSet;
597 class EqSetTracker;
598 class VersionManager;
599 class VersionInfo;
600 class ProjectionNode;
601 class ProjectionRegion;
602 class ProjectionPartition;
603 class RefinementTracker;
604 class RegionRefinementTracker;
605 class PartitionRefinementTracker;
606 class CopyFillGuard;
607 class CopyFillAggregator;
608
609 class Collectable;
610 class ImplicitReferenceTracker;
611 class DistributedCollectable;
612 class LayoutDescription;
613 class InstanceManager; // base class for all instances
614 class CopyAcrossHelper;
615 class LogicalView; // base class for instance and reduction
616 class InstanceKey;
617 class InstanceView;
618 class CollectableView; // pure virtual class
619 class IndividualView;
620 class NodeView;
621 class SpaceView;
622 class PartitionView;
623 class CollectiveView;
624 class MaterializedView;
625 class ReplicatedView;
626 class ReductionView;
627 class AllreduceView;
628 class DeferredView;
629 class FillView;
630 class PhiView;
631 class MappingRef;
632 class InstanceRef;
633 class InstanceSet;
634 class InnerTaskView;
635 class VirtualManager;
636 class PhysicalManager;
637 class InstanceBuilder;
638
639 class RegionAnalyzer;
640 class RegionMapper;
641
642 struct LogicalUser;
643 struct PhysicalUser;
644 struct LogicalTraceInfo;
645 struct TraceInfo;
646 struct PhysicalTraceInfo;
647 struct UniqueInst;
648 class TreeCloseImpl;
649 class TreeClose;
650 struct CloseInfo;
651 struct FieldDataDescriptor;
652 class ProjectionSummary;
653 class ProjectionInfo;
654
655 class LegionProfiler;
656 class LegionProfInstance;
657
658 class MappingCallInfo;
659 class MapperManager;
660 class SerializingManager;
661 class ConcurrentManager;
662
663 class ShardedMapping;
664 class ReplIndividualTask;
665 class ReplIndexTask;
666 class ReplMergeCloseOp;
667 class ReplRefinementOp;
668 class ReplResetOp;
669 class ReplFillOp;
670 class ReplIndexFillOp;
671 class ReplDiscardOp;
672 class ReplCopyOp;
673 class ReplIndexCopyOp;
674 class ReplDeletionOp;
675 class ReplPendingPartitionOp;
676 class ReplDependentPartitionOp;
677 class ReplPredicateImpl;
678 class ReplMustEpochOp;
679 class ReplTimingOp;
680 class ReplTunableOp;
681 class ReplAllReduceOp;
682 class ReplFenceOp;
683 class ReplMapOp;
684 class ReplAttachOp;
685 class ReplIndexAttachOp;
686 class ReplDetachOp;
687 class ReplIndexDetachOp;
688 class ReplAcquireOp;
689 class ReplReleaseOp;
690 class ReplTraceOp;
691 class ReplTraceBeginOp;
692 class ReplTraceRecurrentOp;
693 class ReplTraceCompleteOp;
694 class ShardMapping;
695 class CollectiveMapping;
696 class ShardManager;
697 class ImplicitShardManager;
698 class ShardCollective;
699 class GatherCollective;
700 template<bool>
702 template<typename T>
704 template<typename T>
706 template<typename T, bool>
708 class CrossProductCollective;
709 class ShardingGatherCollective;
710 class FieldDescriptorExchange;
711 class FieldDescriptorGather;
712 class FutureBroadcast;
713 class FutureExchange;
714 class FutureNameExchange;
715 class MustEpochMappingBroadcast;
716 class MustEpochMappingExchange;
717 class PredicateCollective;
718 class UnorderedExchange;
719 class ShardRendezvous;
720 class ProjectionTreeExchange;
721 class TimeoutMatchExchange;
722 class ConcurrentAllreduce;
723 class BufferBroadcast;
724 class CreateCollectiveFillView;
725
726 // The invalid color
727 constexpr LegionColor INVALID_COLOR =
728 std::numeric_limits<LegionColor>::max();
729 // This is only needed internally
730 typedef Realm::RegionInstance PhysicalInstance;
731 typedef Realm::CopySrcDstField CopySrcDstField;
732 typedef unsigned long long CollectiveID;
733 typedef unsigned long long IndexSpaceExprID;
734 typedef uint64_t LamportClock;
735 struct ContextCoordinate;
736 typedef ContextCoordinate TraceLocalID;
737 class TaskTreeCoordinates;
738 // Helper for encoding templates
739 struct NT_TemplateHelper : public Realm::DynamicTemplates::ListProduct2<
740 Realm::DIMCOUNTS, Realm::DIMTYPES> {
741 typedef Realm::DynamicTemplates::ListProduct2<
742 Realm::DIMCOUNTS, Realm::DIMTYPES>
743 SUPER;
744 public:
745 template<int N, typename T>
746 __LEGION_CUDA_HD__ static inline constexpr TypeTag encode_tag(void)
747 {
748 constexpr TypeTag type =
749 SUPER::template encode_tag<Realm::DynamicTemplates::Int<N>, T>();
750 static_assert(type != 0, "All types should be non-zero for Legion");
751 return type;
752 }
753 template<int N, typename T>
754 static inline void check_type(const TypeTag t)
755 {
756 legion_assert((encode_tag<N, T>() == t));
757 }
758 struct DimHelper {
759 public:
760 template<typename N, typename T>
761 static inline void demux(int* result)
762 {
763 *result = N::N;
764 }
765 };
766 static inline int get_dim(const TypeTag t)
767 {
768 int result = 0;
769 SUPER::demux<DimHelper>(t, &result);
770 return result;
771 }
772 };
773 // Pull some of the mapper types into the internal space
774 typedef Mapping::Mapper Mapper;
775 typedef Mapping::MapperEvent MapperEvent;
776 typedef Mapping::PhysicalInstance MappingInstance;
777 typedef Mapping::CollectiveView MappingCollective;
778 typedef Mapping::ProfilingMeasurementID ProfilingMeasurementID;
779 } // namespace Internal
780
781 // Magical typedefs
782 typedef Internal::TaskContext* Context;
783 // More magical typedefs for the mapping namespace
784 namespace Mapping {
785 typedef Internal::MappingCallInfo* MapperContext;
786 typedef Internal::InstanceManager* PhysicalInstanceImpl;
787 typedef Internal::CollectiveView* CollectiveViewImpl;
788 // This type import is experimental to facilitate coordination and
789 // synchronization between different mappers and may be revoked later
790 // as we develop new abstractions for mappers to interact
791 typedef Internal::LocalLock LocalLock;
792 }; // namespace Mapping
793
794 // Events are locks are important enough that we want them inlined everywhere
795 // so we pull these classes and implementations into this header file so
796 // that everyone will have access to them.
797 namespace Internal {
798
799 // Legion derived event types
800 class LgEvent : public Realm::Event {
801 public:
802 static const LgEvent NO_LG_EVENT;
803 public:
804 LgEvent(void) noexcept { id = 0; }
805 LgEvent(const LgEvent& rhs) = default;
806 explicit LgEvent(const Realm::Event e) { id = e.id; }
807 public:
808 inline LgEvent& operator=(const LgEvent& rhs) = default;
809 public:
810 // Override the wait method so we can have our own implementation
811 inline void wait(void) const;
812 inline void wait_faultaware(bool& poisoned, bool from_application) const;
813 inline bool is_barrier(void) const;
814 protected:
815 void begin_wait(Context ctx, bool from_application) const;
816 void end_wait(Context ctx, bool from_application) const;
817 void begin_mapper_call_wait(MappingCallInfo* call) const;
818 void record_event_wait(Realm::Backtrace& bt, ProvenanceID pid) const;
819 void record_event_trigger(LgEvent precondition) const;
820 };
821
822 class PredEvent : public LgEvent {
823 public:
824 static const PredEvent NO_PRED_EVENT;
825 public:
826 PredEvent(void) noexcept : LgEvent() { }
827 PredEvent(const PredEvent& rhs) = default;
828 explicit PredEvent(const Realm::Event& e) : LgEvent(e) { }
829 public:
830 inline PredEvent& operator=(const PredEvent& rhs) = default;
831 };
832
833 class PredUserEvent : public PredEvent {
834 public:
835 static const PredUserEvent NO_PRED_USER_EVENT;
836 public:
837 PredUserEvent(void) noexcept : PredEvent() { }
838 PredUserEvent(const PredUserEvent& rhs) = default;
839 explicit PredUserEvent(const Realm::UserEvent& e) : PredEvent(e) { }
840 public:
841 inline PredUserEvent& operator=(const PredUserEvent& rhs) = default;
842 inline operator Realm::UserEvent() const
843 {
844 Realm::UserEvent e;
845 e.id = id;
846 return e;
847 }
848 };
849
850 class ApEvent : public LgEvent {
851 public:
852 static const ApEvent NO_AP_EVENT;
853 public:
854 ApEvent(void) noexcept : LgEvent() { }
855 ApEvent(const ApEvent& rhs) = default;
856 explicit ApEvent(const Realm::Event& e) : LgEvent(e) { }
857 explicit ApEvent(const PredEvent& e) { id = e.id; }
858 public:
859 inline ApEvent& operator=(const ApEvent& rhs) = default;
860 inline bool has_triggered_faultignorant(void) const
861 {
862 bool poisoned = false;
863 return has_triggered_faultaware(poisoned);
864 }
865 inline void wait_faultaware(bool& poisoned) const
866 {
867 return LgEvent::wait_faultaware(poisoned, true /*application*/);
868 }
869 inline void wait_faultignorant(void) const
870 {
871 bool poisoned = false;
872 LgEvent::wait_faultaware(poisoned, true /*application*/);
873 }
874 private:
875 // Make these private because we always want to be conscious of faults
876 // when testing or waiting on application events
877 inline bool has_triggered(void) const { return LgEvent::has_triggered(); }
878 inline void wait(void) const { LgEvent::wait(); }
879 };
880
881 class ApUserEvent : public ApEvent {
882 public:
883 static const ApUserEvent NO_AP_USER_EVENT;
884 public:
885 ApUserEvent(void) noexcept : ApEvent() { }
886 ApUserEvent(const ApUserEvent& rhs) = default;
887 explicit ApUserEvent(const Realm::UserEvent& e) : ApEvent(e) { }
888 public:
889 inline ApUserEvent& operator=(const ApUserEvent& rhs) = default;
890 inline operator Realm::UserEvent() const
891 {
892 Realm::UserEvent e;
893 e.id = id;
894 return e;
895 }
896 };
897
898 class ApBarrier : public ApEvent {
899 public:
900 static const ApBarrier NO_AP_BARRIER;
901 public:
902 ApBarrier(void) noexcept : ApEvent(), timestamp(0) { }
903 ApBarrier(const ApBarrier& rhs) = default;
904 explicit ApBarrier(const Realm::Barrier& b)
905 : ApEvent(b), timestamp(b.timestamp)
906 { }
907 public:
908 inline ApBarrier& operator=(const ApBarrier& rhs) = default;
909 inline operator Realm::Barrier() const
910 {
911 Realm::Barrier b;
912 b.id = id;
913 b.timestamp = timestamp;
914 return b;
915 }
916 public:
917 inline bool get_result(void* value, size_t value_size) const
918 {
919 Realm::Barrier b;
920 b.id = id;
921 b.timestamp = timestamp;
922 return b.get_result(value, value_size);
923 }
924 inline void destroy_barrier(void)
925 {
926 Realm::Barrier b;
927 b.id = id;
928 b.timestamp = timestamp;
929 b.destroy_barrier();
930 }
931 public:
932 Realm::Barrier::timestamp_t timestamp;
933 };
934
935 class RtEvent : public LgEvent {
936 public:
937 static const RtEvent NO_RT_EVENT;
938 public:
939 RtEvent(void) noexcept : LgEvent() { }
940 RtEvent(const RtEvent& rhs) = default;
941 explicit RtEvent(const Realm::Event& e) : LgEvent(e) { }
942 explicit RtEvent(const PredEvent& e) { id = e.id; }
943 public:
944 inline RtEvent& operator=(const RtEvent& rhs) = default;
945 };
946
947 class RtUserEvent : public RtEvent {
948 public:
949 static const RtUserEvent NO_RT_USER_EVENT;
950 public:
951 RtUserEvent(void) noexcept : RtEvent() { }
952 RtUserEvent(const RtUserEvent& rhs) = default;
953 explicit RtUserEvent(const Realm::UserEvent& e) : RtEvent(e) { }
954 public:
955 inline RtUserEvent& operator=(const RtUserEvent& rhs) = default;
956 inline operator Realm::UserEvent() const
957 {
958 Realm::UserEvent e;
959 e.id = id;
960 return e;
961 }
962 };
963
964 class RtBarrier : public RtEvent {
965 public:
966 static const RtBarrier NO_RT_BARRIER;
967 public:
968 RtBarrier(void) noexcept : RtEvent(), timestamp(0) { }
969 RtBarrier(const RtBarrier& rhs) = default;
970 explicit RtBarrier(const Realm::Barrier& b)
971 : RtEvent(b), timestamp(b.timestamp)
972 { }
973 public:
974 inline RtBarrier& operator=(const RtBarrier& rhs) = default;
975 inline operator Realm::Barrier() const
976 {
977 Realm::Barrier b;
978 b.id = id;
979 b.timestamp = timestamp;
980 return b;
981 }
982 public:
983 inline bool get_result(void* value, size_t value_size) const
984 {
985 Realm::Barrier b;
986 b.id = id;
987 b.timestamp = timestamp;
988 return b.get_result(value, value_size);
989 }
990 inline RtBarrier get_previous_phase(void)
991 {
992 Realm::Barrier b;
993 b.id = id;
994 return RtBarrier(b.get_previous_phase());
995 }
996 inline void destroy_barrier(void)
997 {
998 Realm::Barrier b;
999 b.id = id;
1000 b.timestamp = timestamp;
1001 b.destroy_barrier();
1002 }
1003 public:
1004 Realm::Barrier::timestamp_t timestamp;
1005 };
1006
1007 // Local lock for accelerating lock taking
1009 public:
1010 inline LocalLock(void) { }
1011 public:
1012 LocalLock(const LocalLock& rhs) = delete;
1013 inline ~LocalLock(void) { }
1014 public:
1015 LocalLock& operator=(const LocalLock& rhs) = delete;
1016 private:
1017 // These are only accessible via AutoLock
1018 friend class AutoLock;
1019 friend class AutoTryLock;
1020 friend class Mapping::AutoLock;
1021 inline RtEvent lock(void) { return RtEvent(wrlock()); }
1022 inline RtEvent wrlock(void) { return RtEvent(reservation.wrlock()); }
1023 inline RtEvent rdlock(void) { return RtEvent(reservation.rdlock()); }
1024 inline bool trylock(void) { return reservation.trylock(); }
1025 inline bool trywrlock(void) { return reservation.trywrlock(); }
1026 inline bool tryrdlock(void) { return reservation.tryrdlock(); }
1027 inline void unlock(void) { reservation.unlock(); }
1028 private:
1029 inline void advise_sleep_entry(Realm::UserEvent guard)
1030 {
1031 reservation.advise_sleep_entry(guard);
1032 }
1033 inline void advise_sleep_exit(void) { reservation.advise_sleep_exit(); }
1034 protected:
1035 Realm::FastReservation reservation;
1036 };
1037
1038 // External global variable references
1039 // With the exception fo the runtime singleton all of these should
1040 // only be thread-local or logggers
1041 // This is the pointer to the runtime singleton
1042 inline Runtime* runtime = nullptr;
1043 // One more global variable for the spy_logging_level which says
1044 // which level of legion spy logging we are doing, put this here
1045 // so that we inline it into everything
1046 enum SpyLoggingLevel {
1047 NO_SPY_LOGGING,
1048 LIGHT_SPY_LOGGING,
1049 HEAVY_SPY_LOGGING,
1050 EQ_SPY_LOGGING,
1051 };
1052#ifdef LEGION_SPY
1053 inline SpyLoggingLevel spy_logging_level = HEAVY_SPY_LOGGING;
1054#else
1055 inline SpyLoggingLevel spy_logging_level = NO_SPY_LOGGING;
1056#endif
1057 // Nasty global variable for TLS support of figuring out
1058 // our context implicitly
1059 // This one is only set for application tasks
1060 inline thread_local TaskContext* implicit_context = nullptr;
1061 // Mapper context if we're inside of a mapper call
1062 inline thread_local MappingCallInfo* implicit_mapper_call = nullptr;
1063 // Implicit thread-local profiler
1064 inline thread_local LegionProfInstance* implicit_profiler = nullptr;
1065 // Another nasty global variable for tracking the fast
1066 // reservations that we are holding
1067 inline thread_local AutoLock* local_lock_list = nullptr;
1068 // Track the enclosing task context that we're in for error reporting
1069 // This is only set for some internal meta-tasks
1070 inline thread_local DistributedID implicit_enclosing_context = 0;
1071 // The implicit operation if it exists, this is only set for certain
1072 // meta-tasks that correspond to pipeline stages that permit us to
1073 // take a fault in them so we prune out that operation
1074 inline thread_local Operation* implicit_operation = nullptr;
1075 // The implicit provenance if we're inside of a call into Legion
1076 // from an application task or in a meta-task derviced from a
1077 // particular operation
1078 inline thread_local ProvenanceID implicit_provenance = 0;
1079 // One more nasty global variable that we use for tracking
1080 // the provenance of meta-task operations for profiling
1081 // purposes, this has no bearing on correctness
1082 inline thread_local ::legion_unique_id_t implicit_unique_op_id = 0;
1083 // Use this global variable to track name of the "finish event"
1084 // for whatever (meta-)task we're running on at the moment.
1085 // It should always be the case that the owner node of the
1086 // "finish" event" is the same as the node we're on.
1087 inline thread_local LgEvent implicit_fevent = {};
1088 // Use this to track if we're inside of a registration
1089 // callback function which we know to be deduplicated
1090 enum RegistrationCallbackMode {
1091 NO_REGISTRATION_CALLBACK = 0,
1092 LOCAL_REGISTRATION_CALLBACK = 1,
1093 GLOBAL_REGISTRATION_CALLBACK = 2,
1094 };
1095 inline thread_local RegistrationCallbackMode inside_registration_callback =
1096 NO_REGISTRATION_CALLBACK;
1097 // This data structure tracks references to any live
1098 // temporary index space expressions that have been
1099 // handed back by the region tree inside the execution
1100 // of a meta-task or a runtime API call. It also tracks
1101 // changes to remote distributed collectable that can be
1102 // delayed and batched together.
1103 inline thread_local ImplicitReferenceTracker* implicit_reference_tracker =
1104 nullptr;
1105#ifdef LEGION_DEBUG_CALLERS
1106 thread_local LgTaskID implicit_task_kind;
1107 thread_local LgTaskID implicit_task_caller;
1108#endif
1109 extern Realm::Logger log_legion;
1110 extern Realm::Logger log_allocation;
1111 extern Realm::Logger log_migration;
1112 extern Realm::Logger log_prof;
1113 extern Realm::Logger log_garbage;
1114 extern Realm::Logger log_spy;
1115 extern Realm::Logger log_shutdown;
1116 extern Realm::Logger log_tracing;
1117 extern Realm::Logger log_auto_trace;
1118 extern Realm::Logger log_registration;
1119
1121 // AutoLock
1123 // An auto locking class for taking a lock and releasing it when
1124 // the object goes out of scope
1125 class AutoLock {
1126 public:
1127 inline AutoLock(LocalLock& r, bool excl = true)
1128 : local_lock(r), previous(local_lock_list), exclusive(excl), held(true)
1129 {
1130#ifdef LEGION_DEBUG_REENTRANT_LOCKS
1131 if (previous != nullptr)
1132 previous->check_for_reentrant_locks(&local_lock, this);
1133#endif
1134 if (exclusive)
1135 {
1136 RtEvent ready = local_lock.wrlock();
1137 while (ready.exists())
1138 {
1139 ready.wait();
1140 ready = local_lock.wrlock();
1141 }
1142 }
1143 else
1144 {
1145 RtEvent ready = local_lock.rdlock();
1146 while (ready.exists())
1147 {
1148 ready.wait();
1149 ready = local_lock.rdlock();
1150 }
1151 }
1152 local_lock_list = this;
1153 }
1154 protected:
1155 // Helper constructor for AutoTryLock and Mapping::AutoLock
1156 inline AutoLock(bool excl, LocalLock& r)
1157 : local_lock(r), previous(local_lock_list), exclusive(excl), held(false)
1158 {
1159 local_lock_list = this;
1160#ifdef LEGION_DEBUG_REENTRANT_LOCKS
1161 if (previous != nullptr)
1162 previous->check_for_reentrant_locks(&local_lock, this);
1163#endif
1164 }
1165 public:
1166 AutoLock(AutoLock&& rhs) = delete;
1167 AutoLock(const AutoLock& rhs) = delete;
1168 inline ~AutoLock(void)
1169 {
1170 if (held)
1171 local_lock.unlock();
1172 legion_assert(local_lock_list == this);
1173 local_lock_list = previous;
1174 }
1175 public:
1176 AutoLock& operator=(AutoLock&& rhs) = delete;
1177 AutoLock& operator=(const AutoLock& rhs) = delete;
1178 public:
1179 inline void release(void)
1180 {
1181 legion_assert(held);
1182 local_lock.unlock();
1183 held = false;
1184 }
1185 inline void reacquire(void)
1186 {
1187 legion_assert(!held);
1188#ifdef LEGION_DEBUG_REENTRANT_LOCKS
1189 local_lock_list->check_for_reentrant_locks(&local_lock, this);
1190#endif
1191 if (exclusive)
1192 {
1193 RtEvent ready = local_lock.wrlock();
1194 while (ready.exists())
1195 {
1196 ready.wait();
1197 ready = local_lock.wrlock();
1198 }
1199 }
1200 else
1201 {
1202 RtEvent ready = local_lock.rdlock();
1203 while (ready.exists())
1204 {
1205 ready.wait();
1206 ready = local_lock.rdlock();
1207 }
1208 }
1209 held = true;
1210 }
1211 public:
1212 inline void advise_sleep_entry(Realm::UserEvent guard) const
1213 {
1214 if (held)
1215 local_lock.advise_sleep_entry(guard);
1216 if (previous != nullptr)
1217 previous->advise_sleep_entry(guard);
1218 }
1219 inline void advise_sleep_exit(void) const
1220 {
1221 if (held)
1222 local_lock.advise_sleep_exit();
1223 if (previous != nullptr)
1224 previous->advise_sleep_exit();
1225 }
1226#ifdef LEGION_DEBUG_REENTRANT_LOCKS
1227 inline void check_for_reentrant_locks(
1228 LocalLock* to_acquire, const AutoLock* acquirer) const
1229 {
1230 legion_assert((to_acquire != &local_lock) || (this == acquirer));
1231 if (previous != nullptr)
1232 previous->check_for_reentrant_locks(to_acquire, acquirer);
1233 }
1234#endif
1235 protected:
1236 LocalLock& local_lock;
1237 AutoLock* const previous;
1238 const bool exclusive;
1239 bool held;
1240 };
1241
1242 // AutoTryLock is an extension of AutoLock that supports try lock
1243 class AutoTryLock : public AutoLock {
1244 public:
1245 inline AutoTryLock(LocalLock& r, bool excl = true) : AutoLock(excl, r)
1246 {
1247 if (exclusive)
1248 ready = local_lock.wrlock();
1249 else
1250 ready = local_lock.rdlock();
1251 held = !ready.exists();
1252 }
1253 AutoTryLock(const AutoTryLock& rhs) = delete;
1254 public:
1255 AutoTryLock& operator=(const AutoTryLock& rhs) = delete;
1256 public:
1257 // Allow an easy test for whether we got the lock or not
1258 inline bool has_lock(void) const { return held; }
1259 inline RtEvent try_next(void) const { return ready; }
1260 protected:
1261 RtEvent ready;
1262 };
1263
1264 //--------------------------------------------------------------------------
1265 inline void LgEvent::wait(void) const
1266 //--------------------------------------------------------------------------
1267 {
1268 if (!exists())
1269 return;
1270#ifdef DEBUG_LEGION_CALLERS
1271 LgTaskID local_kind = implicit_task_kind;
1272 LgTaskID local_caller = implicit_task_caller;
1273#endif
1274 // Save the mapper call locally
1275 MappingCallInfo* local_call = nullptr;
1276 std::swap(local_call, implicit_mapper_call);
1277 // If we're in a mapper call, notify the mapper that we're waiting
1278 // Do this first in case we get a re-entrant wait (e.g. because
1279 // SerializingManager::pause_mapper_call takes and lock and we might
1280 // end up coming back around here to wait on that event too)
1281 if (local_call != NULL)
1282 begin_mapper_call_wait(local_call);
1283 // Save whether we are in a registration callback
1284 RegistrationCallbackMode local_callback = NO_REGISTRATION_CALLBACK;
1285 std::swap(local_callback, inside_registration_callback);
1286 // Save the reference tracker that we have
1287 ImplicitReferenceTracker* local_tracker = nullptr;
1288 std::swap(local_tracker, implicit_reference_tracker);
1289 // Save the context locally
1290 TaskContext* local_ctx = nullptr;
1291 std::swap(local_ctx, implicit_context);
1292 // Save the operation locally
1293 Operation* local_op = nullptr;
1294 std::swap(local_op, implicit_operation);
1295 // Save the provenance
1296 ProvenanceID local_provenance = 0;
1297 std::swap(local_provenance, implicit_provenance);
1298 // Save the enclosing context
1299 DistributedID local_did = 0;
1300 std::swap(local_did, implicit_enclosing_context);
1301 // Save the implicit fevent
1302 LgEvent local_fevent;
1303 std::swap(local_fevent, implicit_fevent);
1304 // Save the task provenance information
1305 UniqueID local_uid = 0;
1306 std::swap(local_uid, implicit_unique_op_id);
1307 // Check to see if we have any local locks to notify
1308 if (local_lock_list != nullptr)
1309 {
1310 // Make a copy of the local locks here
1311 AutoLock* local_lock_list_copy = nullptr;
1312 std::swap(local_lock_list_copy, local_lock_list);
1313 // Make a user event and notify all the thread locks
1314 const Realm::UserEvent done = Realm::UserEvent::create_user_event();
1315 local_lock_list_copy->advise_sleep_entry(done);
1316 begin_wait(local_ctx, false /*from application*/);
1317 // Now we can do the wait (Realm checks for external waits itself now)
1318 Realm::Event::wait();
1319 // Restore our implicit fevent in case we have profiling to do
1320 // Must restore implicit_fevent before calling end_wait
1321 implicit_fevent = local_fevent;
1322 end_wait(local_ctx, false /*from application*/);
1323 // When we wake up, notify that we are done and exited the wait
1324 local_lock_list_copy->advise_sleep_exit();
1325 // Trigger the user-event
1326 done.trigger();
1327 // Restore our local lock list
1328 local_lock_list = local_lock_list_copy;
1329 // If we're profiling we need to record that we triggered this
1330 // event as it will help us hook up the critical path for
1331 // local lock acquires
1332 if (implicit_profiler != nullptr)
1333 {
1334 // Have to do this recording after the wait because it might
1335 // end up waiting on an event too and don't want to cause
1336 // a stack overflow with repeated calls into wait
1337 const LgEvent to_trigger(done);
1338 to_trigger.record_event_trigger(LgEvent::NO_LG_EVENT);
1339 // Record the backtrace too
1340 Realm::Backtrace bt;
1341 bt.capture_backtrace();
1342 record_event_wait(bt, local_provenance);
1343 }
1344 }
1345 else // Just do the normal wait
1346 {
1347 begin_wait(local_ctx, false /*from application*/);
1348 // Realm checks for external waits itself now
1349 Realm::Event::wait();
1350 // Restore our implicit fevent in case we have profiling to do
1351 // Must restore implicit_fevent before calling end_wait
1352 implicit_fevent = local_fevent;
1353 end_wait(local_ctx, false /*from application*/);
1354 if (implicit_profiler != nullptr)
1355 {
1356 // Have to do this recording after the wait because it might
1357 // end up waiting on an event too and don't want to cause
1358 // a stack overflow with repeated calls into wait
1359 Realm::Backtrace bt;
1360 bt.capture_backtrace();
1361 record_event_wait(bt, local_provenance);
1362 }
1363 }
1364 // Write the context back
1365 implicit_context = local_ctx;
1366 // Write the mapper call back
1367 implicit_mapper_call = local_call;
1368 // Write the operation back
1369 implicit_operation = local_op;
1370 // Write the provenance back
1371 implicit_provenance = local_provenance;
1372 // Write the enclosing context back
1373 implicit_enclosing_context = local_did;
1374 // Write the provenance information back
1375 implicit_unique_op_id = local_uid;
1376#ifdef DEBUG_LEGION_CALLERS
1377 implicit_task_kind = local_kind;
1378 implicit_task_caller = local_caller;
1379#endif
1380 // Write the registration callback information back
1381 inside_registration_callback = local_callback;
1382#ifdef DEBUG_LEGION
1383 assert(implicit_reference_tracker == nullptr);
1384#endif
1385 // Write the local reference tracker back
1386 implicit_reference_tracker = local_tracker;
1387 }
1388
1389 //--------------------------------------------------------------------------
1390 inline void LgEvent::wait_faultaware(bool& poisoned, bool from_app) const
1391 //--------------------------------------------------------------------------
1392 {
1393 if (!exists())
1394 return;
1395 if (has_triggered_faultaware(poisoned))
1396 return;
1397#ifdef DEBUG_LEGION_CALLERS
1398 LgTaskID local_kind = implicit_task_kind;
1399 LgTaskID local_caller = implicit_task_caller;
1400#endif
1401 // Save the mapper call locally
1402 MappingCallInfo* local_call = nullptr;
1403 std::swap(local_call, implicit_mapper_call);
1404 // If we're in a mapper call, notify the mapper that we're waiting
1405 // Do this first in case we get a re-entrant wait (e.g. because
1406 // SerializingManager::pause_mapper_call takes and lock and we might
1407 // end up coming back around here to wait on that event too)
1408 if (local_call != NULL)
1409 begin_mapper_call_wait(local_call);
1410 // Save whether we are in a registration callback
1411 RegistrationCallbackMode local_callback = NO_REGISTRATION_CALLBACK;
1412 std::swap(local_callback, inside_registration_callback);
1413 // Save the reference tracker that we have
1414 ImplicitReferenceTracker* local_tracker = nullptr;
1415 std::swap(local_tracker, implicit_reference_tracker);
1416 // Save the context locally
1417 TaskContext* local_ctx = nullptr;
1418 std::swap(local_ctx, implicit_context);
1419 // Save the operation locally
1420 Operation* local_op = nullptr;
1421 std::swap(local_op, implicit_operation);
1422 // Save the provenance
1423 ProvenanceID local_provenance = 0;
1424 std::swap(local_provenance, implicit_provenance);
1425 // Save the enclosing context
1426 DistributedID local_did = 0;
1427 std::swap(local_did, implicit_enclosing_context);
1428 // Save the fevent
1429 LgEvent local_fevent;
1430 std::swap(local_fevent, implicit_fevent);
1431 // Save the task provenance information
1432 UniqueID local_uid = 0;
1433 std::swap(local_uid, implicit_unique_op_id);
1434 // Check to see if we have any local locks to notify
1435 if (local_lock_list != nullptr)
1436 {
1437 // Make a copy of the local locks here
1438 AutoLock* local_lock_list_copy = nullptr;
1439 std::swap(local_lock_list_copy, local_lock_list);
1440 // Make a user event and notify all the thread locks
1441 const Realm::UserEvent done = Realm::UserEvent::create_user_event();
1442 local_lock_list_copy->advise_sleep_entry(done);
1443 begin_wait(local_ctx, from_app);
1444 // Now we can do the wait (Realm checks for external waits itself now)
1445 Realm::Event::wait_faultaware(poisoned);
1446 // Restore our implicit fevent in case we have profiling to do
1447 // Must restore implicit_fevent before calling end_wait
1448 implicit_fevent = local_fevent;
1449 end_wait(local_ctx, from_app);
1450 // When we wake up, notify that we are done and exited the wait
1451 local_lock_list_copy->advise_sleep_exit();
1452 // Trigger the user-event
1453 done.trigger();
1454 // Restore our local lock list
1455 local_lock_list = local_lock_list_copy;
1456 // If we're profiling we need to record that we triggered this
1457 // event as it will help us hook up the critical path for
1458 // local lock acquires
1459 if (implicit_profiler != nullptr)
1460 {
1461 // Have to do this recording after the wait because it might
1462 // end up waiting on an event too and don't want to cause
1463 // a stack overflow with repeated calls into wait
1464 const LgEvent to_trigger(done);
1465 to_trigger.record_event_trigger(LgEvent::NO_LG_EVENT);
1466 // Record the backtrace too
1467 Realm::Backtrace bt;
1468 bt.capture_backtrace();
1469 record_event_wait(bt, local_provenance);
1470 }
1471 }
1472 else // Just do the normal wait
1473 {
1474 begin_wait(local_ctx, from_app);
1475 // Realm checks for external waits itself now
1476 Realm::Event::wait_faultaware(poisoned);
1477 // Restore our implicit fevent in case we have profiling to do
1478 // Must restore implicit_fevent before calling end_wait
1479 implicit_fevent = local_fevent;
1480 end_wait(local_ctx, from_app);
1481 if (implicit_profiler != nullptr)
1482 {
1483 // Have to do this recording after the wait because it might
1484 // end up waiting on an event too and don't want to cause
1485 // a stack overflow with repeated calls into wait
1486 Realm::Backtrace bt;
1487 bt.capture_backtrace();
1488 record_event_wait(bt, local_provenance);
1489 }
1490 }
1491 // Write the context back
1492 implicit_context = local_ctx;
1493 // Write the mapper call back
1494 implicit_mapper_call = local_call;
1495 // Write the operation back
1496 implicit_operation = local_op;
1497 // Write the provenance back
1498 implicit_provenance = local_provenance;
1499 // Write the enclosing context back
1500 implicit_enclosing_context = local_did;
1501 // Write the provenance information back
1502 implicit_unique_op_id = local_uid;
1503#ifdef DEBUG_LEGION_CALLERS
1504 implicit_task_kind = local_kind;
1505 implicit_task_caller = local_caller;
1506#endif
1507 // Write the registration callback information back
1508 inside_registration_callback = local_callback;
1509#ifdef DEBUG_LEGION
1510 assert(implicit_reference_tracker == nullptr);
1511#endif
1512 // Write the local reference tracker back
1513 implicit_reference_tracker = local_tracker;
1514 }
1515
1516 //--------------------------------------------------------------------------
1517 inline bool LgEvent::is_barrier(void) const
1518 //--------------------------------------------------------------------------
1519 {
1520 const Realm::ID identity(id);
1521 return identity.is_barrier();
1522 }
1523
1524 } // namespace Internal
1525} // namespace Legion
1526
1527#define FRIEND_ALL_RUNTIME_CLASSES \
1528 friend class Legion::Runtime; \
1529 friend class Legion::Mapping::MapperRuntime; \
1530 friend class Internal::Runtime; \
1531 friend class Internal::FutureCreateInstanceRequest; \
1532 friend class Internal::FutureMapFutureRequest; \
1533 friend class Internal::FutureImpl; \
1534 friend class Internal::FutureMapImpl; \
1535 friend class Internal::PhysicalRegionImpl; \
1536 friend class Internal::ExternalResourcesImpl; \
1537 friend class Internal::TaskImpl; \
1538 friend class Internal::VariantImpl; \
1539 friend class Internal::ProcessorManager; \
1540 friend class Internal::MemoryManager; \
1541 friend class Internal::Operation; \
1542 friend class Internal::PredicatedOp; \
1543 friend class Internal::MapOp; \
1544 friend class Internal::CopyOp; \
1545 friend class Internal::IndexCopyOp; \
1546 friend class Internal::PointCopyOp; \
1547 friend class Internal::FenceOp; \
1548 friend class Internal::DynamicCollectiveOp; \
1549 friend class Internal::FuturePredOp; \
1550 friend class Internal::CreationOp; \
1551 friend class Internal::DeletionOp; \
1552 friend class Internal::CloseOp; \
1553 friend class Internal::MergeCloseOp; \
1554 friend class Internal::PostCloseOp; \
1555 friend class Internal::RefinementOp; \
1556 friend class Internal::ResetOp; \
1557 friend class Internal::AcquireOp; \
1558 friend class Internal::ReleaseOp; \
1559 friend class Internal::PredicateImpl; \
1560 friend class Internal::NotPredOp; \
1561 friend class Internal::AndPredOp; \
1562 friend class Internal::OrPredOp; \
1563 friend class Internal::MustEpochOp; \
1564 friend class Internal::PendingPartitionOp; \
1565 friend class Internal::DependentPartitionOp; \
1566 friend class Internal::PointDepPartOp; \
1567 friend class Internal::FillOp; \
1568 friend class Internal::IndexFillOp; \
1569 friend class Internal::PointFillOp; \
1570 friend class Internal::DiscardOp; \
1571 friend class Internal::AttachOp; \
1572 friend class Internal::IndexAttachOp; \
1573 friend class Internal::ReplIndexAttachOp; \
1574 friend class Internal::PointAttachOp; \
1575 friend class Internal::DetachOp; \
1576 friend class Internal::IndexDetachOp; \
1577 friend class Internal::ReplIndexDetachOp; \
1578 friend class Internal::PointDetachOp; \
1579 friend class Internal::TimingOp; \
1580 friend class Internal::TunableOp; \
1581 friend class Internal::AllReduceOp; \
1582 friend class Internal::TraceRecurrentOp; \
1583 friend class Internal::ExternalMappable; \
1584 friend class Internal::ExternalTask; \
1585 friend class Internal::TaskOp; \
1586 friend class Internal::SingleTask; \
1587 friend class Internal::MultiTask; \
1588 friend class Internal::IndividualTask; \
1589 friend class Internal::PointTask; \
1590 friend class Internal::IndexTask; \
1591 friend class Internal::SliceTask; \
1592 friend class Internal::ReplIndividualTask; \
1593 friend class Internal::ReplIndexTask; \
1594 friend class Internal::ReplFillOp; \
1595 friend class Internal::ReplIndexFillOp; \
1596 friend class Internal::ReplDiscardOp; \
1597 friend class Internal::ReplCopyOp; \
1598 friend class Internal::ReplIndexCopyOp; \
1599 friend class Internal::ReplDeletionOp; \
1600 friend class Internal::ReplPendingPartitionOp; \
1601 friend class Internal::ReplDependentPartitionOp; \
1602 friend class Internal::ReplMustEpochOp; \
1603 friend class Internal::ReplMapOp; \
1604 friend class Internal::ReplTimingOp; \
1605 friend class Internal::ReplTunableOp; \
1606 friend class Internal::ReplAllReduceOp; \
1607 friend class Internal::ReplFenceOp; \
1608 friend class Internal::ReplAttachOp; \
1609 friend class Internal::ReplDetachOp; \
1610 friend class Internal::ReplAcquireOp; \
1611 friend class Internal::ReplReleaseOp; \
1612 friend class Internal::MemoizableOp; \
1613 template<typename OP> \
1614 friend class Internal::Memoizable; \
1615 friend class Internal::ShardManager; \
1616 friend class Internal::IndexSpaceNode; \
1617 template<int, typename> \
1618 friend class Internal::IndexSpaceNodeT; \
1619 friend class Internal::IndexPartNode; \
1620 friend class Internal::FieldSpaceNode; \
1621 friend class Internal::RegionTreeNode; \
1622 friend class Internal::RegionNode; \
1623 friend class Internal::PartitionNode; \
1624 friend class Internal::LogicalView; \
1625 friend class Internal::InstanceView; \
1626 friend class Internal::DeferredView; \
1627 friend class Internal::ReductionView; \
1628 friend class Internal::MaterializedView; \
1629 friend class Internal::FillView; \
1630 friend class Internal::LayoutDescription; \
1631 friend class Internal::InstanceManager; \
1632 friend class Internal::PhysicalManager; \
1633 friend class Internal::MapperManager; \
1634 friend class Internal::InstanceRef; \
1635 friend class Internal::HandshakeImpl; \
1636 friend class Internal::ArgumentMapImpl; \
1637 friend class Internal::FutureMapImpl; \
1638 friend class Internal::ReplFutureMapImpl; \
1639 friend class Internal::TaskContext; \
1640 friend class Internal::InnerContext; \
1641 friend class Internal::TopLevelContext; \
1642 friend class Internal::RemoteContext; \
1643 friend class Internal::LeafContext; \
1644 friend class Internal::ReplicateContext; \
1645 friend class Internal::InstanceBuilder; \
1646 friend class Internal::FutureNameExchange; \
1647 friend class Internal::MustEpochMappingExchange; \
1648 friend class Internal::MustEpochMappingBroadcast; \
1649 friend class Internal::MappingCallInfo; \
1650 friend class CObjectWrapper;
1651
1652#endif // __LEGION_TYPES_H__
Definition mapping.h:235
Definition constraints.h:689
Definition mapping.h:287
Definition constraints.h:202
Definition mapping.h:180
Definition constraints.h:640
Definition geometry.h:154
Definition geometry.h:29
Definition exception.h:170
Definition constraints.h:240
Definition constraints.h:475
Definition mapping.h:307
Definition constraints.h:61
Definition mapping.h:211
Definition types.h:898
Definition types.h:850
Definition types.h:881
Definition types.h:1125
Definition types.h:1243
Definition types.h:576
Definition types.h:563
Definition types.h:560
Definition types.h:551
Definition types.h:573
Definition types.h:800
Definition types.h:1008
Definition types.h:490
Definition types.h:822
Definition types.h:833
Definition types.h:492
Definition types.h:964
Definition types.h:935
Definition types.h:947
Definition types.h:705
Definition constraints.h:167
Definition constraints.h:881
Definition interop.h:33
Definition data.h:255
Definition data.h:184
Definition interop.h:96
Definition mapping.h:37
Definition mapping.h:3087
Definition mapping.h:481
Definition mapping.h:517
Definition mapping.h:633
Definition mapping.h:405
Definition constraints.h:422
Definition mapping.h:372
Definition constraints.h:737
Definition constraints.h:538
Definition constraints.h:830
Definition mapping.h:337
Definition physical_region.h:231
Definition physical_region.h:270
Definition functors.h:376
Definition constraints.h:783
Definition constraints.h:95
Definition functors.h:40
Definition mapping.h:259
Definition constraints.h:132
Definition runtime.h:103
Definition functors.h:281
Definition physical_region.h:602
Definition constraints.h:357
Definition mapping.h:107
Definition constraints.h:942
Definition constraints.h:592
Definition types.h:259
Definition types.h:334
Definition runtime.h:41
Definition runtime.h:51