| //===--- 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 |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // GenericDevice instatiation for SPIR-V/Xe machine. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0DEVICE_H |
| #define OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0DEVICE_H |
| |
| #include "llvm/ADT/SmallVector.h" |
| |
| #include "PerThreadTable.h" |
| |
| #include "AsyncQueue.h" |
| #include "L0Context.h" |
| #include "L0Program.h" |
| #include "PluginInterface.h" |
| #include "TLS.h" |
| |
| namespace llvm::omp::target::plugin { |
| |
| using OmpInteropTy = omp_interop_val_t *; |
| class LevelZeroPluginTy; |
| |
| // clang-format off |
| enum class PCIIdTy : int32_t { |
| None = 0x0000, |
| SKL = 0x1900, |
| KBL = 0x5900, |
| CFL = 0x3E00, |
| CFL_2 = 0x9B00, |
| ICX = 0x8A00, |
| TGL = 0xFF20, |
| TGL_2 = 0x9A00, |
| DG1 = 0x4900, |
| RKL = 0x4C00, |
| ADLS = 0x4600, |
| RTL = 0xA700, |
| MTL = 0x7D00, |
| PVC = 0x0B00, |
| DG2_ATS_M = 0x4F00, |
| DG2_ATS_M_2 = 0x5600, |
| LNL = 0x6400, |
| BMG = 0xE200, |
| }; |
| |
| /// Device type enumeration common to compiler and runtime. |
| enum class DeviceArchTy : uint64_t { |
| DeviceArch_None = 0, |
| DeviceArch_Gen = 0x0001, // Gen 9, Gen 11 or Xe |
| DeviceArch_XeLPG = 0x0002, |
| DeviceArch_XeHPC = 0x0004, |
| DeviceArch_XeHPG = 0x0008, |
| DeviceArch_Xe2LP = 0x0010, |
| DeviceArch_Xe2HP = 0x0020, |
| DeviceArch_x86_64 = 0x0100 |
| }; |
| // clang-format on |
| |
| struct L0DeviceIdTy { |
| ze_device_handle_t zeId; |
| int32_t RootId; |
| int32_t SubId; |
| int32_t CCSId; |
| |
| L0DeviceIdTy(ze_device_handle_t Device, int32_t RootId, int32_t SubId = -1, |
| int32_t CCSId = -1) |
| : zeId(Device), RootId(RootId), SubId(SubId), CCSId(CCSId) {} |
| }; |
| |
| class L0DeviceTLSTy { |
| /// Command list for each device. |
| ze_command_list_handle_t CmdList = nullptr; |
| |
| /// Main copy command list for each device. |
| ze_command_list_handle_t CopyCmdList = nullptr; |
| |
| /// Command queue for each device. |
| ze_command_queue_handle_t CmdQueue = nullptr; |
| |
| /// Main copy command queue for each device. |
| ze_command_queue_handle_t CopyCmdQueue = nullptr; |
| |
| /// Immediate command list for each device. |
| ze_command_list_handle_t ImmCmdList = nullptr; |
| |
| /// Immediate copy command list for each device. |
| ze_command_list_handle_t ImmCopyCmdList = nullptr; |
| |
| public: |
| L0DeviceTLSTy() = default; |
| ~L0DeviceTLSTy() { |
| // assert all fields are nullptr on destruction. |
| assert(!CmdList && !CopyCmdList && !CmdQueue && !CopyCmdQueue && |
| !ImmCmdList && !ImmCopyCmdList && |
| "L0DeviceTLSTy destroyed without clearing resources"); |
| } |
| |
| L0DeviceTLSTy(const L0DeviceTLSTy &) = delete; |
| L0DeviceTLSTy(L0DeviceTLSTy &&Other) { |
| CmdList = std::exchange(Other.CmdList, nullptr); |
| CopyCmdList = std::exchange(Other.CopyCmdList, nullptr); |
| CmdQueue = std::exchange(Other.CmdQueue, nullptr); |
| CopyCmdQueue = std::exchange(Other.CopyCmdQueue, nullptr); |
| ImmCmdList = std::exchange(Other.ImmCmdList, nullptr); |
| ImmCopyCmdList = std::exchange(Other.ImmCopyCmdList, nullptr); |
| } |
| |
| Error deinit() { |
| // destroy all lists and queues. |
| if (CmdList) |
| CALL_ZE_RET_ERROR(zeCommandListDestroy, CmdList); |
| if (CopyCmdList) |
| CALL_ZE_RET_ERROR(zeCommandListDestroy, CopyCmdList); |
| if (ImmCmdList) |
| CALL_ZE_RET_ERROR(zeCommandListDestroy, ImmCmdList); |
| if (ImmCopyCmdList) |
| CALL_ZE_RET_ERROR(zeCommandListDestroy, ImmCopyCmdList); |
| if (CmdQueue) |
| CALL_ZE_RET_ERROR(zeCommandQueueDestroy, CmdQueue); |
| if (CopyCmdQueue) |
| CALL_ZE_RET_ERROR(zeCommandQueueDestroy, CopyCmdQueue); |
| |
| CmdList = nullptr; |
| CopyCmdList = nullptr; |
| CmdQueue = nullptr; |
| CopyCmdQueue = nullptr; |
| ImmCmdList = nullptr; |
| ImmCopyCmdList = nullptr; |
| |
| return Plugin::success(); |
| } |
| |
| L0DeviceTLSTy &operator=(const L0DeviceTLSTy &) = delete; |
| L0DeviceTLSTy &operator=(L0DeviceTLSTy &&) = delete; |
| |
| ze_command_list_handle_t getCmdList() const { return CmdList; } |
| void setCmdList(ze_command_list_handle_t _CmdList) { CmdList = _CmdList; } |
| |
| ze_command_list_handle_t getCopyCmdList() const { return CopyCmdList; } |
| void setCopyCmdList(ze_command_list_handle_t _CopyCmdList) { |
| CopyCmdList = _CopyCmdList; |
| } |
| |
| ze_command_list_handle_t getImmCmdList() const { return ImmCmdList; } |
| void setImmCmdList(ze_command_list_handle_t ImmCmdListIn) { |
| ImmCmdList = ImmCmdListIn; |
| } |
| |
| ze_command_list_handle_t getImmCopyCmdList() const { return ImmCopyCmdList; } |
| void setImmCopyCmdList(ze_command_list_handle_t ImmCopyCmdListIn) { |
| ImmCopyCmdList = ImmCopyCmdListIn; |
| } |
| |
| ze_command_queue_handle_t getCmdQueue() const { return CmdQueue; } |
| void setCmdQueue(ze_command_queue_handle_t CmdQueueIn) { |
| CmdQueue = CmdQueueIn; |
| } |
| |
| ze_command_queue_handle_t getCopyCmdQueue() const { return CopyCmdQueue; } |
| void setCopyCmdQueue(ze_command_queue_handle_t CopyCmdQueueIn) { |
| CopyCmdQueue = CopyCmdQueueIn; |
| } |
| }; |
| |
| struct L0DeviceTLSTableTy |
| : public PerThreadContainer<std::vector<L0DeviceTLSTy>, 8> { |
| Error deinit() { |
| return PerThreadTable::deinit( |
| [](L0DeviceTLSTy &Entry) { return Entry.deinit(); }); |
| } |
| }; |
| |
| class L0DeviceTy final : public GenericDeviceTy { |
| // Level Zero Context for this Device. |
| L0ContextTy &l0Context; |
| |
| // Level Zero handle for this Device. |
| ze_device_handle_t zeDevice; |
| // Device Properties. |
| ze_device_properties_t DeviceProperties{}; |
| ze_device_compute_properties_t ComputeProperties{}; |
| ze_device_memory_properties_t MemoryProperties{}; |
| ze_device_cache_properties_t CacheProperties{}; |
| |
| /// Devices' default target allocation kind for internal allocation. |
| int32_t AllocKind = TARGET_ALLOC_DEVICE; |
| |
| DeviceArchTy DeviceArch = DeviceArchTy::DeviceArch_None; |
| |
| std::string DeviceName; |
| |
| /// Common indirect access flags for this device. |
| ze_kernel_indirect_access_flags_t IndirectAccessFlags = 0; |
| |
| /// Device UUID for toplevel devices only. |
| std::string DeviceUuid; |
| |
| /// L0 Device ID as string. |
| std::string zeId; |
| |
| /// Command queue group ordinals for each device. |
| static constexpr uint32_t MaxOrdinal = |
| std::numeric_limits<decltype(MaxOrdinal)>::max(); |
| std::pair<uint32_t, uint32_t> ComputeOrdinal{MaxOrdinal, 0}; |
| /// Command queue group ordinals for copying. |
| std::pair<uint32_t, uint32_t> CopyOrdinal{MaxOrdinal, 0}; |
| |
| /// Command queue index for each device. |
| uint32_t ComputeIndex = 0; |
| |
| bool IsAsyncEnabled = false; |
| |
| /// Lock for this device. |
| std::mutex Mutex; |
| |
| /// Contains all modules (possibly from multiple device images) to handle |
| /// dynamic link across multiple images |
| llvm::SmallVector<ze_module_handle_t> GlobalModules; |
| |
| /// L0 programs created for this device |
| std::list<L0ProgramTy> Programs; |
| |
| /// MemAllocator for this device. |
| MemAllocatorTy MemAllocator; |
| |
| DeviceArchTy computeArch() const; |
| |
| /// Get default compute group ordinal. Returns Ordinal-NumQueues pair. |
| std::pair<uint32_t, uint32_t> findComputeOrdinal(); |
| |
| /// Get copy command queue group ordinal. Returns Ordinal-NumQueues pair. |
| std::pair<uint32_t, uint32_t> findCopyOrdinal(bool LinkCopy = false); |
| |
| public: |
| L0DeviceTy(GenericPluginTy &Plugin, int32_t DeviceId, int32_t NumDevices, |
| ze_device_handle_t zeDevice, L0ContextTy &DriverInfo, |
| const std::string_view zeId, int32_t ComputeIndex) |
| : GenericDeviceTy(Plugin, DeviceId, NumDevices, SPIRVGridValues), |
| l0Context(DriverInfo), zeDevice(zeDevice), zeId(zeId), |
| ComputeIndex(ComputeIndex) { |
| DeviceProperties.stype = ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES; |
| DeviceProperties.pNext = nullptr; |
| ComputeProperties.stype = ZE_STRUCTURE_TYPE_DEVICE_COMPUTE_PROPERTIES; |
| ComputeProperties.pNext = nullptr; |
| MemoryProperties.stype = ZE_STRUCTURE_TYPE_DEVICE_MEMORY_PROPERTIES; |
| MemoryProperties.pNext = nullptr; |
| CacheProperties.stype = ZE_STRUCTURE_TYPE_DEVICE_CACHE_PROPERTIES; |
| CacheProperties.pNext = nullptr; |
| } |
| |
| static L0DeviceTy &makeL0Device(GenericDeviceTy &Device) { |
| return static_cast<L0DeviceTy &>(Device); |
| } |
| LevelZeroPluginTy &getPlugin() { |
| return reinterpret_cast<LevelZeroPluginTy &>(Plugin); |
| } |
| |
| L0DeviceTLSTy &getTLS(); |
| |
| Error setContext() override { return Plugin::success(); } |
| Error initImpl(GenericPluginTy &Plugin) override; |
| Error deinitImpl() override; |
| ze_device_handle_t getZeDevice() const { return zeDevice; } |
| |
| const L0ContextTy &getL0Context() const { return l0Context; } |
| L0ContextTy &getL0Context() { return l0Context; } |
| |
| const std::string_view getName() const { return DeviceName; } |
| const char *getNameCStr() const { return DeviceName.c_str(); } |
| |
| const std::string_view getZeId() const { return zeId; } |
| const char *getZeIdCStr() const { return zeId.c_str(); } |
| |
| std::mutex &getMutex() { return Mutex; } |
| |
| uint32_t getComputeIndex() const { return ComputeIndex; } |
| ze_kernel_indirect_access_flags_t getIndirectFlags() const { |
| return IndirectAccessFlags; |
| } |
| |
| size_t getNumGlobalModules() const { return GlobalModules.size(); } |
| void addGlobalModule(ze_module_handle_t Module) { |
| GlobalModules.push_back(Module); |
| } |
| ze_module_handle_t *getGlobalModulesArray() { return GlobalModules.data(); } |
| |
| L0ProgramTy *getProgramFromImage(MemoryBufferRef Image) { |
| for (auto &PGM : Programs) |
| if (PGM.getMemoryBuffer() == Image) |
| return &PGM; |
| return nullptr; |
| } |
| |
| Error buildAllKernels() { |
| for (auto &PGM : Programs) { |
| if (auto Err = PGM.loadModuleKernels()) |
| return Err; |
| } |
| return Plugin::success(); |
| } |
| |
| // add a new program to the device. Return a reference to the new program. |
| Expected<L0ProgramTy &> addProgram(int32_t ImageId, |
| L0ProgramBuilderTy &Builder) { |
| auto ImageOrErr = Builder.getELF(); |
| if (!ImageOrErr) |
| return ImageOrErr.takeError(); |
| Programs.emplace_back(ImageId, *this, std::move(*ImageOrErr), |
| Builder.getGlobalModule(), |
| std::move(Builder.getModules())); |
| return Programs.back(); |
| } |
| |
| const L0ProgramTy &getLastProgram() const { return Programs.back(); } |
| L0ProgramTy &getLastProgram() { return Programs.back(); } |
| // Device properties getters. |
| uint32_t getVendorId() const { return DeviceProperties.vendorId; } |
| bool isGPU() const { return DeviceProperties.type == ZE_DEVICE_TYPE_GPU; } |
| |
| uint32_t getPCIId() const { return DeviceProperties.deviceId; } |
| uint32_t getNumThreadsPerEU() const { |
| return DeviceProperties.numThreadsPerEU; |
| } |
| uint32_t getSIMDWidth() const { return DeviceProperties.physicalEUSimdWidth; } |
| uint32_t getNumEUsPerSubslice() const { |
| return DeviceProperties.numEUsPerSubslice; |
| } |
| uint32_t getNumSubslicesPerSlice() const { |
| return DeviceProperties.numSubslicesPerSlice; |
| } |
| uint32_t getNumSlices() const { return DeviceProperties.numSlices; } |
| uint32_t getNumSubslices() const { |
| return DeviceProperties.numSubslicesPerSlice * DeviceProperties.numSlices; |
| } |
| uint32_t getNumEUs() const { |
| return DeviceProperties.numEUsPerSubslice * getNumSubslices(); |
| } |
| uint32_t getTotalThreads() const { |
| return DeviceProperties.numThreadsPerEU * getNumEUs(); |
| } |
| uint32_t getNumThreadsPerSubslice() const { |
| return getNumEUsPerSubslice() * getNumThreadsPerEU(); |
| } |
| uint32_t getClockRate() const { return DeviceProperties.coreClockRate; } |
| |
| uint32_t getMaxSharedLocalMemory() const { |
| return ComputeProperties.maxSharedLocalMemory; |
| } |
| uint32_t getMaxGroupSize() const { |
| return ComputeProperties.maxTotalGroupSize; |
| } |
| uint32_t getMaxGroupCount() const { |
| return getMaxGroupCountX() * getMaxGroupCountY() * getMaxGroupCountZ(); |
| } |
| |
| uint32_t getMaxGroupSizeX() const { return ComputeProperties.maxGroupSizeX; } |
| uint32_t getMaxGroupSizeY() const { return ComputeProperties.maxGroupSizeY; } |
| uint32_t getMaxGroupSizeZ() const { return ComputeProperties.maxGroupSizeZ; } |
| uint32_t getMaxGroupCountX() const { |
| return ComputeProperties.maxGroupCountX; |
| } |
| uint32_t getMaxGroupCountY() const { |
| return ComputeProperties.maxGroupCountY; |
| } |
| uint32_t getMaxGroupCountZ() const { |
| return ComputeProperties.maxGroupCountZ; |
| } |
| uint32_t getMemoryClockRate() const { return MemoryProperties.maxClockRate; } |
| uint64_t getGlobalMemorySize() const { return MemoryProperties.totalSize; } |
| size_t getCacheSize() const { return CacheProperties.cacheSize; } |
| uint64_t getMaxMemAllocSize() const { |
| return DeviceProperties.maxMemAllocSize; |
| } |
| |
| int32_t getAllocKind() const { return AllocKind; } |
| DeviceArchTy getDeviceArch() const { return DeviceArch; } |
| bool isDeviceArch(DeviceArchTy Arch) const { return DeviceArch == Arch; } |
| |
| static bool isDiscrete(uint32_t PCIId) { |
| switch (static_cast<PCIIdTy>(PCIId & 0xFF00)) { |
| case PCIIdTy::DG1: |
| case PCIIdTy::PVC: |
| case PCIIdTy::DG2_ATS_M: |
| case PCIIdTy::DG2_ATS_M_2: |
| case PCIIdTy::BMG: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| static bool isDiscrete(ze_device_handle_t Device) { |
| ze_device_properties_t PR{}; |
| PR.stype = ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES; |
| PR.pNext = nullptr; |
| CALL_ZE_RET(false, zeDeviceGetProperties, Device, &PR); |
| return isDiscrete(PR.deviceId); |
| } |
| |
| bool isDiscreteDevice() { return isDiscrete(getPCIId()); } |
| bool isDeviceIPorNewer(uint32_t Version) const; |
| |
| const std::string_view getUuid() const { return DeviceUuid; } |
| |
| uint32_t getComputeEngine() const { return ComputeOrdinal.first; } |
| uint32_t getNumComputeQueues() const { return ComputeOrdinal.second; } |
| |
| bool hasMainCopyEngine() const { return CopyOrdinal.first != MaxOrdinal; } |
| uint32_t getMainCopyEngine() const { return CopyOrdinal.first; } |
| |
| bool deviceRequiresImmCmdList() const { |
| constexpr uint32_t BMGIP = 0x05004000; |
| return isDeviceIPorNewer(BMGIP); |
| } |
| bool asyncEnabled() const { return IsAsyncEnabled; } |
| bool useImmForCompute() const { return true; } |
| bool useImmForCopy() const { return true; } |
| bool useImmForInterop() const { return true; } |
| |
| void reportDeviceInfo() const; |
| |
| // Command queues related functions. |
| /// Create a command list with given ordinal and flags. |
| Expected<ze_command_list_handle_t> |
| createCmdList(ze_context_handle_t Context, ze_device_handle_t Device, |
| uint32_t Ordinal, ze_command_list_flags_t Flags, |
| const std::string_view DeviceIdStr); |
| |
| /// Create a command list with default flags. |
| Expected<ze_command_list_handle_t> |
| createCmdList(ze_context_handle_t Context, ze_device_handle_t Device, |
| uint32_t Ordinal, const std::string_view DeviceIdStr); |
| |
| Expected<ze_command_list_handle_t> getCmdList(); |
| |
| /// Create a command queue with given ordinal and flags. |
| Expected<ze_command_queue_handle_t> |
| createCmdQueue(ze_context_handle_t Context, ze_device_handle_t Device, |
| uint32_t Ordinal, uint32_t Index, |
| ze_command_queue_flags_t Flags, |
| const std::string_view DeviceIdStr); |
| |
| /// Create a command queue with default flags. |
| Expected<ze_command_queue_handle_t> |
| createCmdQueue(ze_context_handle_t Context, ze_device_handle_t Device, |
| uint32_t Ordinal, uint32_t Index, |
| const std::string_view DeviceIdStr, bool InOrder = false); |
| |
| /// Create a new command queue for the given OpenMP device ID. |
| Expected<ze_command_queue_handle_t> createCommandQueue(bool InOrder = false); |
| |
| /// Create an immediate command list. |
| Expected<ze_command_list_handle_t> |
| createImmCmdList(uint32_t Ordinal, uint32_t Index, bool InOrder = false); |
| |
| /// Create an immediate command list for computing. |
| Expected<ze_command_list_handle_t> createImmCmdList(bool InOrder = false) { |
| return createImmCmdList(getComputeEngine(), getComputeIndex(), InOrder); |
| } |
| |
| /// Create an immediate command list for copying. |
| Expected<ze_command_list_handle_t> createImmCopyCmdList(); |
| Expected<ze_command_queue_handle_t> getCmdQueue(); |
| Expected<ze_command_list_handle_t> getCopyCmdList(); |
| Expected<ze_command_queue_handle_t> getCopyCmdQueue(); |
| Expected<ze_command_list_handle_t> getImmCmdList(); |
| Expected<ze_command_list_handle_t> getImmCopyCmdList(); |
| |
| /// Enqueue copy command. |
| Error enqueueMemCopy(void *Dst, const void *Src, size_t Size, |
| __tgt_async_info *AsyncInfo = nullptr, |
| bool UseCopyEngine = true); |
| |
| /// Enqueue asynchronous copy command. |
| Error enqueueMemCopyAsync(void *Dst, const void *Src, size_t Size, |
| __tgt_async_info *AsyncInfo, bool CopyTo = true); |
| |
| /// Enqueue fill command. |
| Error enqueueMemFill(void *Ptr, const void *Pattern, size_t PatternSize, |
| size_t Size); |
| |
| /// Driver related functions. |
| |
| /// Reurn the driver handle for this device. |
| ze_driver_handle_t getZeDriver() const { return l0Context.getZeDriver(); } |
| |
| /// Return context for this device. |
| ze_context_handle_t getZeContext() const { return l0Context.getZeContext(); } |
| |
| /// Return driver API version for this device. |
| ze_api_version_t getDriverAPIVersion() const { |
| return l0Context.getDriverAPIVersion(); |
| } |
| |
| /// Return an event from the driver associated to this device. |
| Expected<ze_event_handle_t> getEvent() { |
| return l0Context.getEventPool().getEvent(); |
| } |
| |
| /// Release event to the pool associated to this device. |
| Error releaseEvent(ze_event_handle_t Event) { |
| return l0Context.getEventPool().releaseEvent(Event, *this); |
| } |
| |
| StagingBufferTy &getStagingBuffer() { return l0Context.getStagingBuffer(); } |
| |
| bool supportsLargeMem() const { return l0Context.supportsLargeMem(); } |
| |
| // Allocation related routines. |
| |
| /// Data alloc. |
| Expected<void *> dataAlloc( |
| size_t Size, size_t Align, int32_t Kind, intptr_t Offset, bool UserAlloc, |
| bool DevMalloc = false, |
| uint32_t MemAdvice = std::numeric_limits<decltype(MemAdvice)>::max(), |
| AllocOptionTy AllocOpt = AllocOptionTy::ALLOC_OPT_NONE); |
| |
| /// Data delete. |
| Error dataDelete(void *Ptr); |
| |
| /// Return the memory allocation type for the specified memory location. |
| uint32_t getMemAllocType(const void *Ptr) const; |
| |
| const MemAllocatorTy &getDeviceMemAllocator() const { return MemAllocator; } |
| MemAllocatorTy &getDeviceMemAllocator() { return MemAllocator; } |
| |
| MemAllocatorTy &getMemAllocator(int32_t Kind) { |
| if (Kind == TARGET_ALLOC_HOST) |
| return l0Context.getHostMemAllocator(); |
| return getDeviceMemAllocator(); |
| } |
| |
| MemAllocatorTy &getMemAllocator(const void *Ptr) { |
| if (ZE_MEMORY_TYPE_HOST == getMemAllocType(Ptr)) |
| return l0Context.getHostMemAllocator(); |
| return getDeviceMemAllocator(); |
| } |
| |
| Error makeMemoryResident(void *Mem, size_t Size); |
| |
| // Generic device interface implementation. |
| Expected<DeviceImageTy *> |
| loadBinaryImpl(std::unique_ptr<MemoryBuffer> &&TgtImage, |
| int32_t ImageId) override; |
| Error unloadBinaryImpl(DeviceImageTy *Image) override; |
| Expected<void *> allocate(size_t Size, void *HstPtr, |
| TargetAllocTy Kind) override; |
| Error free(void *TgtPtr, TargetAllocTy Kind = TARGET_ALLOC_DEFAULT) override; |
| |
| Expected<void *> dataLockImpl(void *HstPtr, int64_t Size) override { |
| return Plugin::error(error::ErrorCode::UNKNOWN, |
| "dataLockImpl not supported"); |
| } |
| Error dataUnlockImpl(void *HstPtr) override { return Plugin::success(); } |
| |
| Expected<bool> isPinnedPtrImpl(void *, void *&, void *&, |
| size_t &) const override { |
| // Don't need to do anything, this is handled by the driver. |
| return false; |
| } |
| |
| Expected<bool> isAccessiblePtrImpl(const void *Ptr, size_t Size) override; |
| Error dataFence(__tgt_async_info *Async) override; |
| Error dataFillImpl(void *TgtPtr, const void *PatternPtr, int64_t PatternSize, |
| int64_t Size, |
| AsyncInfoWrapperTy &AsyncInfoWrapper) override; |
| Error synchronizeImpl(__tgt_async_info &AsyncInfo, |
| bool ReleaseQueue) override; |
| Error queryAsyncImpl(__tgt_async_info &AsyncInfo) override; |
| Error dataSubmitImpl(void *TgtPtr, const void *HstPtr, int64_t Size, |
| AsyncInfoWrapperTy &AsyncInfoWrapper) override; |
| Error dataRetrieveImpl(void *HstPtr, const void *TgtPtr, int64_t Size, |
| AsyncInfoWrapperTy &AsyncInfoWrapper) override; |
| Error dataExchangeImpl(const void *SrcPtr, GenericDeviceTy &DstDev, |
| void *DstPtr, int64_t Size, |
| AsyncInfoWrapperTy &AsyncInfoWrapper) override; |
| Error initAsyncInfoImpl(AsyncInfoWrapperTy &AsyncInfoWrapper) override; |
| Expected<bool> |
| hasPendingWorkImpl(AsyncInfoWrapperTy &AsyncInfoWrapper) override; |
| |
| Error enqueueHostCallImpl(void (*Callback)(void *), void *UserData, |
| AsyncInfoWrapperTy &AsyncInfo) override { |
| return Plugin::error(ErrorCode::UNIMPLEMENTED, |
| "enqueueHostCallImpl not implemented yet"); |
| } |
| |
| // Event routines are used to ensure ordering between dataTransfers. Instead |
| // of adding extra events in the queues, we make sure they're ordered by |
| // using the events from the data submission APIs so we don't need to support |
| // these routines. |
| // They still need to report succes to indicate the event are handled |
| // somewhere waitEvent and syncEvent should remain unimplemented. |
| Expected<bool> isEventCompleteImpl(void *EventPtr, |
| AsyncInfoWrapperTy &) override { |
| return true; |
| } |
| |
| Error createEventImpl(void **EventPtrStorage) override { |
| return Plugin::success(); |
| } |
| Error destroyEventImpl(void *EventPtr) override { return Plugin::success(); } |
| Error recordEventImpl(void *EventPtr, |
| AsyncInfoWrapperTy &AsyncInfoWrapper) override { |
| return Plugin::success(); |
| } |
| |
| Error waitEventImpl(void *EventPtr, |
| AsyncInfoWrapperTy &AsyncInfoWrapper) override { |
| return Plugin::error(error::ErrorCode::UNKNOWN, "%s not implemented yet\n", |
| __func__); |
| } |
| |
| Error syncEventImpl(void *EventPtr) override { |
| return Plugin::error(error::ErrorCode::UNKNOWN, "%s not implemented yet\n", |
| __func__); |
| } |
| |
| Expected<InfoTreeNode> obtainInfoImpl() override; |
| uint64_t getClockFrequency() const override { return getClockRate(); } |
| uint64_t getHardwareParallelism() const override { return getTotalThreads(); } |
| Error getDeviceMemorySize(uint64_t &DSize) override { |
| DSize = getGlobalMemorySize(); |
| return Plugin::success(); |
| } |
| |
| Error getDeviceStackSize(uint64_t &V) override { |
| V = 0; |
| return Plugin::success(); |
| } |
| Expected<GenericKernelTy &> constructKernel(const char *Name) override; |
| |
| Error setDeviceStackSize(uint64_t V) override { return Plugin::success(); } |
| |
| Expected<omp_interop_val_t *> |
| createInterop(int32_t InteropType, interop_spec_t &InteropSpec) override; |
| Error releaseInterop(omp_interop_val_t *Interop) override; |
| |
| interop_spec_t selectInteropPreference(int32_t InteropType, |
| int32_t NumPrefers, |
| interop_spec_t *Prefers) override; |
| }; |
| |
| } // namespace llvm::omp::target::plugin |
| #endif // OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0DEVICE_H |