@@ -93,22 +93,36 @@ struct AllocInfo {
93
93
ol_alloc_type_t Type;
94
94
};
95
95
96
- using AllocInfoMapT = DenseMap<void *, AllocInfo>;
97
- AllocInfoMapT &allocInfoMap () {
98
- static AllocInfoMapT AllocInfoMap{};
99
- return AllocInfoMap;
100
- }
96
+ // Global shared state for liboffload
97
+ struct OffloadContext ;
98
+ static OffloadContext *OffloadContextVal;
99
+ struct OffloadContext {
100
+ OffloadContext (OffloadContext &) = delete ;
101
+ OffloadContext (OffloadContext &&) = delete ;
102
+ OffloadContext &operator =(OffloadContext &) = delete ;
103
+ OffloadContext &operator =(OffloadContext &&) = delete ;
104
+
105
+ bool TracingEnabled = false ;
106
+ bool ValidationEnabled = true ;
107
+ DenseMap<void *, AllocInfo> AllocInfoMap{};
108
+ SmallVector<ol_platform_impl_t , 4 > Platforms{};
109
+
110
+ ol_device_handle_t HostDevice () {
111
+ // The host platform is always inserted last
112
+ return &Platforms.back ().Devices [0 ];
113
+ }
101
114
102
- using PlatformVecT = SmallVector< ol_platform_impl_t , 4 >;
103
- PlatformVecT & Platforms () {
104
- static PlatformVecT Platforms ;
105
- return Platforms;
106
- }
115
+ static OffloadContext & get () {
116
+ assert (OffloadContextVal);
117
+ return *OffloadContextVal ;
118
+ }
119
+ };
107
120
108
- ol_device_handle_t HostDevice () {
109
- // The host platform is always inserted last
110
- return & Platforms ().back (). Devices [ 0 ] ;
121
+ // If the context is uninited, then we assume tracing is disabled
122
+ bool isTracingEnabled () {
123
+ return OffloadContextVal && OffloadContext::get ().TracingEnabled ;
111
124
}
125
+ bool isValidationEnabled () { return OffloadContext::get ().ValidationEnabled ; }
112
126
113
127
template <typename HandleT> Error olDestroy (HandleT Handle) {
114
128
delete Handle;
@@ -130,18 +144,20 @@ constexpr ol_platform_backend_t pluginNameToBackend(StringRef Name) {
130
144
#include " Shared/Targets.def"
131
145
132
146
void initPlugins () {
147
+ auto *Context = new OffloadContext{};
148
+
133
149
// Attempt to create an instance of each supported plugin.
134
150
#define PLUGIN_TARGET (Name ) \
135
151
do { \
136
- Platforms () .emplace_back (ol_platform_impl_t { \
152
+ Context-> Platforms .emplace_back (ol_platform_impl_t { \
137
153
std::unique_ptr<GenericPluginTy>(createPlugin_##Name ()), \
138
154
{}, \
139
155
pluginNameToBackend (#Name)}); \
140
156
} while (false );
141
157
#include " Shared/Targets.def"
142
158
143
159
// Preemptively initialize all devices in the plugin
144
- for (auto &Platform : Platforms () ) {
160
+ for (auto &Platform : Context-> Platforms ) {
145
161
// Do not use the host plugin - it isn't supported.
146
162
if (Platform.BackendType == OL_PLATFORM_BACKEND_UNKNOWN)
147
163
continue ;
@@ -157,15 +173,16 @@ void initPlugins() {
157
173
}
158
174
159
175
// Add the special host device
160
- auto &HostPlatform = Platforms () .emplace_back (
176
+ auto &HostPlatform = Context-> Platforms .emplace_back (
161
177
ol_platform_impl_t {nullptr ,
162
178
{ol_device_impl_t {-1 , nullptr , nullptr }},
163
179
OL_PLATFORM_BACKEND_HOST});
164
- HostDevice ()->Platform = &HostPlatform;
180
+ Context->HostDevice ()->Platform = &HostPlatform;
181
+
182
+ Context->TracingEnabled = std::getenv (" OFFLOAD_TRACE" );
183
+ Context->ValidationEnabled = !std::getenv (" OFFLOAD_DISABLE_VALIDATION" );
165
184
166
- offloadConfig ().TracingEnabled = std::getenv (" OFFLOAD_TRACE" );
167
- offloadConfig ().ValidationEnabled =
168
- !std::getenv (" OFFLOAD_DISABLE_VALIDATION" );
185
+ OffloadContextVal = Context;
169
186
}
170
187
171
188
// TODO: We can properly reference count here and manage the resources in a more
@@ -229,7 +246,7 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
229
246
230
247
// Find the info if it exists under any of the given names
231
248
auto GetInfo = [&](std::vector<std::string> Names) {
232
- if (Device == HostDevice ())
249
+ if (Device == OffloadContext::get (). HostDevice ())
233
250
return std::string (" Host" );
234
251
235
252
if (!Device->Device )
@@ -251,8 +268,9 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
251
268
case OL_DEVICE_INFO_PLATFORM:
252
269
return ReturnValue (Device->Platform );
253
270
case OL_DEVICE_INFO_TYPE:
254
- return Device == HostDevice () ? ReturnValue (OL_DEVICE_TYPE_HOST)
255
- : ReturnValue (OL_DEVICE_TYPE_GPU);
271
+ return Device == OffloadContext::get ().HostDevice ()
272
+ ? ReturnValue (OL_DEVICE_TYPE_HOST)
273
+ : ReturnValue (OL_DEVICE_TYPE_GPU);
256
274
case OL_DEVICE_INFO_NAME:
257
275
return ReturnValue (GetInfo ({" Device Name" }).c_str ());
258
276
case OL_DEVICE_INFO_VENDOR:
@@ -280,7 +298,7 @@ Error olGetDeviceInfoSize_impl(ol_device_handle_t Device,
280
298
}
281
299
282
300
Error olIterateDevices_impl (ol_device_iterate_cb_t Callback, void *UserData) {
283
- for (auto &Platform : Platforms () ) {
301
+ for (auto &Platform : OffloadContext::get (). Platforms ) {
284
302
for (auto &Device : Platform.Devices ) {
285
303
if (!Callback (&Device, UserData)) {
286
304
break ;
@@ -311,24 +329,25 @@ Error olMemAlloc_impl(ol_device_handle_t Device, ol_alloc_type_t Type,
311
329
return Alloc.takeError ();
312
330
313
331
*AllocationOut = *Alloc;
314
- allocInfoMap ().insert_or_assign (*Alloc, AllocInfo{Device, Type});
332
+ OffloadContext::get ().AllocInfoMap .insert_or_assign (*Alloc,
333
+ AllocInfo{Device, Type});
315
334
return Error::success ();
316
335
}
317
336
318
337
Error olMemFree_impl (void *Address) {
319
- if (!allocInfoMap () .contains (Address))
338
+ if (!OffloadContext::get (). AllocInfoMap .contains (Address))
320
339
return createOffloadError (ErrorCode::INVALID_ARGUMENT,
321
340
" address is not a known allocation" );
322
341
323
- auto AllocInfo = allocInfoMap () .at (Address);
342
+ auto AllocInfo = OffloadContext::get (). AllocInfoMap .at (Address);
324
343
auto Device = AllocInfo.Device ;
325
344
auto Type = AllocInfo.Type ;
326
345
327
346
if (auto Res =
328
347
Device->Device ->dataDelete (Address, convertOlToPluginAllocTy (Type)))
329
348
return Res;
330
349
331
- allocInfoMap () .erase (Address);
350
+ OffloadContext::get (). AllocInfoMap .erase (Address);
332
351
333
352
return Error::success ();
334
353
}
@@ -395,7 +414,8 @@ Error olMemcpy_impl(ol_queue_handle_t Queue, void *DstPtr,
395
414
ol_device_handle_t DstDevice, const void *SrcPtr,
396
415
ol_device_handle_t SrcDevice, size_t Size,
397
416
ol_event_handle_t *EventOut) {
398
- if (DstDevice == HostDevice () && SrcDevice == HostDevice ()) {
417
+ auto Host = OffloadContext::get ().HostDevice ();
418
+ if (DstDevice == Host && SrcDevice == Host) {
399
419
if (!Queue) {
400
420
std::memcpy (DstPtr, SrcPtr, Size);
401
421
return Error::success ();
@@ -410,11 +430,11 @@ Error olMemcpy_impl(ol_queue_handle_t Queue, void *DstPtr,
410
430
// If no queue is given the memcpy will be synchronous
411
431
auto QueueImpl = Queue ? Queue->AsyncInfo : nullptr ;
412
432
413
- if (DstDevice == HostDevice () ) {
433
+ if (DstDevice == Host ) {
414
434
if (auto Res =
415
435
SrcDevice->Device ->dataRetrieve (DstPtr, SrcPtr, Size, QueueImpl))
416
436
return Res;
417
- } else if (SrcDevice == HostDevice () ) {
437
+ } else if (SrcDevice == Host ) {
418
438
if (auto Res =
419
439
DstDevice->Device ->dataSubmit (DstPtr, SrcPtr, Size, QueueImpl))
420
440
return Res;
0 commit comments