xref: /llvm-project/offload/include/PluginManager.h (revision 13dcc95dcd4999ff99f2de89d881f1aed5b21709)
1330d8983SJohannes Doerfert //===-- PluginManager.h - Plugin loading and communication API --*- C++ -*-===//
2330d8983SJohannes Doerfert //
3330d8983SJohannes Doerfert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4330d8983SJohannes Doerfert // See https://llvm.org/LICENSE.txt for license information.
5330d8983SJohannes Doerfert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6330d8983SJohannes Doerfert //
7330d8983SJohannes Doerfert //===----------------------------------------------------------------------===//
8330d8983SJohannes Doerfert //
9330d8983SJohannes Doerfert // Declarations for managing devices that are handled by RTL plugins.
10330d8983SJohannes Doerfert //
11330d8983SJohannes Doerfert //===----------------------------------------------------------------------===//
12330d8983SJohannes Doerfert 
13330d8983SJohannes Doerfert #ifndef OMPTARGET_PLUGIN_MANAGER_H
14330d8983SJohannes Doerfert #define OMPTARGET_PLUGIN_MANAGER_H
15330d8983SJohannes Doerfert 
16fa9e90f5SJoseph Huber #include "PluginInterface.h"
17fa9e90f5SJoseph Huber 
18330d8983SJohannes Doerfert #include "DeviceImage.h"
19330d8983SJohannes Doerfert #include "ExclusiveAccess.h"
20330d8983SJohannes Doerfert #include "Shared/APITypes.h"
21330d8983SJohannes Doerfert #include "Shared/Requirements.h"
22330d8983SJohannes Doerfert 
23330d8983SJohannes Doerfert #include "device.h"
24330d8983SJohannes Doerfert 
25330d8983SJohannes Doerfert #include "llvm/ADT/DenseSet.h"
26330d8983SJohannes Doerfert #include "llvm/ADT/SmallVector.h"
27330d8983SJohannes Doerfert #include "llvm/ADT/iterator.h"
28330d8983SJohannes Doerfert #include "llvm/ADT/iterator_range.h"
29330d8983SJohannes Doerfert #include "llvm/Support/DynamicLibrary.h"
30330d8983SJohannes Doerfert #include "llvm/Support/Error.h"
31330d8983SJohannes Doerfert 
32330d8983SJohannes Doerfert #include <cstdint>
33330d8983SJohannes Doerfert #include <list>
34330d8983SJohannes Doerfert #include <memory>
35330d8983SJohannes Doerfert #include <mutex>
36330d8983SJohannes Doerfert #include <string>
37330d8983SJohannes Doerfert 
38fa9e90f5SJoseph Huber using GenericPluginTy = llvm::omp::target::plugin::GenericPluginTy;
39330d8983SJohannes Doerfert 
40330d8983SJohannes Doerfert /// Struct for the data required to handle plugins
41330d8983SJohannes Doerfert struct PluginManager {
42330d8983SJohannes Doerfert   /// Type of the devices container. We hand out DeviceTy& to queries which are
43330d8983SJohannes Doerfert   /// stable addresses regardless if the container changes.
44330d8983SJohannes Doerfert   using DeviceContainerTy = llvm::SmallVector<std::unique_ptr<DeviceTy>>;
45330d8983SJohannes Doerfert 
46330d8983SJohannes Doerfert   /// Exclusive accessor type for the device container.
47330d8983SJohannes Doerfert   using ExclusiveDevicesAccessorTy = Accessor<DeviceContainerTy>;
48330d8983SJohannes Doerfert 
49330d8983SJohannes Doerfert   PluginManager() {}
50330d8983SJohannes Doerfert 
51330d8983SJohannes Doerfert   void init();
52330d8983SJohannes Doerfert 
53fa9e90f5SJoseph Huber   void deinit();
54fa9e90f5SJoseph Huber 
55330d8983SJohannes Doerfert   // Register a shared library with all (compatible) RTLs.
56330d8983SJohannes Doerfert   void registerLib(__tgt_bin_desc *Desc);
57330d8983SJohannes Doerfert 
58330d8983SJohannes Doerfert   // Unregister a shared library from all RTLs.
59330d8983SJohannes Doerfert   void unregisterLib(__tgt_bin_desc *Desc);
60330d8983SJohannes Doerfert 
61330d8983SJohannes Doerfert   void addDeviceImage(__tgt_bin_desc &TgtBinDesc,
62330d8983SJohannes Doerfert                       __tgt_device_image &TgtDeviceImage) {
63330d8983SJohannes Doerfert     DeviceImages.emplace_back(
64330d8983SJohannes Doerfert         std::make_unique<DeviceImageTy>(TgtBinDesc, TgtDeviceImage));
65330d8983SJohannes Doerfert   }
66330d8983SJohannes Doerfert 
67330d8983SJohannes Doerfert   /// Return the device presented to the user as device \p DeviceNo if it is
68330d8983SJohannes Doerfert   /// initialized and ready. Otherwise return an error explaining the problem.
69330d8983SJohannes Doerfert   llvm::Expected<DeviceTy &> getDevice(uint32_t DeviceNo);
70330d8983SJohannes Doerfert 
71330d8983SJohannes Doerfert   /// Iterate over all initialized and ready devices registered with this
72330d8983SJohannes Doerfert   /// plugin.
73330d8983SJohannes Doerfert   auto devices(ExclusiveDevicesAccessorTy &DevicesAccessor) {
74330d8983SJohannes Doerfert     return llvm::make_pointee_range(*DevicesAccessor);
75330d8983SJohannes Doerfert   }
76330d8983SJohannes Doerfert 
77330d8983SJohannes Doerfert   /// Iterate over all device images registered with this plugin.
78330d8983SJohannes Doerfert   auto deviceImages() { return llvm::make_pointee_range(DeviceImages); }
79330d8983SJohannes Doerfert 
80330d8983SJohannes Doerfert   /// Translation table retreived from the binary
81330d8983SJohannes Doerfert   HostEntriesBeginToTransTableTy HostEntriesBeginToTransTable;
82330d8983SJohannes Doerfert   std::mutex TrlTblMtx; ///< For Translation Table
83330d8983SJohannes Doerfert   /// Host offload entries in order of image registration
846518b121SJoseph Huber   llvm::SmallVector<llvm::offloading::EntryTy *>
856518b121SJoseph Huber       HostEntriesBeginRegistrationOrder;
86330d8983SJohannes Doerfert 
87330d8983SJohannes Doerfert   /// Map from ptrs on the host to an entry in the Translation Table
88330d8983SJohannes Doerfert   HostPtrToTableMapTy HostPtrToTableMap;
89330d8983SJohannes Doerfert   std::mutex TblMapMtx; ///< For HostPtrToTableMap
90330d8983SJohannes Doerfert 
91330d8983SJohannes Doerfert   // Work around for plugins that call dlopen on shared libraries that call
92330d8983SJohannes Doerfert   // tgt_register_lib during their initialisation. Stash the pointers in a
93330d8983SJohannes Doerfert   // vector until the plugins are all initialised and then register them.
94330d8983SJohannes Doerfert   bool delayRegisterLib(__tgt_bin_desc *Desc) {
95330d8983SJohannes Doerfert     if (RTLsLoaded)
96330d8983SJohannes Doerfert       return false;
97330d8983SJohannes Doerfert     DelayedBinDesc.push_back(Desc);
98330d8983SJohannes Doerfert     return true;
99330d8983SJohannes Doerfert   }
100330d8983SJohannes Doerfert 
101330d8983SJohannes Doerfert   void registerDelayedLibraries() {
102330d8983SJohannes Doerfert     // Only called by libomptarget constructor
103330d8983SJohannes Doerfert     RTLsLoaded = true;
104330d8983SJohannes Doerfert     for (auto *Desc : DelayedBinDesc)
105330d8983SJohannes Doerfert       __tgt_register_lib(Desc);
106330d8983SJohannes Doerfert     DelayedBinDesc.clear();
107330d8983SJohannes Doerfert   }
108330d8983SJohannes Doerfert 
109330d8983SJohannes Doerfert   /// Return the number of usable devices.
110330d8983SJohannes Doerfert   int getNumDevices() { return getExclusiveDevicesAccessor()->size(); }
111330d8983SJohannes Doerfert 
112330d8983SJohannes Doerfert   /// Return an exclusive handle to access the devices container.
113330d8983SJohannes Doerfert   ExclusiveDevicesAccessorTy getExclusiveDevicesAccessor() {
114330d8983SJohannes Doerfert     return Devices.getExclusiveAccessor();
115330d8983SJohannes Doerfert   }
116330d8983SJohannes Doerfert 
1177102592aSJohannes Doerfert   /// Initialize \p Plugin. Returns true on success.
1187102592aSJohannes Doerfert   bool initializePlugin(GenericPluginTy &Plugin);
1197102592aSJohannes Doerfert 
1207102592aSJohannes Doerfert   /// Initialize device \p DeviceNo of \p Plugin. Returns true on success.
1217102592aSJohannes Doerfert   bool initializeDevice(GenericPluginTy &Plugin, int32_t DeviceId);
1227102592aSJohannes Doerfert 
1237102592aSJohannes Doerfert   /// Eagerly initialize all plugins and their devices.
1247102592aSJohannes Doerfert   void initializeAllDevices();
125330d8983SJohannes Doerfert 
126fa9e90f5SJoseph Huber   /// Iterator range for all plugins (in use or not, but always valid).
127fa9e90f5SJoseph Huber   auto plugins() { return llvm::make_pointee_range(Plugins); }
128330d8983SJohannes Doerfert 
129435aa766SJoseph Huber   /// Iterator range for all plugins (in use or not, but always valid).
130435aa766SJoseph Huber   auto plugins() const { return llvm::make_pointee_range(Plugins); }
131435aa766SJoseph Huber 
132330d8983SJohannes Doerfert   /// Return the user provided requirements.
133330d8983SJohannes Doerfert   int64_t getRequirements() const { return Requirements.getRequirements(); }
134330d8983SJohannes Doerfert 
135330d8983SJohannes Doerfert   /// Add \p Flags to the user provided requirements.
136330d8983SJohannes Doerfert   void addRequirements(int64_t Flags) { Requirements.addRequirements(Flags); }
137330d8983SJohannes Doerfert 
138435aa766SJoseph Huber   /// Returns the number of plugins that are active.
139435aa766SJoseph Huber   int getNumActivePlugins() const {
140435aa766SJoseph Huber     int count = 0;
141435aa766SJoseph Huber     for (auto &R : plugins())
142435aa766SJoseph Huber       if (R.is_initialized())
143435aa766SJoseph Huber         ++count;
144435aa766SJoseph Huber 
145435aa766SJoseph Huber     return count;
146435aa766SJoseph Huber   }
147435aa766SJoseph Huber 
148330d8983SJohannes Doerfert private:
149330d8983SJohannes Doerfert   bool RTLsLoaded = false;
150330d8983SJohannes Doerfert   llvm::SmallVector<__tgt_bin_desc *> DelayedBinDesc;
151330d8983SJohannes Doerfert 
152fa9e90f5SJoseph Huber   // List of all plugins, in use or not.
153fa9e90f5SJoseph Huber   llvm::SmallVector<std::unique_ptr<GenericPluginTy>> Plugins;
154330d8983SJohannes Doerfert 
155435aa766SJoseph Huber   // Mapping of plugins to the OpenMP device identifier.
156435aa766SJoseph Huber   llvm::DenseMap<std::pair<const GenericPluginTy *, int32_t>, int32_t>
157435aa766SJoseph Huber       DeviceIds;
158330d8983SJohannes Doerfert 
159330d8983SJohannes Doerfert   // Set of all device images currently in use.
160330d8983SJohannes Doerfert   llvm::DenseSet<const __tgt_device_image *> UsedImages;
161330d8983SJohannes Doerfert 
162330d8983SJohannes Doerfert   /// Executable images and information extracted from the input images passed
163330d8983SJohannes Doerfert   /// to the runtime.
164330d8983SJohannes Doerfert   llvm::SmallVector<std::unique_ptr<DeviceImageTy>> DeviceImages;
165330d8983SJohannes Doerfert 
166330d8983SJohannes Doerfert   /// The user provided requirements.
167330d8983SJohannes Doerfert   RequirementCollection Requirements;
168330d8983SJohannes Doerfert 
169330d8983SJohannes Doerfert   std::mutex RTLsMtx; ///< For RTLs
170330d8983SJohannes Doerfert 
171330d8983SJohannes Doerfert   /// Devices associated with plugins, accesses to the container are exclusive.
172330d8983SJohannes Doerfert   ProtectedObj<DeviceContainerTy> Devices;
173*13dcc95dSJoseph Huber 
174*13dcc95dSJoseph Huber   /// References to upgraded legacy offloading entires.
175*13dcc95dSJoseph Huber   std::list<llvm::SmallVector<llvm::offloading::EntryTy, 0>> LegacyEntries;
176*13dcc95dSJoseph Huber   std::list<llvm::SmallVector<__tgt_device_image, 0>> LegacyImages;
177*13dcc95dSJoseph Huber   llvm::DenseMap<__tgt_bin_desc *, __tgt_bin_desc> UpgradedDescriptors;
178*13dcc95dSJoseph Huber   __tgt_bin_desc *upgradeLegacyEntries(__tgt_bin_desc *Desc);
179330d8983SJohannes Doerfert };
180330d8983SJohannes Doerfert 
181330d8983SJohannes Doerfert /// Initialize the plugin manager and OpenMP runtime.
182330d8983SJohannes Doerfert void initRuntime();
183330d8983SJohannes Doerfert 
184330d8983SJohannes Doerfert /// Deinitialize the plugin and delete it.
185330d8983SJohannes Doerfert void deinitRuntime();
186330d8983SJohannes Doerfert 
187330d8983SJohannes Doerfert extern PluginManager *PM;
188330d8983SJohannes Doerfert 
189330d8983SJohannes Doerfert #endif // OMPTARGET_PLUGIN_MANAGER_H
190