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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Declarations for managing devices that are handled by RTL plugins. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef OMPTARGET_PLUGIN_MANAGER_H 14 #define OMPTARGET_PLUGIN_MANAGER_H 15 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 using GenericPluginTy = llvm::omp::target::plugin::GenericPluginTy; 39 40 /// Struct for the data required to handle plugins 41 struct PluginManager { 42 /// Type of the devices container. We hand out DeviceTy& to queries which are 43 /// stable addresses regardless if the container changes. 44 using DeviceContainerTy = llvm::SmallVector<std::unique_ptr<DeviceTy>>; 45 46 /// Exclusive accessor type for the device container. 47 using ExclusiveDevicesAccessorTy = Accessor<DeviceContainerTy>; 48 49 PluginManager() {} 50 51 void init(); 52 53 void deinit(); 54 55 // Register a shared library with all (compatible) RTLs. 56 void registerLib(__tgt_bin_desc *Desc); 57 58 // Unregister a shared library from all RTLs. 59 void unregisterLib(__tgt_bin_desc *Desc); 60 61 void addDeviceImage(__tgt_bin_desc &TgtBinDesc, 62 __tgt_device_image &TgtDeviceImage) { 63 DeviceImages.emplace_back( 64 std::make_unique<DeviceImageTy>(TgtBinDesc, TgtDeviceImage)); 65 } 66 67 /// Return the device presented to the user as device \p DeviceNo if it is 68 /// initialized and ready. Otherwise return an error explaining the problem. 69 llvm::Expected<DeviceTy &> getDevice(uint32_t DeviceNo); 70 71 /// Iterate over all initialized and ready devices registered with this 72 /// plugin. 73 auto devices(ExclusiveDevicesAccessorTy &DevicesAccessor) { 74 return llvm::make_pointee_range(*DevicesAccessor); 75 } 76 77 /// Iterate over all device images registered with this plugin. 78 auto deviceImages() { return llvm::make_pointee_range(DeviceImages); } 79 80 /// Translation table retreived from the binary 81 HostEntriesBeginToTransTableTy HostEntriesBeginToTransTable; 82 std::mutex TrlTblMtx; ///< For Translation Table 83 /// Host offload entries in order of image registration 84 llvm::SmallVector<llvm::offloading::EntryTy *> 85 HostEntriesBeginRegistrationOrder; 86 87 /// Map from ptrs on the host to an entry in the Translation Table 88 HostPtrToTableMapTy HostPtrToTableMap; 89 std::mutex TblMapMtx; ///< For HostPtrToTableMap 90 91 // Work around for plugins that call dlopen on shared libraries that call 92 // tgt_register_lib during their initialisation. Stash the pointers in a 93 // vector until the plugins are all initialised and then register them. 94 bool delayRegisterLib(__tgt_bin_desc *Desc) { 95 if (RTLsLoaded) 96 return false; 97 DelayedBinDesc.push_back(Desc); 98 return true; 99 } 100 101 void registerDelayedLibraries() { 102 // Only called by libomptarget constructor 103 RTLsLoaded = true; 104 for (auto *Desc : DelayedBinDesc) 105 __tgt_register_lib(Desc); 106 DelayedBinDesc.clear(); 107 } 108 109 /// Return the number of usable devices. 110 int getNumDevices() { return getExclusiveDevicesAccessor()->size(); } 111 112 /// Return an exclusive handle to access the devices container. 113 ExclusiveDevicesAccessorTy getExclusiveDevicesAccessor() { 114 return Devices.getExclusiveAccessor(); 115 } 116 117 /// Initialize \p Plugin. Returns true on success. 118 bool initializePlugin(GenericPluginTy &Plugin); 119 120 /// Initialize device \p DeviceNo of \p Plugin. Returns true on success. 121 bool initializeDevice(GenericPluginTy &Plugin, int32_t DeviceId); 122 123 /// Eagerly initialize all plugins and their devices. 124 void initializeAllDevices(); 125 126 /// Iterator range for all plugins (in use or not, but always valid). 127 auto plugins() { return llvm::make_pointee_range(Plugins); } 128 129 /// Iterator range for all plugins (in use or not, but always valid). 130 auto plugins() const { return llvm::make_pointee_range(Plugins); } 131 132 /// Return the user provided requirements. 133 int64_t getRequirements() const { return Requirements.getRequirements(); } 134 135 /// Add \p Flags to the user provided requirements. 136 void addRequirements(int64_t Flags) { Requirements.addRequirements(Flags); } 137 138 /// Returns the number of plugins that are active. 139 int getNumActivePlugins() const { 140 int count = 0; 141 for (auto &R : plugins()) 142 if (R.is_initialized()) 143 ++count; 144 145 return count; 146 } 147 148 private: 149 bool RTLsLoaded = false; 150 llvm::SmallVector<__tgt_bin_desc *> DelayedBinDesc; 151 152 // List of all plugins, in use or not. 153 llvm::SmallVector<std::unique_ptr<GenericPluginTy>> Plugins; 154 155 // Mapping of plugins to the OpenMP device identifier. 156 llvm::DenseMap<std::pair<const GenericPluginTy *, int32_t>, int32_t> 157 DeviceIds; 158 159 // Set of all device images currently in use. 160 llvm::DenseSet<const __tgt_device_image *> UsedImages; 161 162 /// Executable images and information extracted from the input images passed 163 /// to the runtime. 164 llvm::SmallVector<std::unique_ptr<DeviceImageTy>> DeviceImages; 165 166 /// The user provided requirements. 167 RequirementCollection Requirements; 168 169 std::mutex RTLsMtx; ///< For RTLs 170 171 /// Devices associated with plugins, accesses to the container are exclusive. 172 ProtectedObj<DeviceContainerTy> Devices; 173 174 /// References to upgraded legacy offloading entires. 175 std::list<llvm::SmallVector<llvm::offloading::EntryTy, 0>> LegacyEntries; 176 std::list<llvm::SmallVector<__tgt_device_image, 0>> LegacyImages; 177 llvm::DenseMap<__tgt_bin_desc *, __tgt_bin_desc> UpgradedDescriptors; 178 __tgt_bin_desc *upgradeLegacyEntries(__tgt_bin_desc *Desc); 179 }; 180 181 /// Initialize the plugin manager and OpenMP runtime. 182 void initRuntime(); 183 184 /// Deinitialize the plugin and delete it. 185 void deinitRuntime(); 186 187 extern PluginManager *PM; 188 189 #endif // OMPTARGET_PLUGIN_MANAGER_H 190