| //===--- Level Zero Target RTL Implementation -----------------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // Level Zero Event and Event Pool abstractions. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #ifndef OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0EVENT_H | |
| #define OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0EVENT_H | |
| #include <level_zero/ze_api.h> | |
| #include <memory> | |
| #include <mutex> | |
| #include "L0Defs.h" | |
| #include "L0Trace.h" | |
| #include "PluginInterface.h" | |
| namespace llvm::omp::target::plugin { | |
| class L0QueueTy; | |
| class L0EventTy { | |
| ze_event_handle_t ZeEvent = nullptr; | |
| bool CounterBased = false; | |
| L0QueueTy *Queue = nullptr; | |
| public: | |
| L0EventTy(ze_event_handle_t ZeEvent, bool CounterBased) | |
| : ZeEvent(ZeEvent), CounterBased(CounterBased) {} | |
| ze_event_handle_t getZeEvent() const { return ZeEvent; } | |
| L0QueueTy *getQueue() const { return Queue; } | |
| Error reset() { | |
| Queue = nullptr; | |
| if (!CounterBased) | |
| CALL_ZE_RET_ERROR(zeEventHostReset, ZeEvent); | |
| return Plugin::success(); | |
| } | |
| void setQueue(L0QueueTy &Q) { Queue = &Q; } | |
| Error synchronize() { | |
| CALL_ZE_RET_ERROR(zeEventHostSynchronize, ZeEvent, L0DefaultTimeout); | |
| return Plugin::success(); | |
| } | |
| Expected<bool> isComplete() { | |
| ze_result_t Result; | |
| CALL_ZE(Result, zeEventQueryStatus, ZeEvent); | |
| if (Result == ZE_RESULT_SUCCESS) | |
| return true; | |
| if (Result == ZE_RESULT_NOT_READY) | |
| return false; | |
| return Plugin::error(ErrorCode::UNKNOWN, "failed to query event status: %s", | |
| getZeErrorName(Result)); | |
| } | |
| }; | |
| /// Common event pool used in the plugin. This event pool assumes all events | |
| /// from the pool are host-visible and use the same event pool flag. | |
| class EventPoolTy { | |
| /// Size of L0 event pool created on demand. | |
| size_t PoolSize = 64; | |
| /// Context of the events. | |
| ze_context_handle_t Context = nullptr; | |
| /// Additional event pool flags common to this pool. | |
| uint32_t Flags = 0; | |
| /// Whether counter-based events are being used (don't need reset). | |
| bool UseCounterBasedEvents = false; | |
| /// Protection. | |
| std::unique_ptr<std::mutex> Mtx; | |
| /// Created L0 event pools. | |
| llvm::SmallVector<ze_event_pool_handle_t> Pools; | |
| /// L0 events cache. | |
| llvm::SmallVector<ze_event_handle_t> Events; | |
| /// L0 event objects cache. | |
| llvm::SmallVector<L0EventTy *> EventObjects; | |
| // Internal method to get an event from the pool. The caller must hold the | |
| // lock. | |
| Expected<ze_event_handle_t> getEventLocked(); | |
| public: | |
| /// Initialize context, flags, and mutex. | |
| Error init(ze_context_handle_t ContextIn, bool UseCounterBased, | |
| uint32_t FlagsIn) { | |
| Context = ContextIn; | |
| Flags = FlagsIn; | |
| UseCounterBasedEvents = UseCounterBased; | |
| Mtx.reset(new std::mutex); | |
| return Plugin::success(); | |
| } | |
| /// Destroys L0 resources. | |
| Error deinit() { | |
| for (auto *EventObj : EventObjects) | |
| delete EventObj; | |
| for (auto E : Events) | |
| CALL_ZE_RET_ERROR(zeEventDestroy, E); | |
| for (auto P : Pools) | |
| CALL_ZE_RET_ERROR(zeEventPoolDestroy, P); | |
| return Plugin::success(); | |
| } | |
| /// Get a L0 Event (ze_event_handle_t) from the pool. | |
| Expected<ze_event_handle_t> getEvent() { | |
| std::lock_guard<std::mutex> Lock(*Mtx); | |
| return getEventLocked(); | |
| } | |
| /// Get an L0EventTy object that wraps a ze_event_handle_t from the pool. | |
| /// This is the preferred way to get an event unless a raw event is really | |
| /// needed. | |
| Expected<L0EventTy *> getEventObject(); | |
| /// Return a ze_event_handle_t to the pool. | |
| Error releaseEvent(ze_event_handle_t Event); | |
| /// Returns an L0EventTy object to the pool so it can be reused. This does not | |
| /// return the underlying ze_event_handle_t to the handle pool. | |
| Error releaseEventObject(L0EventTy *EventObj); | |
| }; | |
| } // namespace llvm::omp::target::plugin | |
| #endif // OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0EVENT_H |