| //===--- 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 Program abstraction. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #ifndef OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0PROGRAM_H | |
| #define OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0PROGRAM_H | |
| #include "L0Kernel.h" | |
| namespace llvm::omp::target::plugin { | |
| class L0DeviceTy; | |
| class L0ProgramBuilderTy { | |
| L0DeviceTy &Device; | |
| std::unique_ptr<MemoryBuffer> Image; | |
| /// Handle multiple modules within a single target image. | |
| llvm::SmallVector<ze_module_handle_t> Modules; | |
| /// Module that contains global data including device RTL. | |
| ze_module_handle_t GlobalModule = nullptr; | |
| /// Requires module link. | |
| bool RequiresModuleLink = false; | |
| /// Build a single module with the given image, build option, and format. | |
| Error addModule(const size_t Size, const uint8_t *Image, | |
| const std::string_view BuildOption, | |
| ze_module_format_t Format); | |
| Error linkModules(); | |
| public: | |
| L0ProgramBuilderTy(L0DeviceTy &Device, std::unique_ptr<MemoryBuffer> &&Image) | |
| : Device(Device), Image(std::move(Image)) {} | |
| ~L0ProgramBuilderTy() = default; | |
| L0DeviceTy &getL0Device() const { return Device; } | |
| ze_module_handle_t getGlobalModule() const { return GlobalModule; } | |
| llvm::SmallVector<ze_module_handle_t> &getModules() { return Modules; } | |
| MemoryBufferRef getMemoryBuffer() const { return MemoryBufferRef(*Image); } | |
| Error buildModules(const std::string_view BuildOptions); | |
| /// Retrieve the ELF binary for the program. | |
| Expected<std::unique_ptr<MemoryBuffer>> getELF(); | |
| }; | |
| /// Level Zero program that can contain multiple modules. | |
| class L0ProgramTy : public DeviceImageTy { | |
| /// Handle multiple modules within a single target image. | |
| llvm::SmallVector<ze_module_handle_t> Modules; | |
| /// Map of kernel names to Modules | |
| std::unordered_map<std::string, ze_module_handle_t> KernelsToModuleMap; | |
| /// List of kernels built for this image. | |
| /// We need to delete them ourselves as the main library is not doing | |
| /// that right now. | |
| std::list<L0KernelTy *> Kernels; | |
| /// Module that contains global data including device RTL. | |
| ze_module_handle_t GlobalModule = nullptr; | |
| L0DeviceTy &getL0Device() const; | |
| public: | |
| L0ProgramTy() = delete; | |
| L0ProgramTy(int32_t ImageId, GenericDeviceTy &Device, | |
| std::unique_ptr<MemoryBuffer> Image, | |
| ze_module_handle_t GlobalModule, | |
| llvm::SmallVector<ze_module_handle_t> &&Modules) | |
| : DeviceImageTy(ImageId, Device, std::move(Image)), | |
| Modules(std::move(Modules)), GlobalModule(GlobalModule) {} | |
| ~L0ProgramTy() = default; | |
| L0ProgramTy(const L0ProgramTy &other) = delete; | |
| L0ProgramTy(L0ProgramTy &&) = delete; | |
| L0ProgramTy &operator=(const L0ProgramTy &) = delete; | |
| L0ProgramTy &operator=(const L0ProgramTy &&) = delete; | |
| Error deinit(); | |
| static L0ProgramTy &makeL0Program(DeviceImageTy &Device) { | |
| return static_cast<L0ProgramTy &>(Device); | |
| } | |
| /// Loads the kernels names from all modules. | |
| Error loadModuleKernels(); | |
| /// Read data from the location in the device image which corresponds to the | |
| /// specified global variable name. | |
| Error readGlobalVariable(const char *Name, size_t Size, void *HostPtr); | |
| /// Write data to the location in the device image which corresponds to the | |
| /// specified global variable name. | |
| Error writeGlobalVariable(const char *Name, size_t Size, const void *HostPtr); | |
| /// Looks up a device global symbol with the given \p Name in the device and | |
| /// returns its address and size in \p Addr and \p SizePtr respectively. | |
| Error getSymbolMetadata(const char *Name, void **AddrPtr, | |
| size_t *SizePtr) const; | |
| /// Returns the handle of a module that contains a given Kernel name. | |
| ze_module_handle_t findModuleFromKernelName(const char *KernelName) const { | |
| auto K = KernelsToModuleMap.find(std::string(KernelName)); | |
| if (K == KernelsToModuleMap.end()) | |
| return nullptr; | |
| return K->second; | |
| } | |
| void addKernel(L0KernelTy *Kernel) { Kernels.push_back(Kernel); } | |
| }; | |
| struct L0GlobalHandlerTy final : public GenericGlobalHandlerTy { | |
| Error getGlobalMetadataFromDevice(GenericDeviceTy &Device, | |
| DeviceImageTy &Image, | |
| GlobalTy &DeviceGlobal) override; | |
| }; | |
| bool isValidOneOmpImage(StringRef Image, uint64_t &MajorVer, | |
| uint64_t &MinorVer); | |
| } // namespace llvm::omp::target::plugin | |
| #endif // OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0PROGRAM_H |