Skip to content

Commit b99d24f

Browse files
committed
fix event caching
L0 requires the adapter to use a variety of different events, depending on the specific use case and configuration. Events are also unique for devices. And, because the adapter wants to avoid unnecessarily allocating new events from the driver, this necessities an event caching solution that can separate the different event type and device combinations. When counter-based events were introduced the event caching was not properly expanded to take that event type into consideration, presumably with the assumption that normal and counter based events will never coexist. Unfortunately that is not true for the current adapter implementation. This patch simplifies the event caching logic, ensuring that each unique event type and device combination has its own event cache.
1 parent 382ae77 commit b99d24f

File tree

2 files changed

+56
-43
lines changed

2 files changed

+56
-43
lines changed

source/adapters/level_zero/context.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -565,18 +565,26 @@ ur_event_handle_t ur_context_handle_t_::getEventFromContextCache(
565565
bool HostVisible, bool WithProfiling, ur_device_handle_t Device,
566566
bool CounterBasedEventEnabled) {
567567
std::scoped_lock<ur_mutex> Lock(EventCacheMutex);
568-
auto Cache = getEventCache(HostVisible, WithProfiling, Device);
569-
if (Cache->empty())
568+
auto Cache = getEventCache(HostVisible, WithProfiling, Device,
569+
CounterBasedEventEnabled);
570+
if (Cache->empty()) {
571+
logger::info("Cache empty (Host Visible: {}, Profiling: {}, Counter: {}, "
572+
"Device: {})",
573+
HostVisible, WithProfiling, CounterBasedEventEnabled, Device);
570574
return nullptr;
575+
}
571576

572577
auto It = Cache->begin();
573578
ur_event_handle_t Event = *It;
574-
if (Event->CounterBasedEventsEnabled != CounterBasedEventEnabled) {
575-
return nullptr;
576-
}
577579
Cache->erase(It);
578580
// We have to reset event before using it.
579581
Event->reset();
582+
583+
logger::info("Using {} event (Host Visible: {}, Profiling: {}, Counter: {}, "
584+
"Device: {}) from cache {}",
585+
Event, Event->HostVisibleEvent, Event->isProfilingEnabled(),
586+
Event->CounterBasedEventsEnabled, Device, Cache);
587+
580588
return Event;
581589
}
582590

@@ -588,8 +596,13 @@ void ur_context_handle_t_::addEventToContextCache(ur_event_handle_t Event) {
588596
Device = Event->UrQueue->Device;
589597
}
590598

591-
auto Cache = getEventCache(Event->isHostVisible(),
592-
Event->isProfilingEnabled(), Device);
599+
auto Cache =
600+
getEventCache(Event->isHostVisible(), Event->isProfilingEnabled(), Device,
601+
Event->CounterBasedEventsEnabled);
602+
logger::info("Inserting {} event (Host Visible: {}, Profiling: {}, Counter: "
603+
"{}, Device: {}) into cache {}",
604+
Event, Event->HostVisibleEvent, Event->isProfilingEnabled(),
605+
Event->CounterBasedEventsEnabled, Device, Cache);
593606
Cache->emplace_back(Event);
594607
}
595608

source/adapters/level_zero/context.hpp

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -169,15 +169,6 @@ struct ur_context_handle_t_ : _ur_object {
169169
// holding the current pool usage counts.
170170
ur_mutex ZeEventPoolCacheMutex;
171171

172-
// Mutex to control operations on event caches.
173-
ur_mutex EventCacheMutex;
174-
175-
// Caches for events.
176-
using EventCache = std::vector<std::list<ur_event_handle_t>>;
177-
EventCache EventCaches{4};
178-
std::vector<std::unordered_map<ur_device_handle_t, size_t>>
179-
EventCachesDeviceMap{4};
180-
181172
// Initialize the PI context.
182173
ur_result_t initialize();
183174

@@ -313,36 +304,45 @@ struct ur_context_handle_t_ : _ur_object {
313304
ze_context_handle_t getZeHandle() const;
314305

315306
private:
307+
enum EventFlags {
308+
EVENT_FLAG_HOST_VISIBLE = UR_BIT(0),
309+
EVENT_FLAG_WITH_PROFILING = UR_BIT(1),
310+
EVENT_FLAG_COUNTER = UR_BIT(2),
311+
EVENT_FLAG_DEVICE = UR_BIT(3), // if set, subsequent bits are device id
312+
MAX_EVENT_FLAG_BITS =
313+
4, // this is used as an offset for embedding device id
314+
};
315+
316+
// Mutex to control operations on event caches.
317+
ur_mutex EventCacheMutex;
318+
319+
// Caches for events.
320+
using EventCache = std::list<ur_event_handle_t>;
321+
std::vector<EventCache> EventCaches;
322+
316323
// Get the cache of events for a provided scope and profiling mode.
317-
auto getEventCache(bool HostVisible, bool WithProfiling,
318-
ur_device_handle_t Device) {
324+
EventCache *getEventCache(bool HostVisible, bool WithProfiling,
325+
ur_device_handle_t Device, bool Counter) {
326+
327+
size_t index = 0;
319328
if (HostVisible) {
320-
if (Device) {
321-
auto EventCachesMap =
322-
WithProfiling ? &EventCachesDeviceMap[0] : &EventCachesDeviceMap[1];
323-
if (EventCachesMap->find(Device) == EventCachesMap->end()) {
324-
EventCaches.emplace_back();
325-
EventCachesMap->insert(
326-
std::make_pair(Device, EventCaches.size() - 1));
327-
}
328-
return &EventCaches[(*EventCachesMap)[Device]];
329-
} else {
330-
return WithProfiling ? &EventCaches[0] : &EventCaches[1];
331-
}
332-
} else {
333-
if (Device) {
334-
auto EventCachesMap =
335-
WithProfiling ? &EventCachesDeviceMap[2] : &EventCachesDeviceMap[3];
336-
if (EventCachesMap->find(Device) == EventCachesMap->end()) {
337-
EventCaches.emplace_back();
338-
EventCachesMap->insert(
339-
std::make_pair(Device, EventCaches.size() - 1));
340-
}
341-
return &EventCaches[(*EventCachesMap)[Device]];
342-
} else {
343-
return WithProfiling ? &EventCaches[2] : &EventCaches[3];
344-
}
329+
index |= EVENT_FLAG_HOST_VISIBLE;
330+
}
331+
if (WithProfiling) {
332+
index |= EVENT_FLAG_WITH_PROFILING;
345333
}
334+
if (Counter) {
335+
index |= EVENT_FLAG_COUNTER;
336+
}
337+
if (Device) {
338+
index |= EVENT_FLAG_DEVICE | (*Device->Id << MAX_EVENT_FLAG_BITS);
339+
}
340+
341+
if (index >= EventCaches.size()) {
342+
EventCaches.resize(index + 1);
343+
}
344+
345+
return &EventCaches[index];
346346
}
347347
};
348348

0 commit comments

Comments
 (0)