//===--- 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 "L0CmdListManager.h"
#include "L0Context.h"
#include "L0Program.h"
#include "L0Queue.h"
#include "PluginInterface.h"
#include <cstdint>
#include <limits>

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) {}
};

/// Properties of a compute command queue group.
struct ComputeQueueGroupInfoTy {
  /// Command queue group ordinal.
  uint32_t Ordinal = std::numeric_limits<uint32_t>::max();
  /// Number of queues in the group.
  uint32_t NumQueues = 0;
  /// Maximum pattern size accepted by zeCommandListMemoryFill for this device.
  /// 0 means value is unavailable.
  size_t MaxMemFillPatternSize = 0;
};

/// Results of scanning a device's command queue groups.
struct DeviceQueueConfigInfoTy {
  /// The compute command queue group selected as the device default.
  ComputeQueueGroupInfoTy DefaultCmdQueueGroup;
  /// Whether any command queue group on this device supports cooperative
  /// kernels.
  bool SupportsCooperativeKernels = false;
};

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{};
  ze_device_module_properties_t ModuleProperties{};

  /// 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 info for this device. Value is unspecified unless the
  /// device reached a valid initialized state.
  DeviceQueueConfigInfoTy QueueConfig;

  /// Command queue index for each device.
  uint32_t ComputeIndex = 0;

  /// 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;

  /// Scan the device's command queue groups, selecting the default compute
  /// group and detecting cooperative kernel support. Returns an Error if the
  /// device exposes no compute queue group.
  Expected<DeviceQueueConfigInfoTy> scanQueueGroups();

  /// Helper function to call global constructors or destructors.
  Error callGlobalCtorDtorCommon(GenericPluginTy &Plugin, DeviceImageTy &Image,
                                 bool IsCtor);

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;
    ModuleProperties.stype = ZE_STRUCTURE_TYPE_DEVICE_MODULE_PROPERTIES;
    ModuleProperties.pNext = nullptr;
  }

  static L0DeviceTy &makeL0Device(GenericDeviceTy &Device) {
    return static_cast<L0DeviceTy &>(Device);
  }
  LevelZeroPluginTy &getPlugin() {
    return reinterpret_cast<LevelZeroPluginTy &>(Plugin);
  }

  Error setContext() override { return Plugin::success(); }
  Error initImpl(GenericPluginTy &Plugin) override;
  Error deinitImpl() override;
  ze_device_handle_t getZeDevice() const { return zeDevice; }

  bool supportsCooperativeKernels() const {
    return QueueConfig.SupportsCooperativeKernels;
  }

  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 char *getArchCStr() const;

  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;
  }

  bool supportsFP64() const {
    return ModuleProperties.flags & ZE_DEVICE_MODULE_FLAG_FP64;
  }

  bool supportsFP16() const {
    return ModuleProperties.flags & ZE_DEVICE_MODULE_FLAG_FP16;
  }

  ze_device_fp_flags_t getFP64Flags() const {
    return ModuleProperties.fp64flags;
  }

  ze_device_fp_flags_t getFP16Flags() const {
    return ModuleProperties.fp16flags;
  }

  ze_device_fp_flags_t getFP32Flags() const {
    return ModuleProperties.fp32flags;
  }

  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 QueueConfig.DefaultCmdQueueGroup.Ordinal;
  }
  uint32_t getNumComputeQueues() const {
    return QueueConfig.DefaultCmdQueueGroup.NumQueues;
  }

  size_t getMaxMemFillPatternSize() {
    return QueueConfig.DefaultCmdQueueGroup.MaxMemFillPatternSize;
  }

  void reportDeviceInfo() const;

  /// Create an immediate command list.
  Expected<ze_command_list_handle_t>
  createImmCmdList(uint32_t Ordinal, uint32_t Index,
                   ze_context_handle_t UserZeCtx, bool InOrder = false);

  /// Create an immediate command list for computing.
  Expected<ze_command_list_handle_t>
  createImmCmdList(ze_context_handle_t UserZeCtx, bool InOrder = false) {
    return createImmCmdList(getComputeEngine(), getComputeIndex(), UserZeCtx,
                            InOrder);
  }

  /// Release an immediate command list.
  Error releaseImmCmdList(ze_command_list_handle_t CmdList) {
    CALL_ZE_RET_ERROR(zeCommandListDestroy, CmdList);
    return Plugin::success();
  }

  Expected<L0CmdListManagerTy *>
  getCmdListManager(ze_context_handle_t UserZeCtx, bool InOrder = false) {
    auto CmdListOrErr = createImmCmdList(UserZeCtx, InOrder);
    if (!CmdListOrErr)
      return CmdListOrErr.takeError();
    return new L0CmdListManagerTy(*CmdListOrErr, L0Context);
  }

  Error releaseCmdListManager(L0CmdListManagerTy *CmndListMngr) {
    if (CmndListMngr) {
      auto CmdList = CmndListMngr->getCmdList();
      CALL_ZE_RET_ERROR(zeCommandListDestroy, CmdList);
      delete CmndListMngr;
    }
    return Plugin::success();
  }

  /// Enqueue non-blocking memory copy.
  Error enqueueMemCopy(void *Dst, const void *Src, size_t Size,
                       __tgt_async_info *AsyncInfo) {
    auto QueueOrErr = getOrCreateQueue(AsyncInfo);
    if (!QueueOrErr)
      return QueueOrErr.takeError();
    L0QueueTy *Queue = *QueueOrErr;
    return Queue->memoryCopy(Dst, Src, Size);
  }

  Error enqueueMemCopyAndSync(void *Dst, const void *Src, size_t Size) {
    __tgt_async_info AsyncInfo;
    if (auto Err = enqueueMemCopy(Dst, Src, Size, &AsyncInfo)) {
      releaseQueue(static_cast<L0QueueTy *>(AsyncInfo.Queue));
      return Err;
    }
    return synchronize(&AsyncInfo);
  }

  /// Enqueue fill command.
  Error enqueueMemFill(void *Ptr, const void *Pattern, size_t PatternSize,
                       size_t Size, __tgt_async_info *AsyncInfo);
  Error enqueueMemFillAndSync(void *Ptr, const void *Pattern,
                              size_t PatternSize, size_t Size) {
    __tgt_async_info AsyncInfo;
    if (auto Err =
            enqueueMemFill(Ptr, Pattern, PatternSize, Size, &AsyncInfo)) {
      releaseQueue(static_cast<L0QueueTy *>(AsyncInfo.Queue));
      return Err;
    }
    return synchronize(&AsyncInfo);
  }

  /// 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();
  }

  /// Get a low-level L0 event from the driver associated to this device.
  Expected<ze_event_handle_t> getEvent() {
    return L0Context.getEventPool().getEvent();
  }
  /// Get a high-level L0EventTy object from the driver associated to this
  /// device.
  Expected<L0EventTy *> getEventObject() {
    return L0Context.getEventPool().getEventObject();
  }

  /// Release a L0 event to the pool associated to this device.
  Error releaseEvent(ze_event_handle_t Event) {
    return L0Context.getEventPool().releaseEvent(Event);
  }
  /// Release an L0EventTy object to the pool associated to this device.
  Error releaseEventObject(L0EventTy *EventObj) {
    return L0Context.getEventPool().releaseEventObject(EventObj);
  }

  StagingBufferTy &getStagingBuffer() { return L0Context.getStagingBuffer(); }

  bool supportsLargeMem() const { return L0Context.supportsLargeMem(); }

  /// Returns the Queue from an async info object, or creates a new one if
  /// the async info does not have a queue yet. When \p UserCtx is null the
  /// driver's default plugin-side context is used.
  Expected<L0QueueTy *>
  getOrCreateQueue(__tgt_async_info *AsyncInfo,
                   LevelZeroPluginContextTy *UserCtx = nullptr);
  void releaseQueue(L0QueueTy *Queue);

  // 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,
                            size_t Alignment) override;
  Error free(void *TgtPtr, TargetAllocTy Kind = TARGET_ALLOC_DEFAULT) override;

  /// This plugin does nothing to lock buffers. Do not return an error, just
  /// return the same pointer as the device pointer.
  Expected<void *> dataLockImpl(void *HstPtr, int64_t Size) override {
    return HstPtr;
  }
  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 dataPrefetchImpl(size_t Count, const void **Mems, const size_t *Sizes,
                         bool ToHost,
                         AsyncInfoWrapperTy &AsyncInfoWrapper) override;
  Error synchronizeImpl(__tgt_async_info &AsyncInfo,
                        bool ReleaseQueue) override;
  Error queryAsyncImpl(__tgt_async_info &AsyncInfo, bool ReleaseQueue,
                       bool *IsQueueWorkCompleted) 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 dataMemcpyImpl(void *DstPtr, const void *SrcPtr, int64_t Size,
                       AsyncInfoWrapperTy &AsyncInfoWrapper) override;
  Error dataExchangeImpl(const void *SrcPtr, GenericDeviceTy &DstDev,
                         void *DstPtr, int64_t Size,
                         AsyncInfoWrapperTy &AsyncInfoWrapper) override;
  Expected<bool>
  hasPendingWorkImpl(AsyncInfoWrapperTy &AsyncInfoWrapper) override;

  Error enqueueHostCallImpl(void (*Callback)(void *), void *UserData,
                            AsyncInfoWrapperTy &AsyncInfo) override;

  Expected<bool> isEventCompleteImpl(void *EventPtr,
                                     AsyncInfoWrapperTy &) override;
  Error createEventImpl(void **EventPtrStorage, bool EnableProfiling) override;
  Error destroyEventImpl(void *EventPtr, bool EnableProfiling) override;
  Error recordEventImpl(void *EventPtr, AsyncInfoWrapperTy &AsyncInfoWrapper,
                        bool EnableProfiling) override;
  Error waitEventImpl(void *EventPtr,
                      AsyncInfoWrapperTy &AsyncInfoWrapper) override;
  Error syncEventImpl(void *EventPtr) override;
  Expected<float> getEventElapsedTimeImpl(void *StartEventPtr,
                                          void *EndEventPtr) override;

  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(StringRef Name) override;

  Error callGlobalConstructors(GenericPluginTy &Plugin,
                               DeviceImageTy &Image) override;

  Error callGlobalDestructors(GenericPluginTy &Plugin,
                              DeviceImageTy &Image) 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
