Realm
A distributed, event-based tasking library
Loading...
Searching...
No Matches
machine.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// machine model for Realm
19
20#ifndef REALM_MACHINE_H
21#define REALM_MACHINE_H
22
23#include "realm/processor.h"
24#include "realm/memory.h"
25
26#include <iterator>
27
28namespace Realm {
29
30 class Runtime;
31
33 protected:
34 friend class Runtime;
35 explicit Machine(void *_impl)
36 : impl(_impl)
37 {}
38
39 public:
40 Machine(const Machine &m)
41 : impl(m.impl)
42 {}
44 {
45 impl = m.impl;
46 return *this;
47 }
48 ~Machine(void) {}
49
50 static Machine get_machine(void);
51
52 class ProcessorQuery;
53 class MemoryQuery;
54
56
57 bool has_affinity(Processor p, Memory m, AffinityDetails *details = 0) const;
58 bool has_affinity(Memory m1, Memory m2, AffinityDetails *details = 0) const;
59
60 // older queries, to be deprecated
61
62 void get_all_memories(std::set<Memory> &mset) const;
63 void get_all_processors(std::set<Processor> &pset) const;
64
65 void get_local_processors(std::set<Processor> &pset) const;
66 void get_local_processors_by_kind(std::set<Processor> &pset,
67 Processor::Kind kind) const;
68
69 // Return the set of memories visible from a processor
70 void get_visible_memories(Processor p, std::set<Memory> &mset,
71 bool local_only = true) const;
72
73 // Return the set of memories visible from a memory
74 void get_visible_memories(Memory m, std::set<Memory> &mset,
75 bool local_only = true) const;
76
77 // Return the set of processors which can all see a given memory
78 void get_shared_processors(Memory m, std::set<Processor> &pset,
79 bool local_only = true) const;
80
81 size_t get_address_space_count(void) const;
82
83 // get information about the OS process in which tasks for a given
84 // processor run - note that the uniqueness of any/all of the provided
85 // information depends on the underlying OS and any container runtimes
86 struct ProcessInfo {
87 static const size_t MAX_HOSTNAME_LENGTH = 256;
88 char hostname[MAX_HOSTNAME_LENGTH]; // always null-terminated
89 uint64_t hostid; // gethostid on posix, hash of hostname on windows
90 uint32_t processid;
91 };
92
93 // populates the `info` struct with information about the processor `p`'s
94 // containing process, returning true if successful, false if the
95 // processor is unknown or the information is unavailable
97
98 public:
100 Processor p; // accessing processor
101 Memory m; // target memory
102 unsigned bandwidth; // in MB/s
103 unsigned latency; // in nanoseconds
104 };
105
107 Memory m1; // source memory
108 Memory m2; // destination memory
109 unsigned bandwidth; // in MB/s
110 unsigned latency; // in nanoseconds
111 };
112
113 int get_proc_mem_affinity(std::vector<ProcessorMemoryAffinity> &result,
114 Processor restrict_proc = Processor::NO_PROC,
115 Memory restrict_memory = Memory::NO_MEMORY,
116 bool local_only = true) const;
117
118 int get_mem_mem_affinity(std::vector<MemoryMemoryAffinity> &result,
119 Memory restrict_mem1 = Memory::NO_MEMORY,
120 Memory restrict_mem2 = Memory::NO_MEMORY,
121 bool local_only = true) const;
122
123 // subscription interface for dynamic machine updates
125 public:
127
129 {
132 THING_UPDATED
133 };
134
135 // callbacks occur on a thread that belongs to the runtime - please defer any
136 // complicated processing if possible
137 virtual void processor_updated(Processor p, UpdateType update_type,
138 const void *payload, size_t payload_size) = 0;
139
140 virtual void memory_updated(Memory m, UpdateType update_type, const void *payload,
141 size_t payload_size) = 0;
142 };
143
144 // subscriptions are encouraged to use a query which filters which processors or
145 // memories cause notifications
148 const ProcessorQuery &query);
149 void add_subscription(MachineUpdateSubscriber *subscriber, const MemoryQuery &query);
150
152
153 void *impl; // hidden internal implementation - this is NOT a transferrable handle
154 };
155
156 template <typename QT, typename RT>
158
159 class REALM_PUBLIC_API Machine::ProcessorQuery {
160 public:
161 explicit ProcessorQuery(const Machine &m);
162 ProcessorQuery(const ProcessorQuery &q);
163
165
166 ProcessorQuery &operator=(const ProcessorQuery &q);
167
168 bool operator==(const ProcessorQuery &compare_to) const;
169 bool operator!=(const ProcessorQuery &compare_to) const;
170
171 // filter predicates (returns self-reference for chaining)
172 // if multiple predicates are used, they must all match (i.e. the intersection is
173 // returned)
174
175 // restrict to just those of the specified 'kind'
176 ProcessorQuery &only_kind(Processor::Kind kind);
177
178 // restrict to those managed by this address space
179 ProcessorQuery &local_address_space(void);
180
181 // restrict to those in same address space as specified Processor or Memory
183 ProcessorQuery &same_address_space_as(Memory m);
184
185 // restrict to those that have affinity to a given memory
186 ProcessorQuery &has_affinity_to(Memory m, unsigned min_bandwidth = 0,
187 unsigned max_latency = 0);
188
189 // restrict to those whose best affinity is to the given memory
190 ProcessorQuery &best_affinity_to(Memory m, int bandwidth_weight = 1,
191 int latency_weight = 0);
192
193 // results - a query may be executed multiple times - when the machine model is
194 // dynamic, there is no guarantee that the results of any two executions will be
195 // consistent
196
197 // return the number of matched processors
198 size_t count(void) const;
199
200 // return the first matched processor, or NO_PROC
201 Processor first(void) const;
202
203 // return the next matched processor after the one given, or NO_PROC
205
206 // return a random matched processor, or NO_PROC if none exist
207 Processor random(void) const;
208
210
211 // return an iterator that allows enumerating all matched processors
212 iterator begin(void) const;
213 iterator end(void) const;
214
215 protected:
216 void *impl;
217 };
218
219 class REALM_PUBLIC_API Machine::MemoryQuery {
220 public:
221 explicit MemoryQuery(const Machine &m);
222 MemoryQuery(const MemoryQuery &q);
223
225
226 MemoryQuery &operator=(const MemoryQuery &q);
227
228 bool operator==(const MemoryQuery &compare_to) const;
229 bool operator!=(const MemoryQuery &compare_to) const;
230
231 // filter predicates (returns self-reference for chaining)
232 // if multiple predicates are used, they must all match (i.e. the intersection is
233 // returned)
234
235 // restrict to just those of the specified 'kind'
236 MemoryQuery &only_kind(Memory::Kind kind);
237
238 // restrict to those managed by this address space
239 MemoryQuery &local_address_space(void);
240
241 // restrict to those in same address space as specified Processor or Memory
244
245 // restrict to those that have affinity to a given processor or memory
246 MemoryQuery &has_affinity_to(Processor p, unsigned min_bandwidth = 0,
247 unsigned max_latency = 0);
248 MemoryQuery &has_affinity_to(Memory m, unsigned min_bandwidth = 0,
249 unsigned max_latency = 0);
250
251 // restrict to those whose best affinity is to the given processor or memory
252 MemoryQuery &best_affinity_to(Processor p, int bandwidth_weight = 1,
253 int latency_weight = 0);
254 MemoryQuery &best_affinity_to(Memory m, int bandwidth_weight = 1,
255 int latency_weight = 0);
256
257 // restrict to those whose total capacity is at least 'min_size' bytes
258 MemoryQuery &has_capacity(size_t min_bytes);
259
260 // results - a query may be executed multiple times - when the machine model is
261 // dynamic, there is no guarantee that the results of any two executions will be
262 // consistent
263
264 // return the number of matched processors
265 size_t count(void) const;
266
267 // return the first matched processor, or NO_PROC
268 Memory first(void) const;
269
270 // return the next matched processor after the one given, or NO_PROC
271 Memory next(Memory after) const;
272
273 // return a random matched processor, or NO_PROC if none exist
274 Memory random(void) const;
275
277
278 // return an iterator that allows enumerating all matched processors
279 iterator begin(void) const;
280 iterator end(void) const;
281
282 protected:
283 void *impl;
284 };
285
286 template <typename QT, typename RT>
288 public:
289 // explicitly set iterator traits
290 typedef std::input_iterator_tag iterator_category;
291 typedef RT value_type;
292 typedef std::ptrdiff_t difference_type;
293 typedef RT *pointer;
294 typedef RT &reference;
295
296 // would like this constructor to be protected and have QT be a friend.
297 // The CUDA compiler also seems to be a little dense here as well
298#if(!defined(__CUDACC__) && !defined(__HIPCC__))
299 protected:
300 friend QT;
301#else
302 public:
303#endif
304 MachineQueryIterator(const QT &_query, RT _result);
305
306 protected:
309
310 public:
313
316
317 bool operator==(const MachineQueryIterator<QT, RT> &compare_to) const;
318 bool operator!=(const MachineQueryIterator<QT, RT> &compare_to) const;
319
320 RT operator*(void);
321 const RT *operator->(void);
322
325
326 // in addition to testing an iterator against .end(), you can also cast to bool,
327 // allowing for(iterator it = q.begin(); q; ++q) ...
328 operator bool(void) const;
329 };
330
331}; // namespace Realm
332
333#include "realm/machine.inl"
334
335#endif // ifndef REALM_MACHINE_H
Definition machine.h:287
MachineQueryIterator< QT, RT > & operator++()
bool operator==(const MachineQueryIterator< QT, RT > &compare_to) const
const RT * operator->(void)
RT & reference
Definition machine.h:294
friend QT
Definition machine.h:300
QT query
Definition machine.h:307
MachineQueryIterator(const MachineQueryIterator< QT, RT > &copy_from)
std::ptrdiff_t difference_type
Definition machine.h:292
MachineQueryIterator< QT, RT > & operator=(const MachineQueryIterator< QT, RT > &copy_from)
RT * pointer
Definition machine.h:293
MachineQueryIterator< QT, RT > operator++(int)
bool operator!=(const MachineQueryIterator< QT, RT > &compare_to) const
RT value_type
Definition machine.h:291
MachineQueryIterator(const QT &_query, RT _result)
RT result
Definition machine.h:308
std::input_iterator_tag iterator_category
Definition machine.h:290
virtual void memory_updated(Memory m, UpdateType update_type, const void *payload, size_t payload_size)=0
virtual void processor_updated(Processor p, UpdateType update_type, const void *payload, size_t payload_size)=0
virtual ~MachineUpdateSubscriber(void)
Definition machine.h:126
UpdateType
Definition machine.h:129
@ THING_ADDED
Definition machine.h:130
@ THING_REMOVED
Definition machine.h:131
Definition machine.h:32
~Machine(void)
Definition machine.h:48
MemoryQuery(const Machine &m)
int get_proc_mem_affinity(std::vector< ProcessorMemoryAffinity > &result, Processor restrict_proc=Processor::NO_PROC, Memory restrict_memory=Memory::NO_MEMORY, bool local_only=true) const
ProcessorQuery & local_address_space(void)
int get_mem_mem_affinity(std::vector< MemoryMemoryAffinity > &result, Memory restrict_mem1=Memory::NO_MEMORY, Memory restrict_mem2=Memory::NO_MEMORY, bool local_only=true) const
void get_local_processors(std::set< Processor > &pset) const
void get_visible_memories(Processor p, std::set< Memory > &mset, bool local_only=true) const
ProcessorQuery & operator=(const ProcessorQuery &q)
MemoryQuery & best_affinity_to(Memory m, int bandwidth_weight=1, int latency_weight=0)
bool operator==(const ProcessorQuery &compare_to) const
bool operator==(const MemoryQuery &compare_to) const
static Machine get_machine(void)
~ProcessorQuery(void)
Processor next(Processor after) const
Machine(const Machine &m)
Definition machine.h:40
void get_shared_processors(Memory m, std::set< Processor > &pset, bool local_only=true) const
void add_subscription(MachineUpdateSubscriber *subscriber, const ProcessorQuery &query)
ProcessorQuery(const ProcessorQuery &q)
Processor first(void) const
MachineQueryIterator< ProcessorQuery, Processor > iterator
Definition machine.h:209
ProcessorQuery & best_affinity_to(Memory m, int bandwidth_weight=1, int latency_weight=0)
void get_all_memories(std::set< Memory > &mset) const
MemoryQuery & has_affinity_to(Processor p, unsigned min_bandwidth=0, unsigned max_latency=0)
ProcessorQuery(const Machine &m)
MemoryQuery & best_affinity_to(Processor p, int bandwidth_weight=1, int latency_weight=0)
MemoryQuery & operator=(const MemoryQuery &q)
Machine(void *_impl)
Definition machine.h:35
MachineQueryIterator< MemoryQuery, Memory > iterator
Definition machine.h:276
MemoryQuery & same_address_space_as(Processor p)
MemoryQuery(const MemoryQuery &q)
void remove_subscription(MachineUpdateSubscriber *subscriber)
Memory first(void) const
void get_visible_memories(Memory m, std::set< Memory > &mset, bool local_only=true) const
Machine & operator=(const Machine &m)
Definition machine.h:43
MemoryQuery & has_affinity_to(Memory m, unsigned min_bandwidth=0, unsigned max_latency=0)
Processor random(void) const
bool get_process_info(Processor p, ProcessInfo *info) const
size_t count(void) const
MemoryQuery & only_kind(Memory::Kind kind)
void get_all_processors(std::set< Processor > &pset) const
MemoryQuery & has_capacity(size_t min_bytes)
bool has_affinity(Processor p, Memory m, AffinityDetails *details=0) const
MemoryQuery & local_address_space(void)
size_t get_address_space_count(void) const
bool operator!=(const ProcessorQuery &compare_to) const
void get_local_processors_by_kind(std::set< Processor > &pset, Processor::Kind kind) const
realm_affinity_details_t AffinityDetails
Definition machine.h:55
Memory random(void) const
ProcessorQuery & same_address_space_as(Processor p)
iterator begin(void) const
bool operator!=(const MemoryQuery &compare_to) const
ProcessorQuery & only_kind(Processor::Kind kind)
void add_subscription(MachineUpdateSubscriber *subscriber, const MemoryQuery &query)
Memory next(Memory after) const
bool has_affinity(Memory m1, Memory m2, AffinityDetails *details=0) const
void add_subscription(MachineUpdateSubscriber *subscriber)
void * impl
Definition machine.h:153
MemoryQuery & same_address_space_as(Memory m)
iterator end(void) const
ProcessorQuery & has_affinity_to(Memory m, unsigned min_bandwidth=0, unsigned max_latency=0)
ProcessorQuery & same_address_space_as(Memory m)
Definition memory.h:33
Kind
Definition memory.h:59
Definition processor.h:37
Kind
Definition processor.h:65
Definition runtime.h:32
#define REALM_PUBLIC_API
Definition compiler_support.h:217
Definition activemsg.h:38
Definition machine.h:106
Memory m1
Definition machine.h:107
Memory m2
Definition machine.h:108
unsigned bandwidth
Definition machine.h:109
unsigned latency
Definition machine.h:110
Definition machine.h:86
uint64_t hostid
Definition machine.h:89
uint32_t processid
Definition machine.h:90
Memory m
Definition machine.h:101
Processor p
Definition machine.h:100
unsigned latency
Definition machine.h:103
unsigned bandwidth
Definition machine.h:102
Definition realm_c.h:285