Retrieve kernel argument sizes directly from Level Zero API as a temporary workaround. This approach assumes no padding or alignment between arguments. This enables immediate functionality while a more permanent solution requiring offload API changes is being discussed.
148 lines
4.7 KiB
C++
148 lines
4.7 KiB
C++
//===--- 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 Context abstraction.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0CONTEXT_H
|
|
#define OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0CONTEXT_H
|
|
|
|
#include "L0Memory.h"
|
|
#include "PerThreadTable.h"
|
|
|
|
namespace llvm::omp::target::plugin {
|
|
|
|
class LevelZeroPluginTy;
|
|
|
|
class L0ContextTLSTy {
|
|
StagingBufferTy StagingBuffer;
|
|
|
|
public:
|
|
StagingBufferTy &getStagingBuffer() { return StagingBuffer; }
|
|
const StagingBufferTy &getStagingBuffer() const { return StagingBuffer; }
|
|
|
|
Error deinit() { return StagingBuffer.clear(); }
|
|
};
|
|
|
|
struct L0ContextTLSTableTy
|
|
: public PerThreadContainer<
|
|
std::unordered_map<ze_context_handle_t, L0ContextTLSTy>> {
|
|
Error deinit() {
|
|
return PerThreadTable::deinit(
|
|
[](L0ContextTLSTy &Entry) -> auto { return Entry.deinit(); });
|
|
}
|
|
};
|
|
|
|
/// Driver and context-specific resources. We assume a single context per
|
|
/// driver.
|
|
class L0ContextTy {
|
|
/// The plugin that created this context.
|
|
LevelZeroPluginTy &Plugin;
|
|
|
|
/// Level Zero Driver handle.
|
|
ze_driver_handle_t zeDriver = nullptr;
|
|
|
|
/// Common Level Zero context.
|
|
ze_context_handle_t zeContext = nullptr;
|
|
|
|
/// API version supported by the Level Zero driver.
|
|
ze_api_version_t APIVersion = ZE_API_VERSION_CURRENT;
|
|
|
|
/// Imported external pointers. Track this only for user-directed
|
|
/// imports/releases.
|
|
llvm::DenseMap<uintptr_t, size_t> ImportedPtrs;
|
|
|
|
/// Common event pool.
|
|
EventPoolTy EventPool;
|
|
|
|
/// Host Memory allocator for this driver.
|
|
MemAllocatorTy HostMemAllocator;
|
|
|
|
public:
|
|
/// Named constants for checking the imported external pointer regions.
|
|
static constexpr int32_t ImportNotExist = -1;
|
|
static constexpr int32_t ImportUnknown = 0;
|
|
static constexpr int32_t ImportExist = 1;
|
|
|
|
/// Create context, initialize event pool and extension functions.
|
|
L0ContextTy(LevelZeroPluginTy &Plugin, ze_driver_handle_t zeDriver,
|
|
int32_t DriverId)
|
|
: Plugin(Plugin), zeDriver(zeDriver) {}
|
|
|
|
L0ContextTy(const L0ContextTy &) = delete;
|
|
L0ContextTy(L0ContextTy &&) = delete;
|
|
L0ContextTy &operator=(const L0ContextTy &) = delete;
|
|
L0ContextTy &operator=(const L0ContextTy &&) = delete;
|
|
|
|
/// Release resources.
|
|
~L0ContextTy() = default;
|
|
|
|
Error init();
|
|
Error deinit();
|
|
|
|
LevelZeroPluginTy &getPlugin() const { return Plugin; }
|
|
|
|
StagingBufferTy &getStagingBuffer();
|
|
|
|
/// Add imported external pointer region.
|
|
void addImported(void *Ptr, size_t Size) {
|
|
(void)ImportedPtrs.try_emplace(reinterpret_cast<uintptr_t>(Ptr), Size);
|
|
}
|
|
|
|
/// Remove imported external pointer region.
|
|
void removeImported(void *Ptr) {
|
|
(void)ImportedPtrs.erase(reinterpret_cast<uintptr_t>(Ptr));
|
|
}
|
|
/// Check if imported regions contain the specified region.
|
|
int32_t checkImported(void *Ptr, size_t Size) const {
|
|
uintptr_t LB = reinterpret_cast<uintptr_t>(Ptr);
|
|
uintptr_t UB = LB + Size;
|
|
// We do not expect a large number of user-directed imports, so use simple
|
|
// logic.
|
|
for (auto &I : ImportedPtrs) {
|
|
uintptr_t ILB = I.first;
|
|
uintptr_t IUB = ILB + I.second;
|
|
if (LB >= ILB && UB <= IUB)
|
|
return ImportExist;
|
|
if ((LB >= ILB && LB < IUB) || (UB > ILB && UB <= IUB))
|
|
return ImportUnknown;
|
|
}
|
|
return ImportNotExist;
|
|
}
|
|
|
|
ze_driver_handle_t getZeDriver() const { return zeDriver; }
|
|
|
|
/// Return context associated with the driver.
|
|
ze_context_handle_t getZeContext() const { return zeContext; }
|
|
|
|
/// Return driver API version.
|
|
ze_api_version_t getDriverAPIVersion() const { return APIVersion; }
|
|
|
|
/// Return the event pool of this driver.
|
|
EventPoolTy &getEventPool() { return EventPool; }
|
|
const EventPoolTy &getEventPool() const { return EventPool; }
|
|
|
|
bool supportsLargeMem() const {
|
|
// Large memory support is available since API version 1.1.
|
|
return getDriverAPIVersion() >= ZE_API_VERSION_1_1;
|
|
}
|
|
|
|
const MemAllocatorTy &getHostMemAllocator() const { return HostMemAllocator; }
|
|
MemAllocatorTy &getHostMemAllocator() { return HostMemAllocator; }
|
|
|
|
/// Level Zero extension function pointer for kernel argument size query.
|
|
ze_result_t(ZE_APICALL *zexKernelGetArgumentSize)(
|
|
ze_kernel_handle_t hKernel, uint32_t argIndex,
|
|
uint32_t *pArgSize) = nullptr;
|
|
};
|
|
|
|
} // namespace llvm::omp::target::plugin
|
|
|
|
#endif // OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0CONTEXT_H
|