Realm
A distributed, event-based tasking library
Loading...
Searching...
No Matches
processor.h
Go to the documentation of this file.
1/*
2 * Copyright 2025 Stanford University, NVIDIA Corporation
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18// processors for Realm
19
20#ifndef REALM_PROCESSOR_H
21#define REALM_PROCESSOR_H
22
23#include "realm/realm_c.h"
24
25#include "realm/event.h"
26
27#include <vector>
28#include <map>
29
30namespace Realm {
31
33
34 class ProfilingRequestSet;
35 class CodeDescriptor;
36
38 public:
40
42
43 Processor() = default;
44 constexpr explicit Processor(id_t id)
45 : id(id)
46 {}
47
48 constexpr operator id_t() const { return id; }
49
50 bool operator<(const Processor &rhs) const { return id < rhs.id; }
51 bool operator==(const Processor &rhs) const { return id == rhs.id; }
52 bool operator!=(const Processor &rhs) const { return id != rhs.id; }
53
54 static const Processor NO_PROC;
55
56 bool exists(void) const { return id != 0; }
57
59 typedef void (*TaskFuncPtr)(const void *args, size_t arglen, const void *user_data,
60 size_t user_data_len, Processor proc);
61
62 // Different Processor types (defined in realm_c.h)
63 // can't just typedef the kind because of C/C++ enum scope rules
64 enum Kind
65 {
66#define C_ENUMS(name, desc) name,
68#undef C_ENUMS
69 };
70
71 // Return what kind of processor this is
72 Kind kind(void) const;
73 // Return the address space for this processor
75
77 "use ProcessorGroup::create_group instead",
78 static Processor create_group(const span<const Processor> &members));
79
80 void get_group_members(Processor *member_list, size_t &num_members) const;
81 void get_group_members(std::vector<Processor> &member_list) const;
82
83 int get_num_cores(void) const;
84
85 // special task IDs
86 enum
87 {
88 // Save ID 0 for the force shutdown function
89 TASK_ID_PROCESSOR_NOP = REALM_TASK_ID_PROCESSOR_NOP,
90 TASK_ID_PROCESSOR_INIT = REALM_TASK_ID_PROCESSOR_INIT,
91 TASK_ID_PROCESSOR_SHUTDOWN = REALM_TASK_ID_PROCESSOR_SHUTDOWN,
92 TASK_ID_FIRST_AVAILABLE = REALM_TASK_ID_FIRST_AVAILABLE,
93 };
94
95 Event spawn(TaskFuncID func_id, const void *args, size_t arglen,
96 Event wait_on = Event::NO_EVENT, int priority = 0) const;
97
98 // Same as the above but with requests for profiling
99 Event spawn(TaskFuncID func_id, const void *args, size_t arglen,
100 const ProfilingRequestSet &requests, Event wait_on = Event::NO_EVENT,
101 int priority = 0) const;
102
104
105 // changes the priority of the currently running task
106 static void set_current_task_priority(int new_priority);
107
108 // returns the finish event for the currently running task
110
111 // Add an event that must be a precondition for triggering
112 // the finish event for the currently running task. This allows
113 // for other asynchronous effects from the task to be accumulated
114 // into finish event dynamically and for the task to exit without
115 // needing to block and wait for these events to trigger.
117
118 // a scheduler lock prevents the current thread from releasing its
119 // execution resources even when waiting on an Event - multiple
120 // nested calls to 'enable_scheduler_lock' are permitted, but a
121 // matching number of calls to 'disable_scheduler_lock' are required
122 static void enable_scheduler_lock(void);
123 static void disable_scheduler_lock(void);
124
125 // dynamic task registration - this may be done for:
126 // 1) a specific processor/group (anywhere in the system)
127 // 2) for all processors of a given type, either in the local address space/process,
128 // or globally
129 //
130 // in both cases, an Event is returned, and any tasks launched that expect to use the
131 // newly-registered task IDs must include that event as a precondition
132
134 const ProfilingRequestSet &prs, const void *user_data = 0,
135 size_t user_data_len = 0) const;
136
137 static Event register_task_by_kind(Kind target_kind, bool global, TaskFuncID func_id,
138 const CodeDescriptor &codedesc,
139 const ProfilingRequestSet &prs,
140 const void *user_data = 0,
141 size_t user_data_len = 0);
142
143 // reports an execution fault in the currently running task
144 static void report_execution_fault(int reason, const void *reason_data,
145 size_t reason_size);
146
147 // reports a problem with a processor in general (this is primarily for fault
148 // injection)
149 void report_processor_fault(int reason, const void *reason_data,
150 size_t reason_size) const;
151
152 static const char *get_kind_name(Kind kind);
153
154#ifdef REALM_USE_KOKKOS
155 // Kokkos execution policies will accept an "execution instance" to
156 // capture task parallelism - provide those here
157 class KokkosExecInstance;
158
159 KokkosExecInstance kokkos_work_space(void) const;
160#endif
161 };
162
163#if defined(REALM_USE_KOKKOS)
164 // Kokkos defines this but we can't use it :(
165 template <typename T>
166 class is_kokkos_execution_space {
167 typedef char yes;
168 typedef long no;
169
170 template <typename C>
171 static yes check(typename C::execution_space *);
172 template <typename C>
173 static no check(...);
174
175 public:
176 static constexpr bool value = sizeof(check<T>(0)) == sizeof(yes);
177 };
178
179 class REALM_PUBLIC_API Processor::KokkosExecInstance {
180 public:
181 KokkosExecInstance(Processor _p);
182
183 // template-fu will type-check a coercion to any Kokkos execution
184 // space type - runtime will verify a valid type was requested
185 template <typename exec_space,
186 typename std::enable_if<is_kokkos_execution_space<exec_space>::value,
187 int>::type = 0>
188 operator exec_space() const;
189
190 protected:
191 Processor p;
192 };
193#endif
194
195 // a processor group is a set of processors that share a ready task queue
196 // (in addition to their own processor-specific task queues)
197 // NOTE: processor groups are currently limited to include processors from
198 // only a single node/rank in a distributed setting
200 public:
201 static ProcessorGroup create_group(const Processor *members, size_t num_members);
205 {
206 return create_group(members.data(), members.size());
207 }
208 void destroy(Event wait_on = Event::NO_EVENT) const;
209
211 };
212
213}; // namespace Realm
214
215#include "realm/processor.inl"
216
217#endif // ifndef REALM_PROCESSOR_H
Definition codedesc.h:249
Definition event.h:50
Definition processor.h:199
void destroy(Event wait_on=Event::NO_EVENT) const
static const ProcessorGroup NO_PROC_GROUP
Definition processor.h:210
static ProcessorGroup create_group(const span< const Processor > &members)
Definition processor.h:204
static ProcessorGroup create_group(const Processor *members, size_t num_members)
Definition processor.h:37
bool operator==(const Processor &rhs) const
Definition processor.h:51
void get_group_members(std::vector< Processor > &member_list) const
id_t id
Definition processor.h:41
constexpr Processor(id_t id)
Definition processor.h:44
bool exists(void) const
Definition processor.h:56
void get_group_members(Processor *member_list, size_t &num_members) const
REALM_ATTR_DEPRECATED("use ProcessorGroup::create_group instead", static Processor create_group(const span< const Processor > &members))
static Processor get_executing_processor(void)
static const char * get_kind_name(Kind kind)
::realm_id_t id_t
Definition processor.h:39
Event spawn(TaskFuncID func_id, const void *args, size_t arglen, const ProfilingRequestSet &requests, Event wait_on=Event::NO_EVENT, int priority=0) const
Event register_task(TaskFuncID func_id, const CodeDescriptor &codedesc, const ProfilingRequestSet &prs, const void *user_data=0, size_t user_data_len=0) const
static void report_execution_fault(int reason, const void *reason_data, size_t reason_size)
Kind
Definition processor.h:65
int get_num_cores(void) const
void report_processor_fault(int reason, const void *reason_data, size_t reason_size) const
static Event register_task_by_kind(Kind target_kind, bool global, TaskFuncID func_id, const CodeDescriptor &codedesc, const ProfilingRequestSet &prs, const void *user_data=0, size_t user_data_len=0)
static void disable_scheduler_lock(void)
static void enable_scheduler_lock(void)
Event spawn(TaskFuncID func_id, const void *args, size_t arglen, Event wait_on=Event::NO_EVENT, int priority=0) const
static realm_status_t add_finish_event_precondition(Event precondition)
bool operator<(const Processor &rhs) const
Definition processor.h:50
::realm_task_func_id_t TaskFuncID
Definition processor.h:58
static Event get_current_finish_event(void)
static const Processor NO_PROC
Definition processor.h:54
AddressSpace address_space(void) const
Processor()=default
static void set_current_task_priority(int new_priority)
bool operator!=(const Processor &rhs) const
Definition processor.h:52
Kind kind(void) const
Definition profiling.h:363
Definition utils.h:84
#define REALM_PUBLIC_API
Definition compiler_support.h:217
#define C_ENUMS(name, desc)
Definition memory.h:60
Definition activemsg.h:38
::realm_address_space_t AddressSpace
Definition memory.h:31
#define REALM_TASK_ID_FIRST_AVAILABLE
Definition realm_c.h:174
enum realm_status_enum realm_status_t
unsigned long long realm_id_t
Definition realm_c.h:64
#define REALM_TASK_ID_PROCESSOR_NOP
Definition realm_c.h:171
#define REALM_TASK_ID_PROCESSOR_INIT
Definition realm_c.h:172
#define REALM_PROCESSOR_KINDS(__op__)
Definition realm_c.h:227
#define REALM_TASK_ID_PROCESSOR_SHUTDOWN
Definition realm_c.h:173
unsigned int realm_address_space_t
Definition realm_c.h:72
unsigned realm_task_func_id_t
Definition realm_c.h:73
#define REALM_NO_PROC
Definition realm_c.h:165