196 lines · c
1//===-- PluginManager.h - Plugin loading and communication API --*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Declarations for managing devices that are handled by RTL plugins.10//11//===----------------------------------------------------------------------===//12 13#ifndef OMPTARGET_PLUGIN_MANAGER_H14#define OMPTARGET_PLUGIN_MANAGER_H15 16#include "PluginInterface.h"17 18#include "DeviceImage.h"19#include "ExclusiveAccess.h"20#include "Shared/APITypes.h"21#include "Shared/Requirements.h"22 23#include "device.h"24 25#include "llvm/ADT/DenseSet.h"26#include "llvm/ADT/SmallVector.h"27#include "llvm/ADT/iterator.h"28#include "llvm/ADT/iterator_range.h"29#include "llvm/Support/DynamicLibrary.h"30#include "llvm/Support/Error.h"31 32#include <cstdint>33#include <list>34#include <memory>35#include <mutex>36#include <string>37 38#include "OpenMP/InteropAPI.h"39 40using GenericPluginTy = llvm::omp::target::plugin::GenericPluginTy;41 42/// Struct for the data required to handle plugins43struct PluginManager {44 /// Type of the devices container. We hand out DeviceTy& to queries which are45 /// stable addresses regardless if the container changes.46 using DeviceContainerTy = llvm::SmallVector<std::unique_ptr<DeviceTy>>;47 48 /// Exclusive accessor type for the device container.49 using ExclusiveDevicesAccessorTy = Accessor<DeviceContainerTy>;50 51 PluginManager() {}52 53 void init();54 55 void deinit();56 57 // Register a shared library with all (compatible) RTLs.58 void registerLib(__tgt_bin_desc *Desc);59 60 // Unregister a shared library from all RTLs.61 void unregisterLib(__tgt_bin_desc *Desc);62 63 void addDeviceImage(__tgt_bin_desc &TgtBinDesc,64 __tgt_device_image &TgtDeviceImage) {65 DeviceImages.emplace_back(66 std::make_unique<DeviceImageTy>(TgtBinDesc, TgtDeviceImage));67 }68 69 /// Return the device presented to the user as device \p DeviceNo if it is70 /// initialized and ready. Otherwise return an error explaining the problem.71 llvm::Expected<DeviceTy &> getDevice(uint32_t DeviceNo);72 73 /// Iterate over all initialized and ready devices registered with this74 /// plugin.75 auto devices(ExclusiveDevicesAccessorTy &DevicesAccessor) {76 return llvm::make_pointee_range(*DevicesAccessor);77 }78 79 /// Iterate over all device images registered with this plugin.80 auto deviceImages() { return llvm::make_pointee_range(DeviceImages); }81 82 /// Translation table retrieved from the binary83 HostEntriesBeginToTransTableTy HostEntriesBeginToTransTable;84 std::mutex TrlTblMtx; ///< For Translation Table85 /// Host offload entries in order of image registration86 llvm::SmallVector<llvm::offloading::EntryTy *>87 HostEntriesBeginRegistrationOrder;88 89 /// Map from ptrs on the host to an entry in the Translation Table90 HostPtrToTableMapTy HostPtrToTableMap;91 std::mutex TblMapMtx; ///< For HostPtrToTableMap92 93 /// Table of cached implicit interop objects94 InteropTblTy InteropTbl;95 96 // Work around for plugins that call dlopen on shared libraries that call97 // tgt_register_lib during their initialisation. Stash the pointers in a98 // vector until the plugins are all initialised and then register them.99 bool delayRegisterLib(__tgt_bin_desc *Desc) {100 if (RTLsLoaded)101 return false;102 DelayedBinDesc.push_back(Desc);103 return true;104 }105 106 void registerDelayedLibraries() {107 // Only called by libomptarget constructor108 RTLsLoaded = true;109 for (auto *Desc : DelayedBinDesc)110 __tgt_register_lib(Desc);111 DelayedBinDesc.clear();112 }113 114 /// Return the number of usable devices.115 int getNumDevices() { return getExclusiveDevicesAccessor()->size(); }116 117 /// Return an exclusive handle to access the devices container.118 ExclusiveDevicesAccessorTy getExclusiveDevicesAccessor() {119 return Devices.getExclusiveAccessor();120 }121 122 /// Initialize \p Plugin. Returns true on success.123 bool initializePlugin(GenericPluginTy &Plugin);124 125 /// Initialize device \p DeviceNo of \p Plugin. Returns true on success.126 bool initializeDevice(GenericPluginTy &Plugin, int32_t DeviceId);127 128 /// Eagerly initialize all plugins and their devices.129 void initializeAllDevices();130 131 /// Iterator range for all plugins (in use or not, but always valid).132 auto plugins() { return llvm::make_pointee_range(Plugins); }133 134 /// Iterator range for all plugins (in use or not, but always valid).135 auto plugins() const { return llvm::make_pointee_range(Plugins); }136 137 /// Return the user provided requirements.138 int64_t getRequirements() const { return Requirements.getRequirements(); }139 140 /// Add \p Flags to the user provided requirements.141 void addRequirements(int64_t Flags) { Requirements.addRequirements(Flags); }142 143 /// Returns the number of plugins that are active.144 int getNumActivePlugins() const {145 int count = 0;146 for (auto &R : plugins())147 if (R.is_initialized())148 ++count;149 150 return count;151 }152 153private:154 bool RTLsLoaded = false;155 llvm::SmallVector<__tgt_bin_desc *> DelayedBinDesc;156 157 // List of all plugins, in use or not.158 llvm::SmallVector<std::unique_ptr<GenericPluginTy>> Plugins;159 160 // Mapping of plugins to the OpenMP device identifier.161 llvm::DenseMap<std::pair<const GenericPluginTy *, int32_t>, int32_t>162 DeviceIds;163 164 // Set of all device images currently in use.165 llvm::DenseSet<const __tgt_device_image *> UsedImages;166 167 /// Executable images and information extracted from the input images passed168 /// to the runtime.169 llvm::SmallVector<std::unique_ptr<DeviceImageTy>> DeviceImages;170 171 /// The user provided requirements.172 RequirementCollection Requirements;173 174 std::mutex RTLsMtx; ///< For RTLs175 176 /// Devices associated with plugins, accesses to the container are exclusive.177 ProtectedObj<DeviceContainerTy> Devices;178 179 /// References to upgraded legacy offloading entries.180 std::list<llvm::SmallVector<llvm::offloading::EntryTy, 0>> LegacyEntries;181 std::list<llvm::SmallVector<__tgt_device_image, 0>> LegacyImages;182 llvm::DenseMap<__tgt_bin_desc *, __tgt_bin_desc> UpgradedDescriptors;183 __tgt_bin_desc *upgradeLegacyEntries(__tgt_bin_desc *Desc);184};185 186/// Initialize the plugin manager and OpenMP runtime.187void initRuntime();188 189/// Deinitialize the plugin and delete it.190void deinitRuntime();191 192extern PluginManager *PM;193extern std::atomic<bool> RTLAlive; // Indicates if the RTL has been initialized194extern std::atomic<int> RTLOngoingSyncs; // Counts ongoing external syncs195#endif // OMPTARGET_PLUGIN_MANAGER_H196